Commit 2933e55d authored by Rocky Automation's avatar Rocky Automation 📺
Browse files

import 389-ds-base-1.4.3.23-14.module+el8.5.0+14377+c731dc97

parent 7fabd82e
From 1cdb49e70e35ad69e76be10f93233cdf504375df Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Thu, 16 Dec 2021 16:13:08 -0500
Subject: [PATCH 1/4] CVE-2021-4091 (BZ#2030367) double-free of the virtual
attribute context in persistent search
description:
A search is processed by a worker using a private pblock.
If the search is persistent, the worker spawn a thread
and kind of duplicate its private pblock so that the spawn
thread continue to process the persistent search.
Then worker ends the initial search, reinit (free) its private pblock,
and returns monitoring the wait_queue.
When the persistent search completes, it frees the duplicated
pblock.
The problem is that private pblock and duplicated pblock
are referring to a same structure (pb_vattr_context).
That lead to a double free
Fix:
When cloning the pblock (slapi_pblock_clone) make sure
to transfert the references inside the original (private)
pblock to the target (cloned) one
That includes pb_vattr_context pointer.
Reviewed by: Mark Reynolds, James Chapman, Pierre Rogier (Thanks !)
---
ldap/servers/slapd/connection.c | 8 +++++---
ldap/servers/slapd/pblock.c | 14 ++++++++++++--
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
index e0c1a52d2..fc7ed9c4a 100644
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -1823,9 +1823,11 @@ connection_threadmain()
pthread_mutex_unlock(&(conn->c_mutex));
}
/* ps_add makes a shallow copy of the pb - so we
- * can't free it or init it here - just set operation to NULL.
- * ps_send_results will call connection_remove_operation_ext to free it
- */
+ * can't free it or init it here - just set operation to NULL.
+ * ps_send_results will call connection_remove_operation_ext to free it
+ * The connection_thread private pblock ('pb') has be cloned and should only
+ * be reinit (slapi_pblock_init)
+ */
slapi_pblock_set(pb, SLAPI_OPERATION, NULL);
slapi_pblock_init(pb);
} else {
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
index a64986aeb..c78d1250f 100644
--- a/ldap/servers/slapd/pblock.c
+++ b/ldap/servers/slapd/pblock.c
@@ -292,6 +292,12 @@ _pblock_assert_pb_deprecated(Slapi_PBlock *pblock)
}
}
+/* It clones the pblock
+ * the content of the source pblock is transfered
+ * to the target pblock (returned)
+ * The source pblock should not be used for any operation
+ * it needs to be reinit (slapi_pblock_init)
+ */
Slapi_PBlock *
slapi_pblock_clone(Slapi_PBlock *pb)
{
@@ -312,28 +318,32 @@ slapi_pblock_clone(Slapi_PBlock *pb)
if (pb->pb_task != NULL) {
_pblock_assert_pb_task(new_pb);
*(new_pb->pb_task) = *(pb->pb_task);
+ memset(pb->pb_task, 0, sizeof(slapi_pblock_task));
}
if (pb->pb_mr != NULL) {
_pblock_assert_pb_mr(new_pb);
*(new_pb->pb_mr) = *(pb->pb_mr);
+ memset(pb->pb_mr, 0, sizeof(slapi_pblock_matching_rule));
}
if (pb->pb_misc != NULL) {
_pblock_assert_pb_misc(new_pb);
*(new_pb->pb_misc) = *(pb->pb_misc);
+ memset(pb->pb_misc, 0, sizeof(slapi_pblock_misc));
}
if (pb->pb_intop != NULL) {
_pblock_assert_pb_intop(new_pb);
*(new_pb->pb_intop) = *(pb->pb_intop);
- /* set pwdpolicy to NULL so this clone allocates its own policy */
- new_pb->pb_intop->pwdpolicy = NULL;
+ memset(pb->pb_intop, 0, sizeof(slapi_pblock_intop));
}
if (pb->pb_intplugin != NULL) {
_pblock_assert_pb_intplugin(new_pb);
*(new_pb->pb_intplugin) = *(pb->pb_intplugin);
+ memset(pb->pb_intplugin, 0,sizeof(slapi_pblock_intplugin));
}
if (pb->pb_deprecated != NULL) {
_pblock_assert_pb_deprecated(new_pb);
*(new_pb->pb_deprecated) = *(pb->pb_deprecated);
+ memset(pb->pb_deprecated, 0, sizeof(slapi_pblock_deprecated));
}
#ifdef PBLOCK_ANALYTICS
new_pb->analytics = NULL;
--
2.31.1
From cf620c104ac50af48e48e8c0040820b6c073f7d7 Mon Sep 17 00:00:00 2001
From: Firstyear <william@blackhats.net.au>
Date: Thu, 19 Aug 2021 10:46:00 +1000
Subject: [PATCH 2/4] Issue 4775 - Add entryuuid CLI and Fixup (#4776)
Bug Description: EntryUUID when added was missing it's CLI
and helpers for fixups.
Fix Description: Add the CLI elements.
fixes: https://github.com/389ds/389-ds-base/issues/4775
Author: William Brown <william@blackhats.net.au>
Review by: @mreynolds389 (thanks!)
---
src/lib389/lib389/cli_conf/plugin.py | 2 +
.../lib389/cli_conf/plugins/entryuuid.py | 39 +++++++++++++++++++
src/plugins/entryuuid/src/lib.rs | 34 +++++++++-------
3 files changed, 60 insertions(+), 15 deletions(-)
create mode 100644 src/lib389/lib389/cli_conf/plugins/entryuuid.py
diff --git a/src/lib389/lib389/cli_conf/plugin.py b/src/lib389/lib389/cli_conf/plugin.py
index b50837cb8..1bd0c70db 100644
--- a/src/lib389/lib389/cli_conf/plugin.py
+++ b/src/lib389/lib389/cli_conf/plugin.py
@@ -27,6 +27,7 @@ from lib389.cli_conf.plugins import passthroughauth as cli_passthroughauth
from lib389.cli_conf.plugins import retrochangelog as cli_retrochangelog
from lib389.cli_conf.plugins import automember as cli_automember
from lib389.cli_conf.plugins import posix_winsync as cli_posix_winsync
+from lib389.cli_conf.plugins import entryuuid as cli_entryuuid
SINGULAR = Plugin
MANY = Plugins
@@ -113,6 +114,7 @@ def create_parser(subparsers):
cli_passthroughauth.create_parser(subcommands)
cli_retrochangelog.create_parser(subcommands)
cli_posix_winsync.create_parser(subcommands)
+ cli_entryuuid.create_parser(subcommands)
list_parser = subcommands.add_parser('list', help="List current configured (enabled and disabled) plugins")
list_parser.set_defaults(func=plugin_list)
diff --git a/src/lib389/lib389/cli_conf/plugins/entryuuid.py b/src/lib389/lib389/cli_conf/plugins/entryuuid.py
new file mode 100644
index 000000000..6c86bff4b
--- /dev/null
+++ b/src/lib389/lib389/cli_conf/plugins/entryuuid.py
@@ -0,0 +1,39 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2021 William Brown <william@blackhats.net.au>
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import ldap
+from lib389.plugins import EntryUUIDPlugin
+from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add
+
+def do_fixup(inst, basedn, log, args):
+ plugin = EntryUUIDPlugin(inst)
+ log.info('Attempting to add task entry...')
+ if not plugin.status():
+ log.error("'%s' is disabled. Fix up task can't be executed" % plugin.rdn)
+ return
+ fixup_task = plugin.fixup(args.DN, args.filter)
+ fixup_task.wait()
+ exitcode = fixup_task.get_exit_code()
+ if exitcode != 0:
+ log.error('EntryUUID fixup task has failed. Please, check the error log for more - %s' % exitcode)
+ else:
+ log.info('Successfully added task entry')
+
+def create_parser(subparsers):
+ referint = subparsers.add_parser('entryuuid', help='Manage and configure EntryUUID plugin')
+ subcommands = referint.add_subparsers(help='action')
+
+ add_generic_plugin_parsers(subcommands, EntryUUIDPlugin)
+
+ fixup = subcommands.add_parser('fixup', help='Run the fix-up task for EntryUUID plugin')
+ fixup.set_defaults(func=do_fixup)
+ fixup.add_argument('DN', help="Base DN that contains entries to fix up")
+ fixup.add_argument('-f', '--filter',
+ help='Filter for entries to fix up.\n If omitted, all entries under base DN'
+ 'will have their EntryUUID attribute regenerated if not present.')
+
diff --git a/src/plugins/entryuuid/src/lib.rs b/src/plugins/entryuuid/src/lib.rs
index 0197c5e83..29a9f1258 100644
--- a/src/plugins/entryuuid/src/lib.rs
+++ b/src/plugins/entryuuid/src/lib.rs
@@ -33,7 +33,7 @@ fn assign_uuid(e: &mut EntryRef) {
// 🚧 safety barrier 🚧
if e.contains_attr("entryUUID") {
log_error!(
- ErrorLevel::Trace,
+ ErrorLevel::Plugin,
"assign_uuid -> entryUUID exists, skipping dn {}",
sdn.to_dn_string()
);
@@ -47,7 +47,7 @@ fn assign_uuid(e: &mut EntryRef) {
if sdn.is_below_suffix(&*config_sdn) || sdn.is_below_suffix(&*schema_sdn) {
// We don't need to assign to these suffixes.
log_error!(
- ErrorLevel::Trace,
+ ErrorLevel::Plugin,
"assign_uuid -> not assigning to {:?} as part of system suffix",
sdn.to_dn_string()
);
@@ -57,7 +57,7 @@ fn assign_uuid(e: &mut EntryRef) {
// Generate a new Uuid.
let u: Uuid = Uuid::new_v4();
log_error!(
- ErrorLevel::Trace,
+ ErrorLevel::Plugin,
"assign_uuid -> assigning {:?} to dn {}",
u,
sdn.to_dn_string()
@@ -78,13 +78,13 @@ impl SlapiPlugin3 for EntryUuid {
fn betxn_pre_add(pb: &mut PblockRef) -> Result<(), PluginError> {
if pb.get_is_replicated_operation() {
log_error!(
- ErrorLevel::Trace,
+ ErrorLevel::Plugin,
"betxn_pre_add -> replicated operation, will not change"
);
return Ok(());
}
- log_error!(ErrorLevel::Trace, "betxn_pre_add -> start");
+ log_error!(ErrorLevel::Plugin, "betxn_pre_add -> start");
let mut e = pb.get_op_add_entryref().map_err(|_| PluginError::Pblock)?;
assign_uuid(&mut e);
@@ -105,7 +105,7 @@ impl SlapiPlugin3 for EntryUuid {
.first()
.ok_or_else(|| {
log_error!(
- ErrorLevel::Trace,
+ ErrorLevel::Plugin,
"task_validate basedn error -> empty value array?"
);
LDAPError::Operation
@@ -113,7 +113,7 @@ impl SlapiPlugin3 for EntryUuid {
.as_ref()
.try_into()
.map_err(|e| {
- log_error!(ErrorLevel::Trace, "task_validate basedn error -> {:?}", e);
+ log_error!(ErrorLevel::Plugin, "task_validate basedn error -> {:?}", e);
LDAPError::Operation
})?,
None => return Err(LDAPError::ObjectClassViolation),
@@ -124,7 +124,7 @@ impl SlapiPlugin3 for EntryUuid {
.first()
.ok_or_else(|| {
log_error!(
- ErrorLevel::Trace,
+ ErrorLevel::Plugin,
"task_validate filter error -> empty value array?"
);
LDAPError::Operation
@@ -132,7 +132,7 @@ impl SlapiPlugin3 for EntryUuid {
.as_ref()
.try_into()
.map_err(|e| {
- log_error!(ErrorLevel::Trace, "task_validate filter error -> {:?}", e);
+ log_error!(ErrorLevel::Plugin, "task_validate filter error -> {:?}", e);
LDAPError::Operation
})?,
None => {
@@ -144,7 +144,11 @@ impl SlapiPlugin3 for EntryUuid {
// Error if the first filter is empty?
// Now, to make things faster, we wrap the filter in a exclude term.
- let raw_filter = format!("(&{}(!(entryuuid=*)))", raw_filter);
+ let raw_filter = if !raw_filter.starts_with('(') && !raw_filter.ends_with('(') {
+ format!("(&({})(!(entryuuid=*)))", raw_filter)
+ } else {
+ format!("(&{}(!(entryuuid=*)))", raw_filter)
+ };
Ok(FixupData { basedn, raw_filter })
}
@@ -155,7 +159,7 @@ impl SlapiPlugin3 for EntryUuid {
fn task_handler(_task: &Task, data: Self::TaskData) -> Result<Self::TaskData, PluginError> {
log_error!(
- ErrorLevel::Trace,
+ ErrorLevel::Plugin,
"task_handler -> start thread with -> {:?}",
data
);
@@ -195,12 +199,12 @@ impl SlapiPlugin3 for EntryUuid {
}
fn start(_pb: &mut PblockRef) -> Result<(), PluginError> {
- log_error!(ErrorLevel::Trace, "plugin start");
+ log_error!(ErrorLevel::Plugin, "plugin start");
Ok(())
}
fn close(_pb: &mut PblockRef) -> Result<(), PluginError> {
- log_error!(ErrorLevel::Trace, "plugin close");
+ log_error!(ErrorLevel::Plugin, "plugin close");
Ok(())
}
}
@@ -212,7 +216,7 @@ pub fn entryuuid_fixup_mapfn(e: &EntryRef, _data: &()) -> Result<(), PluginError
/* Sanity check that entryuuid doesn't already exist */
if e.contains_attr("entryUUID") {
log_error!(
- ErrorLevel::Trace,
+ ErrorLevel::Plugin,
"skipping fixup for -> {}",
sdn.to_dn_string()
);
@@ -232,7 +236,7 @@ pub fn entryuuid_fixup_mapfn(e: &EntryRef, _data: &()) -> Result<(), PluginError
match lmod.execute() {
Ok(_) => {
- log_error!(ErrorLevel::Trace, "fixed-up -> {}", sdn.to_dn_string());
+ log_error!(ErrorLevel::Plugin, "fixed-up -> {}", sdn.to_dn_string());
Ok(())
}
Err(e) => {
--
2.31.1
From 0ed5299841733f9e18c5fe8c6a3f9d3fbd49c75a Mon Sep 17 00:00:00 2001
From: Firstyear <william@blackhats.net.au>
Date: Fri, 20 Aug 2021 09:18:50 +1000
Subject: [PATCH 3/4] Issue 4877 - RFE - EntryUUID to validate UUIDs on fixup
(#4878)
Bug Description: Due to changing the syntax of EntryUUID's
to string, we may have invalid EntryUUID's imported into
the database.
Fix Description: To resolve this during a fixup we validate
that Uuid's have a valid syntax. If they do not, we regenerate
them.
fixes: https://github.com/389ds/389-ds-base/issues/4877
Author: William Brown <william@blackhats.net.au>
Review by: @mreynolds389
---
.../entryuuid/localhost-userRoot-invalid.ldif | 233 ++++++++++++++++++
.../tests/suites/entryuuid/basic_test.py | 58 ++++-
src/plugins/entryuuid/src/lib.rs | 28 ++-
src/slapi_r_plugin/src/pblock.rs | 4 +-
src/slapi_r_plugin/src/value.rs | 10 +-
5 files changed, 322 insertions(+), 11 deletions(-)
create mode 100644 dirsrvtests/tests/data/entryuuid/localhost-userRoot-invalid.ldif
diff --git a/dirsrvtests/tests/data/entryuuid/localhost-userRoot-invalid.ldif b/dirsrvtests/tests/data/entryuuid/localhost-userRoot-invalid.ldif
new file mode 100644
index 000000000..9703babed
--- /dev/null
+++ b/dirsrvtests/tests/data/entryuuid/localhost-userRoot-invalid.ldif
@@ -0,0 +1,233 @@
+version: 1
+
+# entry-id: 1
+dn: dc=example,dc=com
+objectClass: top
+objectClass: domain
+dc: example
+description: dc=example,dc=com
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015542Z
+modifyTimestamp: 20200325015542Z
+nsUniqueId: a2b33229-6e3b11ea-8de0c78c-83e27eda
+aci: (targetattr="dc || description || objectClass")(targetfilter="(objectClas
+ s=domain)")(version 3.0; acl "Enable anyone domain read"; allow (read, search
+ , compare)(userdn="ldap:///anyone");)
+aci: (targetattr="ou || objectClass")(targetfilter="(objectClass=organizationa
+ lUnit)")(version 3.0; acl "Enable anyone ou read"; allow (read, search, compa
+ re)(userdn="ldap:///anyone");)
+
+# entry-id: 2
+dn: cn=389_ds_system,dc=example,dc=com
+objectClass: top
+objectClass: nscontainer
+objectClass: ldapsubentry
+cn: 389_ds_system
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015542Z
+modifyTimestamp: 20200325015542Z
+nsUniqueId: a2b3322a-6e3b11ea-8de0c78c-83e27eda
+
+# entry-id: 3
+dn: ou=groups,dc=example,dc=com
+objectClass: top
+objectClass: organizationalunit
+ou: groups
+aci: (targetattr="cn || member || gidNumber || nsUniqueId || description || ob
+ jectClass")(targetfilter="(objectClass=groupOfNames)")(version 3.0; acl "Enab
+ le anyone group read"; allow (read, search, compare)(userdn="ldap:///anyone")
+ ;)
+aci: (targetattr="member")(targetfilter="(objectClass=groupOfNames)")(version
+ 3.0; acl "Enable group_modify to alter members"; allow (write)(groupdn="ldap:
+ ///cn=group_modify,ou=permissions,dc=example,dc=com");)
+aci: (targetattr="cn || member || gidNumber || description || objectClass")(ta
+ rgetfilter="(objectClass=groupOfNames)")(version 3.0; acl "Enable group_admin
+ to manage groups"; allow (write, add, delete)(groupdn="ldap:///cn=group_admi
+ n,ou=permissions,dc=example,dc=com");)
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015543Z
+modifyTimestamp: 20200325015543Z
+nsUniqueId: a2b3322b-6e3b11ea-8de0c78c-83e27eda
+
+# entry-id: 4
+dn: ou=people,dc=example,dc=com
+objectClass: top
+objectClass: organizationalunit
+ou: people
+aci: (targetattr="objectClass || description || nsUniqueId || uid || displayNa
+ me || loginShell || uidNumber || gidNumber || gecos || homeDirectory || cn ||
+ memberOf || mail || nsSshPublicKey || nsAccountLock || userCertificate")(tar
+ getfilter="(objectClass=posixaccount)")(version 3.0; acl "Enable anyone user
+ read"; allow (read, search, compare)(userdn="ldap:///anyone");)
+aci: (targetattr="displayName || legalName || userPassword || nsSshPublicKey")
+ (version 3.0; acl "Enable self partial modify"; allow (write)(userdn="ldap://
+ /self");)
+aci: (targetattr="legalName || telephoneNumber || mobile || sn")(targetfilter=
+ "(|(objectClass=nsPerson)(objectClass=inetOrgPerson))")(version 3.0; acl "Ena
+ ble self legalname read"; allow (read, search, compare)(userdn="ldap:///self"
+ );)
+aci: (targetattr="legalName || telephoneNumber")(targetfilter="(objectClass=ns
+ Person)")(version 3.0; acl "Enable user legalname read"; allow (read, search,
+ compare)(groupdn="ldap:///cn=user_private_read,ou=permissions,dc=example,dc=
+ com");)
+aci: (targetattr="uid || description || displayName || loginShell || uidNumber
+ || gidNumber || gecos || homeDirectory || cn || memberOf || mail || legalNam
+ e || telephoneNumber || mobile")(targetfilter="(&(objectClass=nsPerson)(objec
+ tClass=nsAccount))")(version 3.0; acl "Enable user admin create"; allow (writ
+ e, add, delete, read)(groupdn="ldap:///cn=user_admin,ou=permissions,dc=exampl
+ e,dc=com");)
+aci: (targetattr="uid || description || displayName || loginShell || uidNumber
+ || gidNumber || gecos || homeDirectory || cn || memberOf || mail || legalNam
+ e || telephoneNumber || mobile")(targetfilter="(&(objectClass=nsPerson)(objec
+ tClass=nsAccount))")(version 3.0; acl "Enable user modify to change users"; a
+ llow (write, read)(groupdn="ldap:///cn=user_modify,ou=permissions,dc=example,
+ dc=com");)
+aci: (targetattr="userPassword || nsAccountLock || userCertificate || nsSshPub
+ licKey")(targetfilter="(objectClass=nsAccount)")(version 3.0; acl "Enable use
+ r password reset"; allow (write, read)(groupdn="ldap:///cn=user_passwd_reset,
+ ou=permissions,dc=example,dc=com");)
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015543Z
+modifyTimestamp: 20200325015543Z
+nsUniqueId: a2b3322c-6e3b11ea-8de0c78c-83e27eda
+
+# entry-id: 5
+dn: ou=permissions,dc=example,dc=com
+objectClass: top
+objectClass: organizationalunit
+ou: permissions
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015543Z
+modifyTimestamp: 20200325015543Z
+nsUniqueId: a2b3322d-6e3b11ea-8de0c78c-83e27eda
+
+# entry-id: 6
+dn: ou=services,dc=example,dc=com
+objectClass: top
+objectClass: organizationalunit
+ou: services
+aci: (targetattr="objectClass || description || nsUniqueId || cn || memberOf |
+ | nsAccountLock ")(targetfilter="(objectClass=netscapeServer)")(version 3.0;
+ acl "Enable anyone service account read"; allow (read, search, compare)(userd
+ n="ldap:///anyone");)
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015544Z
+modifyTimestamp: 20200325015544Z
+nsUniqueId: a2b3322e-6e3b11ea-8de0c78c-83e27eda
+
+# entry-id: 7
+dn: uid=demo_user,ou=people,dc=example,dc=com
+objectClass: top
+objectClass: nsPerson
+objectClass: nsAccount
+objectClass: nsOrgPerson
+objectClass: posixAccount
+uid: demo_user
+cn: Demo User
+displayName: Demo User
+legalName: Demo User Name
+uidNumber: 99998
+gidNumber: 99998
+homeDirectory: /var/empty
+loginShell: /bin/false
+nsAccountLock: true
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015544Z
+modifyTimestamp: 20200325061615Z
+nsUniqueId: a2b3322f-6e3b11ea-8de0c78c-83e27eda
+entryUUID: INVALID_UUID
+
+# entry-id: 8
+dn: cn=demo_group,ou=groups,dc=example,dc=com
+objectClass: top
+objectClass: groupOfNames
+objectClass: posixGroup
+objectClass: nsMemberOf
+cn: demo_group
+gidNumber: 99999
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015544Z
+modifyTimestamp: 20200325015544Z
+nsUniqueId: a2b33230-6e3b11ea-8de0c78c-83e27eda
+entryUUID: f6df8fe9-6b30-46aa-aa13-f0bf755371e8
+
+# entry-id: 9
+dn: cn=group_admin,ou=permissions,dc=example,dc=com
+objectClass: top
+objectClass: groupOfNames
+objectClass: nsMemberOf
+cn: group_admin
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015545Z
+modifyTimestamp: 20200325015545Z
+nsUniqueId: a2b33231-6e3b11ea-8de0c78c-83e27eda
+
+# entry-id: 10
+dn: cn=group_modify,ou=permissions,dc=example,dc=com
+objectClass: top
+objectClass: groupOfNames
+objectClass: nsMemberOf
+cn: group_modify
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015545Z
+modifyTimestamp: 20200325015545Z
+nsUniqueId: a2b33232-6e3b11ea-8de0c78c-83e27eda
+
+# entry-id: 11
+dn: cn=user_admin,ou=permissions,dc=example,dc=com
+objectClass: top
+objectClass: groupOfNames
+objectClass: nsMemberOf
+cn: user_admin
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015545Z
+modifyTimestamp: 20200325015545Z
+nsUniqueId: a2b33233-6e3b11ea-8de0c78c-83e27eda
+
+# entry-id: 12
+dn: cn=user_modify,ou=permissions,dc=example,dc=com
+objectClass: top
+objectClass: groupOfNames
+objectClass: nsMemberOf
+cn: user_modify
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015546Z
+modifyTimestamp: 20200325015546Z
+nsUniqueId: a2b33234-6e3b11ea-8de0c78c-83e27eda
+
+# entry-id: 13
+dn: cn=user_passwd_reset,ou=permissions,dc=example,dc=com
+objectClass: top
+objectClass: groupOfNames
+objectClass: nsMemberOf
+cn: user_passwd_reset
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015546Z
+modifyTimestamp: 20200325015546Z
+nsUniqueId: a2b33235-6e3b11ea-8de0c78c-83e27eda
+
+# entry-id: 14
+dn: cn=user_private_read,ou=permissions,dc=example,dc=com
+objectClass: top
+objectClass: groupOfNames
+objectClass: nsMemberOf
+cn: user_private_read
+creatorsName: cn=Directory Manager
+modifiersName: cn=Directory Manager
+createTimestamp: 20200325015547Z
+modifyTimestamp: 20200325015547Z
+nsUniqueId: a2b33236-6e3b11ea-8de0c78c-83e27eda
+
diff --git a/dirsrvtests/tests/suites/entryuuid/basic_test.py b/dirsrvtests/tests/suites/entryuuid/basic_test.py
index 4d8a40909..41ffbfe10 100644
--- a/dirsrvtests/tests/suites/entryuuid/basic_test.py
+++ b/dirsrvtests/tests/suites/entryuuid/basic_test.py
@@ -10,6 +10,7 @@ import ldap
import pytest
import time