|
|
b03d2c |
From 0ed5299841733f9e18c5fe8c6a3f9d3fbd49c75a Mon Sep 17 00:00:00 2001
|
|
|
b03d2c |
From: Firstyear <william@blackhats.net.au>
|
|
|
b03d2c |
Date: Fri, 20 Aug 2021 09:18:50 +1000
|
|
|
b03d2c |
Subject: [PATCH 3/4] Issue 4877 - RFE - EntryUUID to validate UUIDs on fixup
|
|
|
b03d2c |
(#4878)
|
|
|
b03d2c |
|
|
|
b03d2c |
Bug Description: Due to changing the syntax of EntryUUID's
|
|
|
b03d2c |
to string, we may have invalid EntryUUID's imported into
|
|
|
b03d2c |
the database.
|
|
|
b03d2c |
|
|
|
b03d2c |
Fix Description: To resolve this during a fixup we validate
|
|
|
b03d2c |
that Uuid's have a valid syntax. If they do not, we regenerate
|
|
|
b03d2c |
them.
|
|
|
b03d2c |
|
|
|
b03d2c |
fixes: https://github.com/389ds/389-ds-base/issues/4877
|
|
|
b03d2c |
|
|
|
b03d2c |
Author: William Brown <william@blackhats.net.au>
|
|
|
b03d2c |
|
|
|
b03d2c |
Review by: @mreynolds389
|
|
|
b03d2c |
---
|
|
|
b03d2c |
.../entryuuid/localhost-userRoot-invalid.ldif | 233 ++++++++++++++++++
|
|
|
b03d2c |
.../tests/suites/entryuuid/basic_test.py | 58 ++++-
|
|
|
b03d2c |
src/plugins/entryuuid/src/lib.rs | 28 ++-
|
|
|
b03d2c |
src/slapi_r_plugin/src/pblock.rs | 4 +-
|
|
|
b03d2c |
src/slapi_r_plugin/src/value.rs | 10 +-
|
|
|
b03d2c |
5 files changed, 322 insertions(+), 11 deletions(-)
|
|
|
b03d2c |
create mode 100644 dirsrvtests/tests/data/entryuuid/localhost-userRoot-invalid.ldif
|
|
|
b03d2c |
|
|
|
b03d2c |
diff --git a/dirsrvtests/tests/data/entryuuid/localhost-userRoot-invalid.ldif b/dirsrvtests/tests/data/entryuuid/localhost-userRoot-invalid.ldif
|
|
|
b03d2c |
new file mode 100644
|
|
|
b03d2c |
index 000000000..9703babed
|
|
|
b03d2c |
--- /dev/null
|
|
|
b03d2c |
+++ b/dirsrvtests/tests/data/entryuuid/localhost-userRoot-invalid.ldif
|
|
|
b03d2c |
@@ -0,0 +1,233 @@
|
|
|
b03d2c |
+version: 1
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 1
|
|
|
b03d2c |
+dn: dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: domain
|
|
|
b03d2c |
+dc: example
|
|
|
b03d2c |
+description: dc=example,dc=com
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015542Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015542Z
|
|
|
b03d2c |
+nsUniqueId: a2b33229-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+aci: (targetattr="dc || description || objectClass")(targetfilter="(objectClas
|
|
|
b03d2c |
+ s=domain)")(version 3.0; acl "Enable anyone domain read"; allow (read, search
|
|
|
b03d2c |
+ , compare)(userdn="ldap:///anyone");)
|
|
|
b03d2c |
+aci: (targetattr="ou || objectClass")(targetfilter="(objectClass=organizationa
|
|
|
b03d2c |
+ lUnit)")(version 3.0; acl "Enable anyone ou read"; allow (read, search, compa
|
|
|
b03d2c |
+ re)(userdn="ldap:///anyone");)
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 2
|
|
|
b03d2c |
+dn: cn=389_ds_system,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: nscontainer
|
|
|
b03d2c |
+objectClass: ldapsubentry
|
|
|
b03d2c |
+cn: 389_ds_system
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015542Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015542Z
|
|
|
b03d2c |
+nsUniqueId: a2b3322a-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 3
|
|
|
b03d2c |
+dn: ou=groups,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: organizationalunit
|
|
|
b03d2c |
+ou: groups
|
|
|
b03d2c |
+aci: (targetattr="cn || member || gidNumber || nsUniqueId || description || ob
|
|
|
b03d2c |
+ jectClass")(targetfilter="(objectClass=groupOfNames)")(version 3.0; acl "Enab
|
|
|
b03d2c |
+ le anyone group read"; allow (read, search, compare)(userdn="ldap:///anyone")
|
|
|
b03d2c |
+ ;)
|
|
|
b03d2c |
+aci: (targetattr="member")(targetfilter="(objectClass=groupOfNames)")(version
|
|
|
b03d2c |
+ 3.0; acl "Enable group_modify to alter members"; allow (write)(groupdn="ldap:
|
|
|
b03d2c |
+ ///cn=group_modify,ou=permissions,dc=example,dc=com");)
|
|
|
b03d2c |
+aci: (targetattr="cn || member || gidNumber || description || objectClass")(ta
|
|
|
b03d2c |
+ rgetfilter="(objectClass=groupOfNames)")(version 3.0; acl "Enable group_admin
|
|
|
b03d2c |
+ to manage groups"; allow (write, add, delete)(groupdn="ldap:///cn=group_admi
|
|
|
b03d2c |
+ n,ou=permissions,dc=example,dc=com");)
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015543Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015543Z
|
|
|
b03d2c |
+nsUniqueId: a2b3322b-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 4
|
|
|
b03d2c |
+dn: ou=people,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: organizationalunit
|
|
|
b03d2c |
+ou: people
|
|
|
b03d2c |
+aci: (targetattr="objectClass || description || nsUniqueId || uid || displayNa
|
|
|
b03d2c |
+ me || loginShell || uidNumber || gidNumber || gecos || homeDirectory || cn ||
|
|
|
b03d2c |
+ memberOf || mail || nsSshPublicKey || nsAccountLock || userCertificate")(tar
|
|
|
b03d2c |
+ getfilter="(objectClass=posixaccount)")(version 3.0; acl "Enable anyone user
|
|
|
b03d2c |
+ read"; allow (read, search, compare)(userdn="ldap:///anyone");)
|
|
|
b03d2c |
+aci: (targetattr="displayName || legalName || userPassword || nsSshPublicKey")
|
|
|
b03d2c |
+ (version 3.0; acl "Enable self partial modify"; allow (write)(userdn="ldap://
|
|
|
b03d2c |
+ /self");)
|
|
|
b03d2c |
+aci: (targetattr="legalName || telephoneNumber || mobile || sn")(targetfilter=
|
|
|
b03d2c |
+ "(|(objectClass=nsPerson)(objectClass=inetOrgPerson))")(version 3.0; acl "Ena
|
|
|
b03d2c |
+ ble self legalname read"; allow (read, search, compare)(userdn="ldap:///self"
|
|
|
b03d2c |
+ );)
|
|
|
b03d2c |
+aci: (targetattr="legalName || telephoneNumber")(targetfilter="(objectClass=ns
|
|
|
b03d2c |
+ Person)")(version 3.0; acl "Enable user legalname read"; allow (read, search,
|
|
|
b03d2c |
+ compare)(groupdn="ldap:///cn=user_private_read,ou=permissions,dc=example,dc=
|
|
|
b03d2c |
+ com");)
|
|
|
b03d2c |
+aci: (targetattr="uid || description || displayName || loginShell || uidNumber
|
|
|
b03d2c |
+ || gidNumber || gecos || homeDirectory || cn || memberOf || mail || legalNam
|
|
|
b03d2c |
+ e || telephoneNumber || mobile")(targetfilter="(&(objectClass=nsPerson)(objec
|
|
|
b03d2c |
+ tClass=nsAccount))")(version 3.0; acl "Enable user admin create"; allow (writ
|
|
|
b03d2c |
+ e, add, delete, read)(groupdn="ldap:///cn=user_admin,ou=permissions,dc=exampl
|
|
|
b03d2c |
+ e,dc=com");)
|
|
|
b03d2c |
+aci: (targetattr="uid || description || displayName || loginShell || uidNumber
|
|
|
b03d2c |
+ || gidNumber || gecos || homeDirectory || cn || memberOf || mail || legalNam
|
|
|
b03d2c |
+ e || telephoneNumber || mobile")(targetfilter="(&(objectClass=nsPerson)(objec
|
|
|
b03d2c |
+ tClass=nsAccount))")(version 3.0; acl "Enable user modify to change users"; a
|
|
|
b03d2c |
+ llow (write, read)(groupdn="ldap:///cn=user_modify,ou=permissions,dc=example,
|
|
|
b03d2c |
+ dc=com");)
|
|
|
b03d2c |
+aci: (targetattr="userPassword || nsAccountLock || userCertificate || nsSshPub
|
|
|
b03d2c |
+ licKey")(targetfilter="(objectClass=nsAccount)")(version 3.0; acl "Enable use
|
|
|
b03d2c |
+ r password reset"; allow (write, read)(groupdn="ldap:///cn=user_passwd_reset,
|
|
|
b03d2c |
+ ou=permissions,dc=example,dc=com");)
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015543Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015543Z
|
|
|
b03d2c |
+nsUniqueId: a2b3322c-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 5
|
|
|
b03d2c |
+dn: ou=permissions,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: organizationalunit
|
|
|
b03d2c |
+ou: permissions
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015543Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015543Z
|
|
|
b03d2c |
+nsUniqueId: a2b3322d-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 6
|
|
|
b03d2c |
+dn: ou=services,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: organizationalunit
|
|
|
b03d2c |
+ou: services
|
|
|
b03d2c |
+aci: (targetattr="objectClass || description || nsUniqueId || cn || memberOf |
|
|
|
b03d2c |
+ | nsAccountLock ")(targetfilter="(objectClass=netscapeServer)")(version 3.0;
|
|
|
b03d2c |
+ acl "Enable anyone service account read"; allow (read, search, compare)(userd
|
|
|
b03d2c |
+ n="ldap:///anyone");)
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015544Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015544Z
|
|
|
b03d2c |
+nsUniqueId: a2b3322e-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 7
|
|
|
b03d2c |
+dn: uid=demo_user,ou=people,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: nsPerson
|
|
|
b03d2c |
+objectClass: nsAccount
|
|
|
b03d2c |
+objectClass: nsOrgPerson
|
|
|
b03d2c |
+objectClass: posixAccount
|
|
|
b03d2c |
+uid: demo_user
|
|
|
b03d2c |
+cn: Demo User
|
|
|
b03d2c |
+displayName: Demo User
|
|
|
b03d2c |
+legalName: Demo User Name
|
|
|
b03d2c |
+uidNumber: 99998
|
|
|
b03d2c |
+gidNumber: 99998
|
|
|
b03d2c |
+homeDirectory: /var/empty
|
|
|
b03d2c |
+loginShell: /bin/false
|
|
|
b03d2c |
+nsAccountLock: true
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015544Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325061615Z
|
|
|
b03d2c |
+nsUniqueId: a2b3322f-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+entryUUID: INVALID_UUID
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 8
|
|
|
b03d2c |
+dn: cn=demo_group,ou=groups,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: groupOfNames
|
|
|
b03d2c |
+objectClass: posixGroup
|
|
|
b03d2c |
+objectClass: nsMemberOf
|
|
|
b03d2c |
+cn: demo_group
|
|
|
b03d2c |
+gidNumber: 99999
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015544Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015544Z
|
|
|
b03d2c |
+nsUniqueId: a2b33230-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+entryUUID: f6df8fe9-6b30-46aa-aa13-f0bf755371e8
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 9
|
|
|
b03d2c |
+dn: cn=group_admin,ou=permissions,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: groupOfNames
|
|
|
b03d2c |
+objectClass: nsMemberOf
|
|
|
b03d2c |
+cn: group_admin
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015545Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015545Z
|
|
|
b03d2c |
+nsUniqueId: a2b33231-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 10
|
|
|
b03d2c |
+dn: cn=group_modify,ou=permissions,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: groupOfNames
|
|
|
b03d2c |
+objectClass: nsMemberOf
|
|
|
b03d2c |
+cn: group_modify
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015545Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015545Z
|
|
|
b03d2c |
+nsUniqueId: a2b33232-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 11
|
|
|
b03d2c |
+dn: cn=user_admin,ou=permissions,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: groupOfNames
|
|
|
b03d2c |
+objectClass: nsMemberOf
|
|
|
b03d2c |
+cn: user_admin
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015545Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015545Z
|
|
|
b03d2c |
+nsUniqueId: a2b33233-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 12
|
|
|
b03d2c |
+dn: cn=user_modify,ou=permissions,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: groupOfNames
|
|
|
b03d2c |
+objectClass: nsMemberOf
|
|
|
b03d2c |
+cn: user_modify
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015546Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015546Z
|
|
|
b03d2c |
+nsUniqueId: a2b33234-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 13
|
|
|
b03d2c |
+dn: cn=user_passwd_reset,ou=permissions,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: groupOfNames
|
|
|
b03d2c |
+objectClass: nsMemberOf
|
|
|
b03d2c |
+cn: user_passwd_reset
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015546Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015546Z
|
|
|
b03d2c |
+nsUniqueId: a2b33235-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+# entry-id: 14
|
|
|
b03d2c |
+dn: cn=user_private_read,ou=permissions,dc=example,dc=com
|
|
|
b03d2c |
+objectClass: top
|
|
|
b03d2c |
+objectClass: groupOfNames
|
|
|
b03d2c |
+objectClass: nsMemberOf
|
|
|
b03d2c |
+cn: user_private_read
|
|
|
b03d2c |
+creatorsName: cn=Directory Manager
|
|
|
b03d2c |
+modifiersName: cn=Directory Manager
|
|
|
b03d2c |
+createTimestamp: 20200325015547Z
|
|
|
b03d2c |
+modifyTimestamp: 20200325015547Z
|
|
|
b03d2c |
+nsUniqueId: a2b33236-6e3b11ea-8de0c78c-83e27eda
|
|
|
b03d2c |
+
|
|
|
b03d2c |
diff --git a/dirsrvtests/tests/suites/entryuuid/basic_test.py b/dirsrvtests/tests/suites/entryuuid/basic_test.py
|
|
|
b03d2c |
index 4d8a40909..41ffbfe10 100644
|
|
|
b03d2c |
--- a/dirsrvtests/tests/suites/entryuuid/basic_test.py
|
|
|
b03d2c |
+++ b/dirsrvtests/tests/suites/entryuuid/basic_test.py
|
|
|
b03d2c |
@@ -10,6 +10,7 @@ import ldap
|
|
|
b03d2c |
import pytest
|
|
|
b03d2c |
import time
|
|
|
b03d2c |
import shutil
|
|
|
b03d2c |
+import uuid
|
|
|
b03d2c |
from lib389.idm.user import nsUserAccounts, UserAccounts
|
|
|
b03d2c |
from lib389.idm.account import Accounts
|
|
|
b03d2c |
from lib389.idm.domain import Domain
|
|
|
b03d2c |
@@ -217,7 +218,7 @@ def test_entryuuid_fixup_task(topology):
|
|
|
b03d2c |
|
|
|
b03d2c |
# 4. run the fix up
|
|
|
b03d2c |
# For now set the log level to high!
|
|
|
b03d2c |
- topology.standalone.config.loglevel(vals=(ErrorLog.DEFAULT,ErrorLog.TRACE))
|
|
|
b03d2c |
+ topology.standalone.config.loglevel(vals=(ErrorLog.DEFAULT,ErrorLog.PLUGIN))
|
|
|
b03d2c |
task = plug.fixup(DEFAULT_SUFFIX)
|
|
|
b03d2c |
task.wait()
|
|
|
b03d2c |
assert(task.is_complete() and task.get_exit_code() == 0)
|
|
|
b03d2c |
@@ -242,3 +243,58 @@ def test_entryuuid_fixup_task(topology):
|
|
|
b03d2c |
euuid_domain_2 = domain.get_attr_val_utf8('entryUUID')
|
|
|
b03d2c |
assert(euuid_domain_2 == euuid_domain)
|
|
|
b03d2c |
|
|
|
b03d2c |
+@pytest.mark.skipif(not default_paths.rust_enabled or ds_is_older('1.4.2.0'), reason="Entryuuid is not available in older versions")
|
|
|
b03d2c |
+def test_entryuuid_import_and_fixup_of_invalid_values(topology):
|
|
|
b03d2c |
+ """ Test that when we import a database with an invalid entryuuid
|
|
|
b03d2c |
+ that it is accepted *and* that subsequently we can fix the invalid
|
|
|
b03d2c |
+ entryuuid during a fixup.
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+ :id: ec8ef3a7-3cd2-4cbd-b6f1-2449fa17be75
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+ :setup: Standalone instance
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+ :steps:
|
|
|
b03d2c |
+ 1. Import the db from the ldif
|
|
|
b03d2c |
+ 2. Check the entryuuid is invalid
|
|
|
b03d2c |
+ 3. Run the fixup
|
|
|
b03d2c |
+ 4. Check the entryuuid is now valid (regenerated)
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+ :expectedresults:
|
|
|
b03d2c |
+ 1. Success
|
|
|
b03d2c |
+ 2. The entryuuid is invalid
|
|
|
b03d2c |
+ 3. Success
|
|
|
b03d2c |
+ 4. The entryuuid is valid
|
|
|
b03d2c |
+ """
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+ # 1. Import the db
|
|
|
b03d2c |
+ ldif_dir = topology.standalone.get_ldif_dir()
|
|
|
b03d2c |
+ target_ldif = os.path.join(ldif_dir, 'localhost-userRoot-invalid.ldif')
|
|
|
b03d2c |
+ import_ldif = os.path.join(DATADIR1, 'localhost-userRoot-invalid.ldif')
|
|
|
b03d2c |
+ shutil.copyfile(import_ldif, target_ldif)
|
|
|
b03d2c |
+ os.chmod(target_ldif, 0o777)
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+ be = Backends(topology.standalone).get('userRoot')
|
|
|
b03d2c |
+ task = be.import_ldif([target_ldif])
|
|
|
b03d2c |
+ task.wait()
|
|
|
b03d2c |
+ assert(task.is_complete() and task.get_exit_code() == 0)
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+ # 2. Check the entryuuid is invalid
|
|
|
b03d2c |
+ account = nsUserAccounts(topology.standalone, DEFAULT_SUFFIX).get("demo_user")
|
|
|
b03d2c |
+ euuid = account.get_attr_val_utf8('entryUUID')
|
|
|
b03d2c |
+ assert(euuid == "INVALID_UUID")
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+ # 3. Run the fixup
|
|
|
b03d2c |
+ topology.standalone.config.loglevel(vals=(ErrorLog.DEFAULT,ErrorLog.PLUGIN))
|
|
|
b03d2c |
+ plug = EntryUUIDPlugin(topology.standalone)
|
|
|
b03d2c |
+ task = plug.fixup(DEFAULT_SUFFIX)
|
|
|
b03d2c |
+ task.wait()
|
|
|
b03d2c |
+ assert(task.is_complete() and task.get_exit_code() == 0)
|
|
|
b03d2c |
+ topology.standalone.config.loglevel(vals=(ErrorLog.DEFAULT,))
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+ # 4. Check the entryuuid is valid
|
|
|
b03d2c |
+ euuid = account.get_attr_val_utf8('entryUUID')
|
|
|
b03d2c |
+ print(f"❄️ account entryUUID -> {euuid}");
|
|
|
b03d2c |
+ assert(euuid != "INVALID_UUID")
|
|
|
b03d2c |
+ # Raises an error if invalid
|
|
|
b03d2c |
+ uuid.UUID(euuid)
|
|
|
b03d2c |
+
|
|
|
b03d2c |
diff --git a/src/plugins/entryuuid/src/lib.rs b/src/plugins/entryuuid/src/lib.rs
|
|
|
b03d2c |
index 29a9f1258..ad3faef4b 100644
|
|
|
b03d2c |
--- a/src/plugins/entryuuid/src/lib.rs
|
|
|
b03d2c |
+++ b/src/plugins/entryuuid/src/lib.rs
|
|
|
b03d2c |
@@ -144,11 +144,17 @@ impl SlapiPlugin3 for EntryUuid {
|
|
|
b03d2c |
// Error if the first filter is empty?
|
|
|
b03d2c |
|
|
|
b03d2c |
// Now, to make things faster, we wrap the filter in a exclude term.
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+ // 2021 - #4877 because we allow entryuuid to be strings, on import these may
|
|
|
b03d2c |
+ // be invalid. As a result, we DO need to allow the fixup to check the entryuuid
|
|
|
b03d2c |
+ // value is correct, so we can not exclude these during the search.
|
|
|
b03d2c |
+ /*
|
|
|
b03d2c |
let raw_filter = if !raw_filter.starts_with('(') && !raw_filter.ends_with('(') {
|
|
|
b03d2c |
format!("(&({})(!(entryuuid=*)))", raw_filter)
|
|
|
b03d2c |
} else {
|
|
|
b03d2c |
format!("(&{}(!(entryuuid=*)))", raw_filter)
|
|
|
b03d2c |
};
|
|
|
b03d2c |
+ */
|
|
|
b03d2c |
|
|
|
b03d2c |
Ok(FixupData { basedn, raw_filter })
|
|
|
b03d2c |
}
|
|
|
b03d2c |
@@ -213,14 +219,20 @@ pub fn entryuuid_fixup_mapfn(e: &EntryRef, _data: &()) -> Result<(), PluginError
|
|
|
b03d2c |
/* Supply a modification to the entry. */
|
|
|
b03d2c |
let sdn = e.get_sdnref();
|
|
|
b03d2c |
|
|
|
b03d2c |
- /* Sanity check that entryuuid doesn't already exist */
|
|
|
b03d2c |
- if e.contains_attr("entryUUID") {
|
|
|
b03d2c |
- log_error!(
|
|
|
b03d2c |
- ErrorLevel::Plugin,
|
|
|
b03d2c |
- "skipping fixup for -> {}",
|
|
|
b03d2c |
- sdn.to_dn_string()
|
|
|
b03d2c |
- );
|
|
|
b03d2c |
- return Ok(());
|
|
|
b03d2c |
+ /* Check that entryuuid doesn't already exist, and is valid */
|
|
|
b03d2c |
+ if let Some(valueset) = e.get_attr("entryUUID") {
|
|
|
b03d2c |
+ if valueset.iter().all(|v| {
|
|
|
b03d2c |
+ let u: Result<Uuid, _> = (&v).try_into();
|
|
|
b03d2c |
+ u.is_ok()
|
|
|
b03d2c |
+ }) {
|
|
|
b03d2c |
+ // All values were valid uuid, move on!
|
|
|
b03d2c |
+ log_error!(
|
|
|
b03d2c |
+ ErrorLevel::Plugin,
|
|
|
b03d2c |
+ "skipping fixup for -> {}",
|
|
|
b03d2c |
+ sdn.to_dn_string()
|
|
|
b03d2c |
+ );
|
|
|
b03d2c |
+ return Ok(());
|
|
|
b03d2c |
+ }
|
|
|
b03d2c |
}
|
|
|
b03d2c |
|
|
|
b03d2c |
// Setup the modifications
|
|
|
b03d2c |
diff --git a/src/slapi_r_plugin/src/pblock.rs b/src/slapi_r_plugin/src/pblock.rs
|
|
|
b03d2c |
index 718ff2ca7..ac1b3c33b 100644
|
|
|
b03d2c |
--- a/src/slapi_r_plugin/src/pblock.rs
|
|
|
b03d2c |
+++ b/src/slapi_r_plugin/src/pblock.rs
|
|
|
b03d2c |
@@ -281,7 +281,9 @@ impl PblockRef {
|
|
|
b03d2c |
}
|
|
|
b03d2c |
|
|
|
b03d2c |
pub fn get_is_replicated_operation(&mut self) -> bool {
|
|
|
b03d2c |
- let i = self.get_value_i32(PblockType::IsReplicationOperation).unwrap_or(0);
|
|
|
b03d2c |
+ let i = self
|
|
|
b03d2c |
+ .get_value_i32(PblockType::IsReplicationOperation)
|
|
|
b03d2c |
+ .unwrap_or(0);
|
|
|
b03d2c |
// Because rust returns the result of the last evaluation, we can
|
|
|
b03d2c |
// just return if not equal 0.
|
|
|
b03d2c |
i != 0
|
|
|
b03d2c |
diff --git a/src/slapi_r_plugin/src/value.rs b/src/slapi_r_plugin/src/value.rs
|
|
|
b03d2c |
index 46246837a..cd565295c 100644
|
|
|
b03d2c |
--- a/src/slapi_r_plugin/src/value.rs
|
|
|
b03d2c |
+++ b/src/slapi_r_plugin/src/value.rs
|
|
|
b03d2c |
@@ -1,6 +1,6 @@
|
|
|
b03d2c |
use crate::ber::{ol_berval, BerValRef};
|
|
|
b03d2c |
use crate::dn::Sdn;
|
|
|
b03d2c |
-use std::convert::{From, TryFrom};
|
|
|
b03d2c |
+use std::convert::{From, TryFrom, TryInto};
|
|
|
b03d2c |
use std::ffi::CString;
|
|
|
b03d2c |
use std::iter::once;
|
|
|
b03d2c |
use std::iter::FromIterator;
|
|
|
b03d2c |
@@ -213,6 +213,14 @@ impl TryFrom<&ValueRef> for String {
|
|
|
b03d2c |
}
|
|
|
b03d2c |
}
|
|
|
b03d2c |
|
|
|
b03d2c |
+impl TryFrom<&ValueRef> for Uuid {
|
|
|
b03d2c |
+ type Error = ();
|
|
|
b03d2c |
+
|
|
|
b03d2c |
+ fn try_from(value: &ValueRef) -> Result<Self, Self::Error> {
|
|
|
b03d2c |
+ (&value.bvr).try_into().map_err(|_| ())
|
|
|
b03d2c |
+ }
|
|
|
b03d2c |
+}
|
|
|
b03d2c |
+
|
|
|
b03d2c |
impl TryFrom<&ValueRef> for Sdn {
|
|
|
b03d2c |
type Error = ();
|
|
|
b03d2c |
|
|
|
b03d2c |
--
|
|
|
b03d2c |
2.31.1
|
|
|
b03d2c |
|