From a6849596f4059405de17f8c3b7e1a8ca2c28667a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 17 Oct 2017 23:01:51 +1300 Subject: [PATCH 01/18] dbcheck: Allow removal of one-way links to missing objects If dbcheck is not run within the tombstone lifetime, these links can persist in the database forever. The risk of unintentional information loss is why these links are only removed within the same partition. A replication may be in progress which has created only one end of the link, so we must keep that. Signed-off-by: Andrew Bartlett Reviewed-by: Rowland Penny Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Thu Oct 19 00:50:19 CEST 2017 on sn-devel-144 (cherry picked from commit 962a1b32201fce0a49c6be55943d4fbb57ed781e) --- python/samba/dbchecker.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index 1a73fe0..82088a0 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -523,8 +523,26 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) # check if its a backlink linkID, _ = self.get_attr_linkID_and_reverse_name(attrname) if (linkID & 1 == 0) and str(dsdb_dn).find('\\0ADEL') == -1: - self.report("Not removing dangling forward link") - return + + linkID, reverse_link_name \ + = self.get_attr_linkID_and_reverse_name(attrname) + if reverse_link_name is not None: + self.report("Not removing dangling forward link") + return + + nc_root = self.samdb.get_nc_root(dn) + target_nc_root = self.samdb.get_nc_root(dsdb_dn.dn) + if nc_root != target_nc_root: + self.report("Not removing dangling one-way " + "cross-partition link " + "(we might be mid-replication)") + return + + # Due to our link handling one-way links pointing to + # missing objects are plausible. + self.err_deleted_dn(dn, attrname, val, + dsdb_dn, dsdb_dn, True) + self.err_deleted_dn(dn, attrname, val, dsdb_dn, dsdb_dn, False) def err_missing_dn_GUID_component(self, dn, attrname, val, dsdb_dn, errstr): -- 1.9.1 From 1ef3615273cf4c92df6e502b5674a7c6345585f5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Aug 2017 17:37:05 +1200 Subject: [PATCH 02/18] selftest: sort dbcheck output to avoid sort order impacting results The GUID index code will change the returned results order Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit da575f01313673fedfc7d15ec11ba6818dbd30d8) --- testprogs/blackbox/dbcheck-links.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/testprogs/blackbox/dbcheck-links.sh b/testprogs/blackbox/dbcheck-links.sh index fb66d14..17973e9 100755 --- a/testprogs/blackbox/dbcheck-links.sh +++ b/testprogs/blackbox/dbcheck-links.sh @@ -59,7 +59,9 @@ dbcheck() { if [ "$?" != "1" ]; then return 1 fi - diff $tmpfile $release_dir/expected-dbcheck-link-output.txt + sort $tmpfile > $tmpfile.sorted + sort $release_dir/expected-dbcheck-link-output.txt > $tmpfile.expected + diff -u $tmpfile.sorted $tmpfile.expected if [ "$?" != "0" ]; then return 1 fi -- 1.9.1 From c7011ee32079ca53418e9f1be0c9de675a6a93fa Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 30 Oct 2017 09:48:43 +1300 Subject: [PATCH 03/18] dbcheck: Clarify error count bumping in deleted/gone DN handling Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher (cherry picked from commit 3b111fbdbed99d5d90c1120243200baae9867534) --- python/samba/dbchecker.py | 40 ++++++++++++++++++---- .../expected-dbcheck-link-output.txt | 34 +++++++++--------- 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index 82088a0..8bbd65f 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -498,13 +498,15 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) def err_deleted_dn(self, dn, attrname, val, dsdb_dn, correct_dn, remove_plausible=False): """handle a DN pointing to a deleted object""" - self.report("ERROR: target DN is deleted for %s in object %s - %s" % (attrname, dn, val)) - self.report("Target GUID points at deleted DN %r" % str(correct_dn)) if not remove_plausible: + self.report("ERROR: target DN is deleted for %s in object %s - %s" % (attrname, dn, val)) + self.report("Target GUID points at deleted DN %r" % str(correct_dn)) if not self.confirm_all('Remove DN link?', 'remove_implausible_deleted_DN_links'): self.report("Not removing") return else: + self.report("WARNING: target DN is deleted for %s in object %s - %s" % (attrname, dn, val)) + self.report("Target GUID points at deleted DN %r" % str(correct_dn)) if not self.confirm_all('Remove stale DN link?', 'remove_plausible_deleted_DN_links'): self.report("Not removing") return @@ -527,23 +529,45 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) linkID, reverse_link_name \ = self.get_attr_linkID_and_reverse_name(attrname) if reverse_link_name is not None: + self.report("WARNING: no target object found for GUID " + "component for one-way forward link " + "%s in object " + "%s - %s" % (attrname, dn, val)) self.report("Not removing dangling forward link") - return + return 0 nc_root = self.samdb.get_nc_root(dn) target_nc_root = self.samdb.get_nc_root(dsdb_dn.dn) if nc_root != target_nc_root: + # We don't bump the error count as Samba produces these + # in normal operation + self.report("WARNING: no target object found for GUID " + "component for cross-partition link " + "%s in object " + "%s - %s" % (attrname, dn, val)) self.report("Not removing dangling one-way " "cross-partition link " "(we might be mid-replication)") - return + return 0 # Due to our link handling one-way links pointing to # missing objects are plausible. + # + # We don't bump the error count as Samba produces these + # in normal operation + self.report("WARNING: no target object found for GUID " + "component for DN value %s in object " + "%s - %s" % (attrname, dn, val)) self.err_deleted_dn(dn, attrname, val, dsdb_dn, dsdb_dn, True) + return 0 + # We bump the error count here, as we should have deleted this + self.report("ERROR: no target object found for GUID " + "component for link %s in object " + "%s - %s" % (attrname, dn, val)) self.err_deleted_dn(dn, attrname, val, dsdb_dn, dsdb_dn, False) + return 1 def err_missing_dn_GUID_component(self, dn, attrname, val, dsdb_dn, errstr): """handle a missing GUID extended DN component""" @@ -883,12 +907,14 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) "reveal_internals:0" ]) except ldb.LdbError, (enum, estr): - error_count += 1 - self.report("ERROR: no target object found for GUID component for %s in object %s - %s" % (attrname, obj.dn, val)) if enum != ldb.ERR_NO_SUCH_OBJECT: raise - self.err_missing_target_dn_or_GUID(obj.dn, attrname, val, dsdb_dn) + # We don't always want to + error_count += self.err_missing_target_dn_or_GUID(obj.dn, + attrname, + val, + dsdb_dn) continue if fixing_msDS_HasInstantiatedNCs: diff --git a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt index ea2ef23..772331b 100644 --- a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt +++ b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt @@ -1,8 +1,11 @@ Checking 223 objects -ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gsg\0ADEL:91aa85cc-fc19-4b8c-9fc7-aaba425439c7,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +ERROR: missing backlink attribute 'memberOf' in CN=dangling-forward,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp for link member in CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +Fix missing backlink memberOf [YES] +Fixed missing backlink memberOf +ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=dsg\0ADEL:6d66d0ef-cad7-4e5d-b1b6-4a233a21c269,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gsg\0ADEL:91aa85cc-fc19-4b8c-9fc7-aaba425439c7,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=dsg\0ADEL:6d66d0ef-cad7-4e5d-b1b6-4a233a21c269,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp @@ -11,38 +14,35 @@ Fixed undead forward link member ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: missing backlink attribute 'memberOf' in CN=dangling-forward,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp for link member in CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp -Fix missing backlink memberOf [YES] -Fixed missing backlink memberOf -ERROR: target DN is deleted for member in object CN=swimmers,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp - ;;;;;;;;;CN=fred,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp -Target GUID points at deleted DN 'CN=fred\\0ADEL:2301a64c-5b42-4ca8-851e-12d4a711cfb4,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp' -Remove stale DN link? [YES] -Removed deleted DN on attribute member -ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=usg\0ADEL:d012e8f5-a4bd-40ea-a2a1-68ff2508847d,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=usg\0ADEL:d012e8f5-a4bd-40ea-a2a1-68ff2508847d,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=dsg\0ADEL:6d66d0ef-cad7-4e5d-b1b6-4a233a21c269,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=ddg\0ADEL:fb8c2fe3-5448-43de-99f9-e1d3b9357cfc,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=dsg\0ADEL:6d66d0ef-cad7-4e5d-b1b6-4a233a21c269,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=ddg\0ADEL:fb8c2fe3-5448-43de-99f9-e1d3b9357cfc,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member ERROR: orphaned backlink attribute 'memberOf' in CN=dangling-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp for link member in CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove orphaned backlink memberOf [YES] Fixed orphaned backlink memberOf -ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=usg\0ADEL:d012e8f5-a4bd-40ea-a2a1-68ff2508847d,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +WARNING: target DN is deleted for member in object CN=swimmers,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp - ;;;;;;;;;CN=fred,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +Target GUID points at deleted DN 'CN=fred\\0ADEL:2301a64c-5b42-4ca8-851e-12d4a711cfb4,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp' +Remove stale DN link? [YES] +Removed deleted DN on attribute member +ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gsg\0ADEL:91aa85cc-fc19-4b8c-9fc7-aaba425439c7,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=usg\0ADEL:d012e8f5-a4bd-40ea-a2a1-68ff2508847d,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gsg\0ADEL:91aa85cc-fc19-4b8c-9fc7-aaba425439c7,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=ddg\0ADEL:fb8c2fe3-5448-43de-99f9-e1d3b9357cfc,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=ddg\0ADEL:fb8c2fe3-5448-43de-99f9-e1d3b9357cfc,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member Checked 223 objects (15 errors) -- 1.9.1 From 7cf776c12a525ffc223e082886ecb056c2d40e78 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 30 Oct 2017 10:51:35 +1300 Subject: [PATCH 04/18] dbcheck: Use the GUID as the DN to fix replPropertyMetaData This allows this to still work after an object is renamed under the deleted objects container. Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher (cherry picked from commit 527f2c95cfe24d29fa34ed19db3b073781d96d9a) --- python/samba/dbchecker.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index 8bbd65f..45bfdbf 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -1123,11 +1123,14 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) return (set_att, list_attid, wrong_attids) - def fix_metadata(self, dn, attr): + def fix_metadata(self, obj, attr): '''re-write replPropertyMetaData elements for a single attribute for a object. This is used to fix missing replPropertyMetaData elements''' + guid_str = str(ndr_unpack(misc.GUID, obj['objectGUID'][0])) + dn = ldb.Dn(self.samdb, "" % guid_str) res = self.samdb.search(base = dn, scope=ldb.SCOPE_BASE, attrs = [attr], - controls = ["search_options:1:2", "show_recycled:1"]) + controls = ["search_options:1:2", + "show_recycled:1"]) msg = res[0] nmsg = ldb.Message() nmsg.dn = dn @@ -1969,7 +1972,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) if not self.confirm_all("Fix missing replPropertyMetaData element '%s'" % att, 'fix_all_metadata'): self.report("Not fixing missing replPropertyMetaData element '%s'" % att) continue - self.fix_metadata(dn, att) + self.fix_metadata(obj, att) if self.is_fsmo_role(dn): if "fSMORoleOwner" not in obj and ("*" in attrs or "fsmoroleowner" in map(str.lower, attrs)): -- 1.9.1 From 46ff02c36b46f4a379e0493a7b9d43245ff6cb2a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 30 Oct 2017 15:29:36 +1300 Subject: [PATCH 05/18] selftest: add more dbcheck tests This validates some more combinations and ensures that the changes in 962a1b32201fce0a49c6be55943d4fbb57ed781e are tested. Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher (cherry picked from commit 7be38c605468786894a373e15068b8017323da78) --- .../add-dangling-deleted-link.ldif | 5 ++ .../add-deleted-backlink-user.ldif | 3 + .../release-4-5-0-pre1/add-deleted-backlink.ldif | 5 ++ .../add-deleted-target-backlink-user.ldif | 3 + .../add-deleted-target-backlink.ldif | 4 + .../release-4-5-0-pre1/dangling-one-way-dn.ldif | 15 ++++ .../release-4-5-0-pre1/dangling-one-way-link.ldif | 22 ++--- .../release-4-5-0-pre1/deleted-one-way-dn.ldif | 13 +++ .../expected-dbcheck-link-output.txt | 21 +++-- .../expected-dbcheck-link-output_one_way.txt | 7 ++ testprogs/blackbox/dbcheck-links.sh | 93 +++++++++++++++++++--- 11 files changed, 159 insertions(+), 32 deletions(-) create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/add-dangling-deleted-link.ldif create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/add-deleted-backlink-user.ldif create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/add-deleted-backlink.ldif create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/add-deleted-target-backlink-user.ldif create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/add-deleted-target-backlink.ldif create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/dangling-one-way-dn.ldif create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/deleted-one-way-dn.ldif create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output_one_way.txt diff --git a/source4/selftest/provisions/release-4-5-0-pre1/add-dangling-deleted-link.ldif b/source4/selftest/provisions/release-4-5-0-pre1/add-dangling-deleted-link.ldif new file mode 100644 index 0000000..b740252 --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/add-dangling-deleted-link.ldif @@ -0,0 +1,5 @@ +dn: CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: modify +add: member +member: ;;CN=fred\0ADEL:2301a64c-5b42-4ca8-851e-12d4a711cfb4,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +- diff --git a/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-backlink-user.ldif b/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-backlink-user.ldif new file mode 100644 index 0000000..19b6d65 --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-backlink-user.ldif @@ -0,0 +1,3 @@ +dn: CN=deleted-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +objectclass: user +samaccountname: deleted-back diff --git a/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-backlink.ldif b/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-backlink.ldif new file mode 100644 index 0000000..14e014a --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-backlink.ldif @@ -0,0 +1,5 @@ +dn:CN=dsg\0ADEL:6d66d0ef-cad7-4e5d-b1b6-4a233a21c269,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: modify +add: memberOf +memberOf: ;;CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +- \ No newline at end of file diff --git a/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-target-backlink-user.ldif b/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-target-backlink-user.ldif new file mode 100644 index 0000000..6e99aae --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-target-backlink-user.ldif @@ -0,0 +1,3 @@ +dn: CN=deleted-target-back,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp +objectclass: user +samaccountname: deleted-target-back diff --git a/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-target-backlink.ldif b/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-target-backlink.ldif new file mode 100644 index 0000000..6a46e28 --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-target-backlink.ldif @@ -0,0 +1,4 @@ +dn: CN=deleted-target-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: modify +add: memberOf +memberOf: ;;CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp diff --git a/source4/selftest/provisions/release-4-5-0-pre1/dangling-one-way-dn.ldif b/source4/selftest/provisions/release-4-5-0-pre1/dangling-one-way-dn.ldif new file mode 100644 index 0000000..c215c06 --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/dangling-one-way-dn.ldif @@ -0,0 +1,15 @@ +dn: CN=secretary,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: add +objectclass: user +samaccountname: secretary + +dn: CN=dangling-one-way,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: add +objectclass: user +samaccountname: dangling-one-way +secretary: CN=secretary,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp + +dn: CN=secretary,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: modrdn +newrdn: cn=new-secretary +deleteoldrdn: 1 diff --git a/source4/selftest/provisions/release-4-5-0-pre1/dangling-one-way-link.ldif b/source4/selftest/provisions/release-4-5-0-pre1/dangling-one-way-link.ldif index c215c06..2e43cca 100644 --- a/source4/selftest/provisions/release-4-5-0-pre1/dangling-one-way-link.ldif +++ b/source4/selftest/provisions/release-4-5-0-pre1/dangling-one-way-link.ldif @@ -1,15 +1,7 @@ -dn: CN=secretary,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp -changetype: add -objectclass: user -samaccountname: secretary - -dn: CN=dangling-one-way,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp -changetype: add -objectclass: user -samaccountname: dangling-one-way -secretary: CN=secretary,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp - -dn: CN=secretary,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp -changetype: modrdn -newrdn: cn=new-secretary -deleteoldrdn: 1 +dn: CN=36a28334-a8d3-4e67-bfe9-7e66c1af7cff,CN=Partitions,CN=Configuration,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: modify +add: msDS-NC-Replica-Locations +msDS-NC-Replica-Locations: ;CN=NTDS + Settings,CN=NOT-A_SERVER,CN=Servers,CN=Default-First-Site-Name,CN=Sites,C + N=Configuration,DC=release-4-5-0-pre1,DC=samba,DC=corp +- diff --git a/source4/selftest/provisions/release-4-5-0-pre1/deleted-one-way-dn.ldif b/source4/selftest/provisions/release-4-5-0-pre1/deleted-one-way-dn.ldif new file mode 100644 index 0000000..b6cd3df --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/deleted-one-way-dn.ldif @@ -0,0 +1,13 @@ +dn: CN=secretary-del,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: add +objectclass: user +samaccountname: secretary-del + +dn: CN=deleted-one-way-del,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: add +objectclass: user +samaccountname: dangling-one-way-del +secretary: CN=secretary-del,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp + +dn: CN=secretary-del,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: delete diff --git a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt index 772331b..44e10d0 100644 --- a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt +++ b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt @@ -1,13 +1,20 @@ -Checking 223 objects +Checking 225 objects ERROR: missing backlink attribute 'memberOf' in CN=dangling-forward,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp for link member in CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp Fix missing backlink memberOf [YES] Fixed missing backlink memberOf +ERROR: target DN is deleted for member in object CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp - ;;CN=fred\0ADEL:2301a64c-5b42-4ca8-851e-12d4a711cfb4,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +Target GUID points at deleted DN 'CN=fred\\0ADEL:2301a64c-5b42-4ca8-851e-12d4a711cfb4,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp' +Remove DN link? [YES] +Removed deleted DN on attribute member ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=dsg\0ADEL:6d66d0ef-cad7-4e5d-b1b6-4a233a21c269,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=dsg\0ADEL:6d66d0ef-cad7-4e5d-b1b6-4a233a21c269,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member +ERROR: linked attribute 'memberOf' to ';;CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=dsg\0ADEL:6d66d0ef-cad7-4e5d-b1b6-4a233a21c269,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +Remove linked attribute memberOf [YES] +Fixed undead forward link memberOf ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member @@ -26,23 +33,27 @@ Fixed undead forward link member ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=ddg\0ADEL:fb8c2fe3-5448-43de-99f9-e1d3b9357cfc,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: orphaned backlink attribute 'memberOf' in CN=dangling-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp for link member in CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp -Remove orphaned backlink memberOf [YES] -Fixed orphaned backlink memberOf WARNING: target DN is deleted for member in object CN=swimmers,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp - ;;;;;;;;;CN=fred,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp Target GUID points at deleted DN 'CN=fred\\0ADEL:2301a64c-5b42-4ca8-851e-12d4a711cfb4,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp' Remove stale DN link? [YES] Removed deleted DN on attribute member +ERROR: target DN is deleted for memberOf in object CN=deleted-target-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp - ;;CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +Target GUID points at deleted DN 'CN=gdg\\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp' +Remove DN link? [YES] +Removed deleted DN on attribute memberOf ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gsg\0ADEL:91aa85cc-fc19-4b8c-9fc7-aaba425439c7,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gsg\0ADEL:91aa85cc-fc19-4b8c-9fc7-aaba425439c7,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member +ERROR: orphaned backlink attribute 'memberOf' in CN=dangling-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp for link member in CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +Remove orphaned backlink memberOf [YES] +Fixed orphaned backlink memberOf ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -Checked 223 objects (15 errors) +Checked 225 objects (18 errors) diff --git a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output_one_way.txt b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output_one_way.txt new file mode 100644 index 0000000..4309d1f --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output_one_way.txt @@ -0,0 +1,7 @@ +Checking 1612 objects +WARNING: no target object found for GUID component for DN value msDS-NC-Replica-Locations in object CN=36a28334-a8d3-4e67-bfe9-7e66c1af7cff,CN=Partitions,CN=Configuration,DC=release-4-5-0-pre1,DC=samba,DC=corp - ;CN=NTDS Settings,CN=NOT-A_SERVER,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=release-4-5-0-pre1,DC=samba,DC=corp +WARNING: target DN is deleted for msDS-NC-Replica-Locations in object CN=36a28334-a8d3-4e67-bfe9-7e66c1af7cff,CN=Partitions,CN=Configuration,DC=release-4-5-0-pre1,DC=samba,DC=corp - ;CN=NTDS Settings,CN=NOT-A_SERVER,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=release-4-5-0-pre1,DC=samba,DC=corp +Target GUID points at deleted DN ';CN=NTDS Settings,CN=NOT-A_SERVER,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=release-4-5-0-pre1,DC=samba,DC=corp' +Remove stale DN link? [YES] +Removed deleted DN on attribute msDS-NC-Replica-Locations +Checked 1612 objects (0 errors) diff --git a/testprogs/blackbox/dbcheck-links.sh b/testprogs/blackbox/dbcheck-links.sh index 17973e9..655e1aa 100755 --- a/testprogs/blackbox/dbcheck-links.sh +++ b/testprogs/blackbox/dbcheck-links.sh @@ -50,31 +50,41 @@ undump() { } dbcheck() { - tmpfile=$PREFIX_ABS/$RELEASE/expected-dbcheck-link-output.txt.tmp - tmpldif1=$PREFIX_ABS/$RELEASE/expected-dbcheck-output2.txt.tmp1 + tmpfile=$PREFIX_ABS/$RELEASE/expected-dbcheck-link-output${1}.txt.tmp + tmpldif1=$PREFIX_ABS/$RELEASE/expected-dbcheck-output${1}2.txt.tmp1 TZ=UTC $ldbsearch -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb -s base -b '' | grep highestCommittedUSN > $tmpldif1 - $PYTHON $BINDIR/samba-tool dbcheck -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb --fix --yes > $tmpfile - if [ "$?" != "1" ]; then + $PYTHON $BINDIR/samba-tool dbcheck -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $3 --fix --yes > $tmpfile + if [ "$?" != "$2" ]; then return 1 fi sort $tmpfile > $tmpfile.sorted - sort $release_dir/expected-dbcheck-link-output.txt > $tmpfile.expected + sort $release_dir/expected-dbcheck-link-output${1}.txt > $tmpfile.expected diff -u $tmpfile.sorted $tmpfile.expected if [ "$?" != "0" ]; then return 1 fi - tmpldif2=$PREFIX_ABS/$RELEASE/expected-dbcheck-output2.txt.tmp2 + tmpldif2=$PREFIX_ABS/$RELEASE/expected-dbcheck-output${1}2.txt.tmp2 TZ=UTC $ldbsearch -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb -s base -b '' | grep highestCommittedUSN > $tmpldif2 - diff $tmpldif1 $tmpldif2 + diff -u $tmpldif1 $tmpldif2 if [ "$?" != "0" ]; then return 1 fi } +dbcheck_dangling() { + dbcheck "" "1" "" + return $? +} + +dbcheck_one_way() { + dbcheck "_one_way" "0" "CN=Configuration,DC=release-4-5-0-pre1,DC=samba,DC=corp" + return $? +} + dbcheck_clean() { tmpldif1=$PREFIX_ABS/$RELEASE/expected-dbcheck-output2.txt.tmp1 @@ -127,6 +137,42 @@ add_dangling_backlink() { fi } +add_deleted_dangling_backlink() { + ldif=$release_dir/add-deleted-backlink-user.ldif + TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi + + ldif=$release_dir/add-deleted-backlink.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +add_deleted_target_backlink() { + ldif=$release_dir/add-deleted-target-backlink-user.ldif + TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi + + ldif=$release_dir/add-deleted-target-backlink.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +add_deleted_target_link() { + ldif=$release_dir/add-dangling-deleted-link.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + add_two_more_users() { ldif=$release_dir/add-two-more-users.ldif TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif @@ -193,14 +239,30 @@ check_expected_after_objects() { fi } -dangling_one_way() { - ldif=$release_dir/dangling-one-way-link.ldif +dangling_one_way_dn() { + ldif=$release_dir/dangling-one-way-dn.ldif TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif if [ "$?" != "0" ]; then return 1 fi } +deleted_one_way_dn() { + ldif=$release_dir/deleted-one-way-dn.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +dangling_one_way_link() { + ldif=$release_dir/dangling-one-way-link.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/CN%3DCONFIGURATION,DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + dangling_multi_valued() { # multi1 - All 4 backlinks # multi2 - Missing all 4 backlinks @@ -282,13 +344,20 @@ if [ -d $release_dir ]; then testit "move_one_user" move_one_user testit "add_dangling_link" add_dangling_link testit "add_dangling_backlink" add_dangling_backlink - testit "dbcheck" dbcheck + testit "add_deleted_dangling_backlink" add_deleted_dangling_backlink + testit "add_deleted_target_link" add_deleted_target_link + testit "add_deleted_target_backlink" add_deleted_target_backlink + testit "dbcheck_dangling" dbcheck_dangling testit "dbcheck_clean" dbcheck_clean testit "check_expected_after_deleted_links" check_expected_after_deleted_links testit "check_expected_after_links" check_expected_after_links testit "check_expected_after_objects" check_expected_after_objects - testit "dangling_one_way" dangling_one_way - testit "dbcheck_clean" dbcheck_clean + testit "dangling_one_way_link" dangling_one_way_link + testit "dbcheck_one_way" dbcheck_one_way + testit "dbcheck_clean2" dbcheck_clean + testit "dangling_one_way_dn" dangling_one_way_dn + testit "deleted_one_way_dn" deleted_one_way_dn + testit "dbcheck_clean3" dbcheck_clean testit "dangling_multi_valued" dangling_multi_valued testit "dangling_multi_valued_check_missing" dangling_multi_valued_check_missing testit "dangling_multi_valued_check_equal_or_too_many" dangling_multi_valued_check_equal_or_too_many -- 1.9.1 From fb23e5d84087f4f48b4c22c6bf7c2ecd607c1912 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 31 Oct 2017 08:21:15 +1300 Subject: [PATCH 06/18] selftest: Split out dbcheck runs from dangling_multi_valued test Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher (cherry picked from commit b99d2ee122991d0bf1742fa5665656bbbba44057) --- selftest/knownfail | 2 +- testprogs/blackbox/dbcheck-links.sh | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index dfa055f..dd23c7d 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -318,7 +318,7 @@ ^samba3.smb2.credits.session_setup_credits_granted.* ^samba3.smb2.credits.single_req_credits_granted.* ^samba3.smb2.credits.skipped_mid.* -^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dangling_multi_valued_dbcheck +^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dbcheck_dangling_multi_valued_clean ^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dangling_multi_valued_check_missing # # rap password tests don't function in the ad_dc_ntvfs:local environment diff --git a/testprogs/blackbox/dbcheck-links.sh b/testprogs/blackbox/dbcheck-links.sh index 655e1aa..208ec00 100755 --- a/testprogs/blackbox/dbcheck-links.sh +++ b/testprogs/blackbox/dbcheck-links.sh @@ -263,7 +263,7 @@ dangling_one_way_link() { fi } -dangling_multi_valued() { +add_dangling_multi_valued() { # multi1 - All 4 backlinks # multi2 - Missing all 4 backlinks # multi3 - Missing 2 backlinks @@ -292,6 +292,9 @@ dangling_multi_valued() { if [ "$?" != "0" ]; then return 1 fi +} + +dbcheck_dangling_multi_valued() { $PYTHON $BINDIR/samba-tool dbcheck -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb --fix --yes if [ "$?" != "1" ]; then @@ -358,11 +361,12 @@ if [ -d $release_dir ]; then testit "dangling_one_way_dn" dangling_one_way_dn testit "deleted_one_way_dn" deleted_one_way_dn testit "dbcheck_clean3" dbcheck_clean - testit "dangling_multi_valued" dangling_multi_valued + testit "add_dangling_multi_valued" add_dangling_multi_valued + testit "dbcheck_dangling_multi_valued" dbcheck_dangling_multi_valued testit "dangling_multi_valued_check_missing" dangling_multi_valued_check_missing testit "dangling_multi_valued_check_equal_or_too_many" dangling_multi_valued_check_equal_or_too_many # Currently this cannot pass - testit "dangling_multi_valued_dbcheck" dbcheck_clean + testit "dbcheck_dangling_multi_valued_clean" dbcheck_clean else subunit_start_test $RELEASE subunit_skip_test $RELEASE < Date: Tue, 31 Oct 2017 08:23:39 +1300 Subject: [PATCH 07/18] selftest: Split out creation of complex (often invalid) links This will allow us to test other run-time behaviour with broken databases. Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher (cherry picked from commit 25ae8d72d66cbe7342b50254ede7e5890bc23b73) --- testprogs/blackbox/common-links.sh | 199 +++++++++++++++++++++++++++++++++++ testprogs/blackbox/dbcheck-links.sh | 200 +----------------------------------- 2 files changed, 200 insertions(+), 199 deletions(-) create mode 100644 testprogs/blackbox/common-links.sh diff --git a/testprogs/blackbox/common-links.sh b/testprogs/blackbox/common-links.sh new file mode 100644 index 0000000..7c80e35 --- /dev/null +++ b/testprogs/blackbox/common-links.sh @@ -0,0 +1,199 @@ +release_dir=`dirname $0`/../../source4/selftest/provisions/$RELEASE + +ldbadd="ldbadd" +if [ -x "$BINDIR/ldbadd" ]; then + ldbadd="$BINDIR/ldbadd" +fi + +ldbmodify="ldbmodify" +if [ -x "$BINDIR/ldbmodify" ]; then + ldbmodify="$BINDIR/ldbmodify" +fi + +ldbdel="ldbdel" +if [ -x "$BINDIR/ldbdel" ]; then + ldbdel="$BINDIR/ldbdel" +fi + +ldbsearch="ldbsearch" +if [ -x "$BINDIR/ldbsearch" ]; then + ldbsearch="$BINDIR/ldbsearch" +fi + +ldbrename="ldbrename" +if [ -x "$BINDIR/ldbrename" ]; then + ldbrename="$BINDIR/ldbrename" +fi + +undump() { + if test -x $BINDIR/tdbrestore; + then + `dirname $0`/../../source4/selftest/provisions/undump.sh $release_dir $PREFIX_ABS/$RELEASE $BINDIR/tdbrestore + else + `dirname $0`/../../source4/selftest/provisions/undump.sh $release_dir $PREFIX_ABS/$RELEASE + fi +} + +add_dangling_link() { + ldif=$release_dir/add-dangling-forwardlink-user.ldif + TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi + + ldif=$release_dir/add-initially-normal-link.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi + + ldif=$release_dir/delete-only-backlink.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +add_dangling_backlink() { + ldif=$release_dir/add-dangling-backlink-user.ldif + TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi + + ldif=$release_dir/add-dangling-backlink.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +add_deleted_dangling_backlink() { + ldif=$release_dir/add-deleted-backlink-user.ldif + TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi + + ldif=$release_dir/add-deleted-backlink.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +add_deleted_target_backlink() { + ldif=$release_dir/add-deleted-target-backlink-user.ldif + TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi + + ldif=$release_dir/add-deleted-target-backlink.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +add_deleted_target_link() { + ldif=$release_dir/add-dangling-deleted-link.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +add_two_more_users() { + ldif=$release_dir/add-two-more-users.ldif + TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +add_four_more_links() { + ldif=$release_dir/add-four-more-links.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +remove_one_link() { + ldif=$release_dir/remove-one-more-link.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +remove_one_user() { + ldif=$release_dir/remove-one-more-user.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +move_one_user() { + TZ=UTC $ldbrename -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb 'cn=user1,cn=users,DC=release-4-5-0-pre1,DC=samba,DC=corp' 'cn=user1x,cn=users,DC=release-4-5-0-pre1,DC=samba,DC=corp' + if [ "$?" != "0" ]; then + return 1 + fi +} + +dangling_one_way_dn() { + ldif=$release_dir/dangling-one-way-dn.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +deleted_one_way_dn() { + ldif=$release_dir/deleted-one-way-dn.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +dangling_one_way_link() { + ldif=$release_dir/dangling-one-way-link.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/CN%3DCONFIGURATION,DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +add_dangling_multi_valued() { + # multi1 - All 4 backlinks + # multi2 - Missing all 4 backlinks + # multi3 - Missing 2 backlinks + # Administrator - Has 2 too many backlinks + # multi5 - Has 2 backlinks but no forward links + ldif=$release_dir/add-dangling-multilink-users.ldif + TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi + + ldif=$release_dir/add-initially-normal-multilink.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi + + ldif=$release_dir/delete-only-multi-backlink.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi + + ldif=$release_dir/add-dangling-multi-backlink.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} diff --git a/testprogs/blackbox/dbcheck-links.sh b/testprogs/blackbox/dbcheck-links.sh index 208ec00..e1db50f 100755 --- a/testprogs/blackbox/dbcheck-links.sh +++ b/testprogs/blackbox/dbcheck-links.sh @@ -13,41 +13,7 @@ shift 2 . `dirname $0`/subunit.sh -release_dir=`dirname $0`/../../source4/selftest/provisions/$RELEASE - -ldbadd="ldbadd" -if [ -x "$BINDIR/ldbadd" ]; then - ldbadd="$BINDIR/ldbadd" -fi - -ldbmodify="ldbmodify" -if [ -x "$BINDIR/ldbmodify" ]; then - ldbmodify="$BINDIR/ldbmodify" -fi - -ldbdel="ldbdel" -if [ -x "$BINDIR/ldbdel" ]; then - ldbdel="$BINDIR/ldbdel" -fi - -ldbsearch="ldbsearch" -if [ -x "$BINDIR/ldbsearch" ]; then - ldbsearch="$BINDIR/ldbsearch" -fi - -ldbrename="ldbrename" -if [ -x "$BINDIR/ldbrename" ]; then - ldbrename="$BINDIR/ldbrename" -fi - -undump() { - if test -x $BINDIR/tdbrestore; - then - `dirname $0`/../../source4/selftest/provisions/undump.sh $release_dir $PREFIX_ABS/$RELEASE $BINDIR/tdbrestore - else - `dirname $0`/../../source4/selftest/provisions/undump.sh $release_dir $PREFIX_ABS/$RELEASE - fi -} +. `dirname $0`/common-links.sh dbcheck() { tmpfile=$PREFIX_ABS/$RELEASE/expected-dbcheck-link-output${1}.txt.tmp @@ -103,115 +69,6 @@ dbcheck_clean() { fi } -add_dangling_link() { - ldif=$release_dir/add-dangling-forwardlink-user.ldif - TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi - - ldif=$release_dir/add-initially-normal-link.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi - - ldif=$release_dir/delete-only-backlink.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -add_dangling_backlink() { - ldif=$release_dir/add-dangling-backlink-user.ldif - TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi - - ldif=$release_dir/add-dangling-backlink.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -add_deleted_dangling_backlink() { - ldif=$release_dir/add-deleted-backlink-user.ldif - TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi - - ldif=$release_dir/add-deleted-backlink.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -add_deleted_target_backlink() { - ldif=$release_dir/add-deleted-target-backlink-user.ldif - TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi - - ldif=$release_dir/add-deleted-target-backlink.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -add_deleted_target_link() { - ldif=$release_dir/add-dangling-deleted-link.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -add_two_more_users() { - ldif=$release_dir/add-two-more-users.ldif - TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -add_four_more_links() { - ldif=$release_dir/add-four-more-links.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -remove_one_link() { - ldif=$release_dir/remove-one-more-link.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -remove_one_user() { - ldif=$release_dir/remove-one-more-user.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -move_one_user() { - TZ=UTC $ldbrename -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb 'cn=user1,cn=users,DC=release-4-5-0-pre1,DC=samba,DC=corp' 'cn=user1x,cn=users,DC=release-4-5-0-pre1,DC=samba,DC=corp' - if [ "$?" != "0" ]; then - return 1 - fi -} - check_expected_after_links() { tmpldif=$PREFIX_ABS/$RELEASE/expected-links-after-link-dbcheck.ldif.tmp TZ=UTC $ldbsearch -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb '(|(cn=swimmers)(cn=leaders)(cn=helpers))' -s sub -b DC=release-4-5-0-pre1,DC=samba,DC=corp --show-deleted --sorted member > $tmpldif @@ -239,61 +96,6 @@ check_expected_after_objects() { fi } -dangling_one_way_dn() { - ldif=$release_dir/dangling-one-way-dn.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -deleted_one_way_dn() { - ldif=$release_dir/deleted-one-way-dn.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -dangling_one_way_link() { - ldif=$release_dir/dangling-one-way-link.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/CN%3DCONFIGURATION,DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - -add_dangling_multi_valued() { - # multi1 - All 4 backlinks - # multi2 - Missing all 4 backlinks - # multi3 - Missing 2 backlinks - # Administrator - Has 2 too many backlinks - # multi5 - Has 2 backlinks but no forward links - ldif=$release_dir/add-dangling-multilink-users.ldif - TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi - - ldif=$release_dir/add-initially-normal-multilink.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi - - ldif=$release_dir/delete-only-multi-backlink.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi - - ldif=$release_dir/add-dangling-multi-backlink.ldif - TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif - if [ "$?" != "0" ]; then - return 1 - fi -} - dbcheck_dangling_multi_valued() { $PYTHON $BINDIR/samba-tool dbcheck -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb --fix --yes -- 1.9.1 From 41201bf2358b10f217163bcd56d3f76c23335ab0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 31 Oct 2017 11:20:34 +1300 Subject: [PATCH 08/18] selftest: Additional check for a backlink pointing at a deleted object Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher (cherry picked from commit a784cc3a7f2043a5762d426e904a90e44b101ecd) --- .../release-4-5-0-pre1/add-deleted-source-backlink.ldif | 6 ++++++ testprogs/blackbox/common-links.sh | 8 ++++++++ testprogs/blackbox/dbcheck-links.sh | 1 + 3 files changed, 15 insertions(+) create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/add-deleted-source-backlink.ldif diff --git a/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-source-backlink.ldif b/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-source-backlink.ldif new file mode 100644 index 0000000..40e2f8c --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-source-backlink.ldif @@ -0,0 +1,6 @@ +dn: CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: modify +add: memberOf +memberOf: ;;CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +- +# in group udg, the link is deleted, so this is sort of a dangling backlink too \ No newline at end of file diff --git a/testprogs/blackbox/common-links.sh b/testprogs/blackbox/common-links.sh index 7c80e35..e36cb0b 100644 --- a/testprogs/blackbox/common-links.sh +++ b/testprogs/blackbox/common-links.sh @@ -96,6 +96,14 @@ add_deleted_target_backlink() { fi } +add_deleted_source_backlink() { + ldif=$release_dir/add-deleted-source-backlink.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + add_deleted_target_link() { ldif=$release_dir/add-dangling-deleted-link.ldif TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif diff --git a/testprogs/blackbox/dbcheck-links.sh b/testprogs/blackbox/dbcheck-links.sh index e1db50f..a64e8a3 100755 --- a/testprogs/blackbox/dbcheck-links.sh +++ b/testprogs/blackbox/dbcheck-links.sh @@ -150,6 +150,7 @@ if [ -d $release_dir ]; then testit "add_dangling_link" add_dangling_link testit "add_dangling_backlink" add_dangling_backlink testit "add_deleted_dangling_backlink" add_deleted_dangling_backlink + testit "add_deleted_source_backlink" add_deleted_source_backlink testit "add_deleted_target_link" add_deleted_target_link testit "add_deleted_target_backlink" add_deleted_target_backlink testit "dbcheck_dangling" dbcheck_dangling -- 1.9.1 From 7f6f14fa4caf7ca2cea8cceb31508db098f806c3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Oct 2017 16:26:16 +0200 Subject: [PATCH 09/18] s4:schema_samba4: mark DSDB_CONTROL_INVALID_NOT_IMPLEMENTED 1.3.6.1.4.1.7165.4.3.32 as allocated Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 126d28d0b58740a8abd4137562dda685a57449bb) --- source4/setup/schema_samba4.ldif | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/setup/schema_samba4.ldif b/source4/setup/schema_samba4.ldif index fcfaf98..a4a12ea 100644 --- a/source4/setup/schema_samba4.ldif +++ b/source4/setup/schema_samba4.ldif @@ -224,6 +224,7 @@ #Allocated: DSDB_CONTROL_REPLMD_VANISH_LINKS 1.3.6.1.4.1.7165.4.3.29 #Allocated: LDB_CONTROL_RECALCULATE_RDN_OID 1.3.6.1.4.1.7165.4.3.30 #Allocated: DSDB_CONTROL_FORCE_RODC_LOCAL_CHANGE 1.3.6.1.4.1.7165.4.3.31 +#Allocated: DSDB_CONTROL_INVALID_NOT_IMPLEMENTED 1.3.6.1.4.1.7165.4.3.32 # Extended 1.3.6.1.4.1.7165.4.4.x -- 1.9.1 From 06102040e53848a588b69aa9b6deec87a9460ca5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Oct 2017 16:47:36 +0200 Subject: [PATCH 10/18] s4:dsdb: allocate DSDB_CONTROL_DBCHECK_FIX_DUPLICATE_LINKS oid BUG: https://bugzilla.samba.org/show_bug.cgi?id=13095 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 1eb8d8ec5a62baf1b8e3c7cb1856787de4a3ccb2) --- source4/dsdb/samdb/samdb.h | 3 +++ source4/setup/schema_samba4.ldif | 1 + 2 files changed, 4 insertions(+) diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h index c8658dc..894df0f 100644 --- a/source4/dsdb/samdb/samdb.h +++ b/source4/dsdb/samdb/samdb.h @@ -126,6 +126,9 @@ struct dsdb_control_password_change { /* passed when dbcheck wants to modify a read only replica (very special case) */ #define DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA "1.3.6.1.4.1.7165.4.3.19.1" +/* passed by dbcheck to fix duplicate linked attributes (bug #13095) */ +#define DSDB_CONTROL_DBCHECK_FIX_DUPLICATE_LINKS "1.3.6.1.4.1.7165.4.3.19.2" + /* passed when importing plain text password on upgrades */ #define DSDB_CONTROL_PASSWORD_BYPASS_LAST_SET_OID "1.3.6.1.4.1.7165.4.3.20" diff --git a/source4/setup/schema_samba4.ldif b/source4/setup/schema_samba4.ldif index a4a12ea..5dcbe9a 100644 --- a/source4/setup/schema_samba4.ldif +++ b/source4/setup/schema_samba4.ldif @@ -213,6 +213,7 @@ #Allocated: DSDB_CONTROL_PARTIAL_REPLICA 1.3.6.1.4.1.7165.4.3.18 #Allocated: DSDB_CONTROL_DBCHECK 1.3.6.1.4.1.7165.4.3.19 #Allocated: DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA 1.3.6.1.4.1.7165.4.3.19.1 +#Allocated: DSDB_CONTROL_DBCHECK_FIX_DUPLICATE_LINKS 1.3.6.1.4.1.7165.4.3.19.2 #Allocated: DSDB_CONTROL_PASSWORD_BYPASS_LAST_SET_OID 1.3.6.1.4.1.7165.4.3.20 #Allocated: DSDB_CONTROL_SEC_DESC_PROPAGATION_OID 1.3.6.1.4.1.7165.4.3.21 #Allocated: DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID 1.3.6.1.4.1.7165.4.3.23 -- 1.9.1 From c06efbfc046820aaa1277f664e60aaf9c2549cf0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Oct 2017 16:48:44 +0200 Subject: [PATCH 11/18] dsdb:repl_meta_data: implement DSDB_CONTROL_DBCHECK_FIX_DUPLICATE_LINKS control This will be used by dbcheck to fix duplicate link values. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13095 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 9a1e23a1f67c38248e41e0d3aa2af8a682477364) --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 34 +++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 8c6040a..91914a6 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -3297,6 +3297,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) unsigned int functional_level; const struct ldb_message_element *guid_el = NULL; struct ldb_control *sd_propagation_control; + struct ldb_control *fix_links_control = NULL; struct replmd_private *replmd_private = talloc_get_type(ldb_module_get_private(module), struct replmd_private); @@ -3322,6 +3323,39 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) ldb = ldb_module_get_ctx(module); + fix_links_control = ldb_request_get_control(req, + DSDB_CONTROL_DBCHECK_FIX_DUPLICATE_LINKS); + if (fix_links_control != NULL) { + struct dsdb_schema *schema = NULL; + const struct dsdb_attribute *sa = NULL; + + if (req->op.mod.message->num_elements != 1) { + return ldb_module_operr(module); + } + + if (req->op.mod.message->elements[0].flags != LDB_FLAG_MOD_REPLACE) { + return ldb_module_operr(module); + } + + schema = dsdb_get_schema(ldb, req); + if (schema == NULL) { + return ldb_module_operr(module); + } + + sa = dsdb_attribute_by_lDAPDisplayName(schema, + req->op.mod.message->elements[0].name); + if (sa == NULL) { + return ldb_module_operr(module); + } + + if (sa->linkID == 0) { + return ldb_module_operr(module); + } + + fix_links_control->critical = false; + return ldb_next_request(module, req); + } + ldb_debug(ldb, LDB_DEBUG_TRACE, "replmd_modify\n"); guid_el = ldb_msg_find_element(req->op.mod.message, "objectGUID"); -- 1.9.1 From b20dc06ea6b447027ac37ea1c56b1a8a878130bf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Oct 2017 07:47:48 +0200 Subject: [PATCH 12/18] dsdb:extended_dn_store: implement DSDB_CONTROL_DBCHECK_FIX_DUPLICATE_LINKS control This will be used by dbcheck to fix duplicate link values. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13095 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 83aa22260bd39ad0e6aab7764f9a7fc915d02a4b) --- source4/dsdb/samdb/ldb_modules/extended_dn_store.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c index 28ad9d0..a32ab8d 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c @@ -375,6 +375,7 @@ static int extended_dn_modify(struct ldb_module *module, struct ldb_request *req unsigned int i, j; struct extended_dn_context *ac; + struct ldb_control *fix_links_control = NULL; int ret; if (ldb_dn_is_special(req->op.mod.message->dn)) { @@ -393,6 +394,12 @@ static int extended_dn_modify(struct ldb_module *module, struct ldb_request *req return ldb_next_request(module, req); } + fix_links_control = ldb_request_get_control(req, + DSDB_CONTROL_DBCHECK_FIX_DUPLICATE_LINKS); + if (fix_links_control != NULL) { + return ldb_next_request(module, req); + } + for (i=0; i < req->op.mod.message->num_elements; i++) { const struct ldb_message_element *el = &req->op.mod.message->elements[i]; const struct dsdb_attribute *schema_attr -- 1.9.1 From 5e468fe838eb3f26cb2b20b4e47a140e80f72def Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Oct 2017 16:30:28 +0200 Subject: [PATCH 13/18] dbcheck: remove indentation level Check with git show -w BUG: https://bugzilla.samba.org/show_bug.cgi?id=13095 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit eb6bd6511a98dafebaa0d3951fe78c77acf13e3a) --- python/samba/dbchecker.py | 125 +++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index 45bfdbf..3ecb17a 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -1008,75 +1008,74 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) res[0].dn) continue - else: - # check the reverse_link is correct if there should be one - match_count = 0 - if reverse_link_name in res[0]: - for v in res[0][reverse_link_name]: - v_guid = dsdb_Dn(self.samdb, v).dn.get_extended_component("GUID") - if v_guid == obj_guid: - match_count += 1 - if match_count != 1: - reverse_syntax_oid = self.samdb_schema.get_syntax_oid_from_lDAPDisplayName(reverse_link_name) - if syntax_oid == dsdb.DSDB_SYNTAX_BINARY_DN or reverse_syntax_oid == dsdb.DSDB_SYNTAX_BINARY_DN: - if not linkID & 1: - # Forward binary multi-valued linked attribute - forward_count = 0 - for w in obj[attrname]: - w_guid = dsdb_Dn(self.samdb, w).dn.get_extended_component("GUID") - if w_guid == guid: - forward_count += 1 - - if match_count == forward_count: - continue - - error_count += 1 - - # Add or remove the missing number of backlinks - diff_count = forward_count - match_count - - # Loop until the difference between the forward and - # the backward links is resolved. - while diff_count != 0: - if diff_count > 0: - # self.err_missing_backlink(obj, attrname, - # obj.dn.extended_str(), - # reverse_link_name, - # dsdb_dn.dn) - # diff_count -= 1 - # TODO no method to fix these right now - self.report("ERROR: Can't fix missing " - "multi-valued backlinks on %s" % str(dsdb_dn.dn)) - break - else: - self.err_orphaned_backlink(res[0], reverse_link_name, - obj.dn.extended_str(), attrname, - dsdb_dn.dn) - diff_count += 1 + # check the reverse_link is correct if there should be one + match_count = 0 + if reverse_link_name in res[0]: + for v in res[0][reverse_link_name]: + v_guid = dsdb_Dn(self.samdb, v).dn.get_extended_component("GUID") + if v_guid == obj_guid: + match_count += 1 + if match_count != 1: + reverse_syntax_oid = self.samdb_schema.get_syntax_oid_from_lDAPDisplayName(reverse_link_name) + if syntax_oid == dsdb.DSDB_SYNTAX_BINARY_DN or reverse_syntax_oid == dsdb.DSDB_SYNTAX_BINARY_DN: + if not linkID & 1: + # Forward binary multi-valued linked attribute + forward_count = 0 + for w in obj[attrname]: + w_guid = dsdb_Dn(self.samdb, w).dn.get_extended_component("GUID") + if w_guid == guid: + forward_count += 1 + + if match_count == forward_count: + continue - else: - # If there's a backward link on binary multi-valued linked attribute, - # let the check on the forward link remedy the value. - # UNLESS, there is no forward link detected. - if match_count == 0: - self.err_orphaned_backlink(obj, attrname, - val, reverse_link_name, - dsdb_dn.dn) + error_count += 1 - continue + # Add or remove the missing number of backlinks + diff_count = forward_count - match_count + + # Loop until the difference between the forward and + # the backward links is resolved. + while diff_count != 0: + if diff_count > 0: + # self.err_missing_backlink(obj, attrname, + # obj.dn.extended_str(), + # reverse_link_name, + # dsdb_dn.dn) + # diff_count -= 1 + # TODO no method to fix these right now + self.report("ERROR: Can't fix missing " + "multi-valued backlinks on %s" % str(dsdb_dn.dn)) + break + else: + self.err_orphaned_backlink(res[0], reverse_link_name, + obj.dn.extended_str(), attrname, + dsdb_dn.dn) + diff_count += 1 - error_count += 1 - if linkID & 1: - # Backlink exists, but forward link does not - # Delete the hanging backlink - self.err_orphaned_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn) else: - # Forward link exists, but backlink does not - # Add the missing backlink (if the target object is not Deleted Objects?) - if not target_is_deleted: - self.err_missing_backlink(obj, attrname, obj.dn.extended_str(), reverse_link_name, dsdb_dn.dn) + # If there's a backward link on binary multi-valued linked attribute, + # let the check on the forward link remedy the value. + # UNLESS, there is no forward link detected. + if match_count == 0: + self.err_orphaned_backlink(obj, attrname, + val, reverse_link_name, + dsdb_dn.dn) + continue + error_count += 1 + if linkID & 1: + # Backlink exists, but forward link does not + # Delete the hanging backlink + self.err_orphaned_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn) + else: + # Forward link exists, but backlink does not + # Add the missing backlink (if the target object is not Deleted Objects?) + if not target_is_deleted: + self.err_missing_backlink(obj, attrname, obj.dn.extended_str(), reverse_link_name, dsdb_dn.dn) + continue + -- 1.9.1 From 5d74b71e5843134be4db485a6b523c7ab53bae18 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 27 Oct 2017 10:21:26 +0200 Subject: [PATCH 14/18] dbcheck: only calculate linked attribute helper variables once in check_dn() BUG: https://bugzilla.samba.org/show_bug.cgi?id=13095 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 9a631560c9358e4f28b96fecf23a545e1d04098c) --- python/samba/dbchecker.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index 3ecb17a..dafa844 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -876,6 +876,12 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) error_count = 0 obj_guid = obj['objectGUID'][0] + linkID, reverse_link_name = self.get_attr_linkID_and_reverse_name(attrname) + if reverse_link_name is not None: + reverse_syntax_oid = self.samdb_schema.get_syntax_oid_from_lDAPDisplayName(reverse_link_name) + else: + reverse_syntax_oid = None + for val in obj[attrname]: dsdb_dn = dsdb_Dn(self.samdb, val, syntax_oid) @@ -896,7 +902,6 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) else: fixing_msDS_HasInstantiatedNCs = False - linkID, reverse_link_name = self.get_attr_linkID_and_reverse_name(attrname) if reverse_link_name is not None: attrs.append(reverse_link_name) @@ -1016,7 +1021,6 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) if v_guid == obj_guid: match_count += 1 if match_count != 1: - reverse_syntax_oid = self.samdb_schema.get_syntax_oid_from_lDAPDisplayName(reverse_link_name) if syntax_oid == dsdb.DSDB_SYNTAX_BINARY_DN or reverse_syntax_oid == dsdb.DSDB_SYNTAX_BINARY_DN: if not linkID & 1: # Forward binary multi-valued linked attribute -- 1.9.1 From fd917c5068f1d60945419977188321cfa9a14eed Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 27 Oct 2017 10:21:26 +0200 Subject: [PATCH 15/18] dbcheck: detect and fix duplicate links Check with git show -w BUG: https://bugzilla.samba.org/show_bug.cgi?id=13095 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 239fbeb163c24b0f08e1bd9d8f7a9f73443d4b90) --- python/samba/dbchecker.py | 193 ++++++++++++++++----- .../expected-dbcheck-link-output.txt | 9 +- 2 files changed, 152 insertions(+), 50 deletions(-) diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index dafa844..1933740 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -65,6 +65,7 @@ class dbcheck(object): self.fix_undead_linked_attributes = False self.fix_all_missing_backlinks = False self.fix_all_orphaned_backlinks = False + self.fix_all_duplicate_links = False self.fix_rmd_flags = False self.fix_ntsecuritydescriptor = False self.fix_ntsecuritydescriptor_owner_group = False @@ -720,6 +721,19 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) "Failed to fix orphaned backlink %s" % attrname): self.report("Fixed orphaned backlink %s" % (attrname)) + def err_duplicate_links(self, obj, attrname, vals): + '''handle a duplicate links value''' + + if not self.confirm_all("Remove duplicate links in attribute '%s'" % attrname, 'fix_all_duplicate_links'): + self.report("Not removing duplicate links in attribute '%s'" % attrname) + return + m = ldb.Message() + m.dn = obj.dn + m['value'] = ldb.MessageElement(vals, ldb.FLAG_MOD_REPLACE, attrname) + if self.do_modify(m, ["local_oid:1.3.6.1.4.1.7165.4.3.19.2:1"], + "Failed to fix duplicate links in attribute '%s'" % attrname): + self.report("Fixed duplicate links in attribute '%s'" % (attrname)) + def err_no_fsmoRoleOwner(self, obj): '''handle a missing fSMORoleOwner''' self.report("ERROR: fSMORoleOwner not found for role %s" % (obj.dn)) @@ -882,6 +896,75 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) else: reverse_syntax_oid = None + duplicate_dict = dict() + duplicate_list = list() + unique_dict = dict() + unique_list = list() + for val in obj[attrname]: + if linkID & 1: + # + # Only cleanup forward links here, + # back links are handled below. + break + + dsdb_dn = dsdb_Dn(self.samdb, val, syntax_oid) + + # all DNs should have a GUID component + guid = dsdb_dn.dn.get_extended_component("GUID") + if guid is None: + continue + guidstr = str(misc.GUID(guid)) + keystr = guidstr + dsdb_dn.prefix + if keystr not in unique_dict: + unique_dict[keystr] = dsdb_dn + unique_list.append(keystr) + continue + error_count += 1 + if keystr not in duplicate_dict: + duplicate_dict[keystr] = dict() + duplicate_dict[keystr]["keep"] = None + duplicate_dict[keystr]["delete"] = list() + duplicate_list.append(keystr) + + # Now check for the highest RMD_VERSION + v1 = int(unique_dict[keystr].dn.get_extended_component("RMD_VERSION")) + v2 = int(dsdb_dn.dn.get_extended_component("RMD_VERSION")) + if v1 > v2: + duplicate_dict[keystr]["keep"] = unique_dict[keystr] + duplicate_dict[keystr]["delete"].append(dsdb_dn) + continue + if v1 < v2: + duplicate_dict[keystr]["keep"] = dsdb_dn + duplicate_dict[keystr]["delete"].append(unique_dict[keystr]) + unique_dict[keystr] = dsdb_dn + continue + # Fallback to the highest RMD_LOCAL_USN + u1 = int(unique_dict[keystr].dn.get_extended_component("RMD_LOCAL_USN")) + u2 = int(dsdb_dn.dn.get_extended_component("RMD_LOCAL_USN")) + if u1 >= u2: + duplicate_dict[keystr]["keep"] = unique_dict[keystr] + duplicate_dict[keystr]["delete"].append(dsdb_dn) + continue + duplicate_dict[keystr]["keep"] = dsdb_dn + duplicate_dict[keystr]["delete"].append(unique_dict[keystr]) + unique_dict[keystr] = dsdb_dn + + if len(duplicate_list) != 0: + self.report("ERROR: Duplicate link values for attribute '%s' in '%s'" % (attrname, obj.dn)) + for keystr in duplicate_list: + d = duplicate_dict[keystr] + for dd in d["delete"]: + self.report("Duplicate link '%s'" % dd) + self.report("Correct link '%s'" % d["keep"]) + + vals = [] + for keystr in unique_list: + dsdb_dn = unique_dict[keystr] + vals.append(str(dsdb_dn)) + self.err_duplicate_links(obj, attrname, vals) + # We should continue with the fixed values + obj[attrname] = ldb.MessageElement(vals, ldb.FLAG_MOD_REPLACE, attrname) + for val in obj[attrname]: dsdb_dn = dsdb_Dn(self.samdb, val, syntax_oid) @@ -975,16 +1058,15 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) # components on deleted links, as these are allowed to # go stale (we just need the GUID, not the name) rmd_blob = dsdb_dn.dn.get_extended_component("RMD_FLAGS") + rmd_flags = 0 if rmd_blob is not None: rmd_flags = int(rmd_blob) - if rmd_flags & 1: - continue # assert the DN matches in string form, where a reverse # link exists, otherwise (below) offer to fix it as a non-error. # The string form is essentially only kept for forensics, # as we always re-resolve by GUID in normal operations. - if reverse_link_name is not None: + if not rmd_flags & 1 and reverse_link_name is not None: if str(res[0].dn) != str(dsdb_dn.dn): error_count += 1 self.err_dn_component_target_mismatch(obj.dn, attrname, val, dsdb_dn, @@ -1017,9 +1099,17 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) match_count = 0 if reverse_link_name in res[0]: for v in res[0][reverse_link_name]: - v_guid = dsdb_Dn(self.samdb, v).dn.get_extended_component("GUID") + v_dn = dsdb_Dn(self.samdb, v) + v_guid = v_dn.dn.get_extended_component("GUID") + v_blob = v_dn.dn.get_extended_component("RMD_FLAGS") + v_rmd_flags = 0 + if v_blob is not None: + v_rmd_flags = int(v_blob) + if v_rmd_flags & 1: + continue if v_guid == obj_guid: match_count += 1 + if match_count != 1: if syntax_oid == dsdb.DSDB_SYNTAX_BINARY_DN or reverse_syntax_oid == dsdb.DSDB_SYNTAX_BINARY_DN: if not linkID & 1: @@ -1032,55 +1122,66 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) if match_count == forward_count: continue + expected_count = 0 + for v in obj[attrname]: + v_dn = dsdb_Dn(self.samdb, v) + v_guid = v_dn.dn.get_extended_component("GUID") + v_blob = v_dn.dn.get_extended_component("RMD_FLAGS") + v_rmd_flags = 0 + if v_blob is not None: + v_rmd_flags = int(v_blob) + if v_rmd_flags & 1: + continue + if v_guid == guid: + expected_count += 1 - error_count += 1 + if match_count == expected_count: + continue - # Add or remove the missing number of backlinks - diff_count = forward_count - match_count - - # Loop until the difference between the forward and - # the backward links is resolved. - while diff_count != 0: - if diff_count > 0: - # self.err_missing_backlink(obj, attrname, - # obj.dn.extended_str(), - # reverse_link_name, - # dsdb_dn.dn) - # diff_count -= 1 - # TODO no method to fix these right now - self.report("ERROR: Can't fix missing " - "multi-valued backlinks on %s" % str(dsdb_dn.dn)) - break - else: - self.err_orphaned_backlink(res[0], reverse_link_name, - obj.dn.extended_str(), attrname, - dsdb_dn.dn) - diff_count += 1 - - else: - # If there's a backward link on binary multi-valued linked attribute, - # let the check on the forward link remedy the value. - # UNLESS, there is no forward link detected. - if match_count == 0: - self.err_orphaned_backlink(obj, attrname, - val, reverse_link_name, - dsdb_dn.dn) + diff_count = expected_count - match_count + if linkID & 1: + # If there's a backward link on binary multi-valued linked attribute, + # let the check on the forward link remedy the value. + # UNLESS, there is no forward link detected. + if match_count == 0: + error_count += 1 + self.err_orphaned_backlink(obj, attrname, + val, reverse_link_name, + dsdb_dn.dn) continue - - error_count += 1 - if linkID & 1: - # Backlink exists, but forward link does not - # Delete the hanging backlink - self.err_orphaned_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn) - else: - # Forward link exists, but backlink does not - # Add the missing backlink (if the target object is not Deleted Objects?) - if not target_is_deleted: - self.err_missing_backlink(obj, attrname, obj.dn.extended_str(), reverse_link_name, dsdb_dn.dn) + # Only warn here and let the forward link logic fix it. + self.report("WARNING: Link (back) mismatch for '%s' (%d) on '%s' to '%s' (%d) on '%s'" % ( + attrname, expected_count, str(obj.dn), + reverse_link_name, match_count, str(dsdb_dn.dn))) continue + assert not target_is_deleted + self.report("ERROR: Link (forward) mismatch for '%s' (%d) on '%s' to '%s' (%d) on '%s'" % ( + attrname, expected_count, str(obj.dn), + reverse_link_name, match_count, str(dsdb_dn.dn))) + + # Loop until the difference between the forward and + # the backward links is resolved. + while diff_count != 0: + error_count += 1 + if diff_count > 0: + if match_count > 0 or diff_count > 1: + # TODO no method to fix these right now + self.report("ERROR: Can't fix missing " + "multi-valued backlinks on %s" % str(dsdb_dn.dn)) + break + self.err_missing_backlink(obj, attrname, + obj.dn.extended_str(), + reverse_link_name, + dsdb_dn.dn) + diff_count -= 1 + else: + self.err_orphaned_backlink(res[0], reverse_link_name, + obj.dn.extended_str(), attrname, + obj.dn) + diff_count += 1 return error_count diff --git a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt index 44e10d0..6f0d2fc 100644 --- a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt +++ b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt @@ -1,4 +1,5 @@ Checking 225 objects +ERROR: Link (forward) mismatch for 'member' (1) on 'CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' to 'memberOf' (0) on 'CN=dangling-forward,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' ERROR: missing backlink attribute 'memberOf' in CN=dangling-forward,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp for link member in CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp Fix missing backlink memberOf [YES] Fixed missing backlink memberOf @@ -27,6 +28,10 @@ Fixed undead forward link member ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=usg\0ADEL:d012e8f5-a4bd-40ea-a2a1-68ff2508847d,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member +ERROR: target DN is deleted for memberOf in object CN=deleted-target-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp - ;;CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +Target GUID points at deleted DN 'CN=gdg\\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp' +Remove DN link? [YES] +Removed deleted DN on attribute memberOf ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=ddg\0ADEL:fb8c2fe3-5448-43de-99f9-e1d3b9357cfc,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member @@ -37,10 +42,6 @@ WARNING: target DN is deleted for member in object CN=swimmers,CN=Users,DC=relea Target GUID points at deleted DN 'CN=fred\\0ADEL:2301a64c-5b42-4ca8-851e-12d4a711cfb4,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp' Remove stale DN link? [YES] Removed deleted DN on attribute member -ERROR: target DN is deleted for memberOf in object CN=deleted-target-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp - ;;CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp -Target GUID points at deleted DN 'CN=gdg\\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp' -Remove DN link? [YES] -Removed deleted DN on attribute memberOf ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gsg\0ADEL:91aa85cc-fc19-4b8c-9fc7-aaba425439c7,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -- 1.9.1 From f1169877da0b8c8f275af89fb1a77ea29f1f08bd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Oct 2017 14:42:23 +0200 Subject: [PATCH 16/18] selftest: add dbcheck tests for duplicate links BUG: https://bugzilla.samba.org/show_bug.cgi?id=13095 Pair-Programmed-With: Andrew Bartlett Signed-off-by: Stefan Metzmacher Signed-off-by: Andrew Bartlett (cherry picked from commit 70bf809e0cdf84029022ca95fb83d17a0d6e36c0) --- ...pected-dbcheck-link-output_duplicate_member.txt | 8 +++++ .../expected-duplicates-after-link-dbcheck.ldif | 28 ++++++++++++++++ testprogs/blackbox/dbcheck-links.sh | 39 ++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output_duplicate_member.txt create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/expected-duplicates-after-link-dbcheck.ldif diff --git a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output_duplicate_member.txt b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output_duplicate_member.txt new file mode 100644 index 0000000..baa11ca --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output_duplicate_member.txt @@ -0,0 +1,8 @@ +Checking 225 objects +WARNING: Link (back) mismatch for 'memberOf' (1) on 'CN=Administrator,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' to 'member' (2) on 'CN=Enterprise Admins,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' +ERROR: Duplicate link values for attribute 'member' in 'CN=Enterprise Admins,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' +Duplicate link ';;;;;;;;;CN=Administrator,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' +Correct link ';;;;;;;;;CN=Administrator,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' +Remove duplicate links in attribute 'member' [YES] +Fixed duplicate links in attribute 'member' +Checked 225 objects (1 errors) diff --git a/source4/selftest/provisions/release-4-5-0-pre1/expected-duplicates-after-link-dbcheck.ldif b/source4/selftest/provisions/release-4-5-0-pre1/expected-duplicates-after-link-dbcheck.ldif new file mode 100644 index 0000000..e70426c --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/expected-duplicates-after-link-dbcheck.ldif @@ -0,0 +1,28 @@ +# record 1 +dn: CN=Administrator,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +memberOf: CN=Administrators,CN=Builtin,DC=release-4-5-0-pre1,DC=samba,DC=corp +memberOf: CN=Group Policy Creator Owners,CN=Users,DC=release-4-5-0-pre1,DC=sam + ba,DC=corp +memberOf: CN=Enterprise Admins,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +memberOf: CN=Schema Admins,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +memberOf: CN=Domain Admins,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp + +# record 2 +dn: CN=Enterprise Admins,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +member: CN=Administrator,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +memberOf: CN=Administrators,CN=Builtin,DC=release-4-5-0-pre1,DC=samba,DC=corp +memberOf: CN=Denied RODC Password Replication Group,CN=Users,DC=release-4-5-0- + pre1,DC=samba,DC=corp + +# Referral +ref: ldap:///CN=Configuration,DC=release-4-5-0-pre1,DC=samba,DC=corp + +# Referral +ref: ldap:///DC=DomainDnsZones,DC=release-4-5-0-pre1,DC=samba,DC=corp + +# Referral +ref: ldap:///DC=ForestDnsZones,DC=release-4-5-0-pre1,DC=samba,DC=corp + +# returned 5 records +# 2 entries +# 3 referrals diff --git a/testprogs/blackbox/dbcheck-links.sh b/testprogs/blackbox/dbcheck-links.sh index a64e8a3..074b601 100755 --- a/testprogs/blackbox/dbcheck-links.sh +++ b/testprogs/blackbox/dbcheck-links.sh @@ -96,6 +96,41 @@ check_expected_after_objects() { fi } +duplicate_member() { + # We use an exisiting group so we have a stable GUID in the + # dbcheck output + LDIF1=$(TZ=UTC $ldbsearch -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb -b 'CN=Enterprise Admins,CN=users,DC=release-4-5-0-pre1,DC=samba,DC=corp' -s base --reveal --extended-dn member) + DN=$(echo "${LDIF1}" | grep '^dn: ') + MSG=$(echo "${LDIF1}" | grep -v '^dn: ' | grep -v '^#' | grep -v '^$') + ldif=$PREFIX_ABS/${RELEASE}/duplicate-member-multi.ldif + { + echo "${DN}" + echo "changetype: modify" + echo "replace: member" + echo "${MSG}" + echo "${MSG}" | sed -e 's!RMD_LOCAL_USN=[1-9][0-9]*!RMD_LOCAL_USN=0!' + } > $ldif + + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +dbcheck_duplicate_member() { + dbcheck "_duplicate_member" "1" "" + return $? +} + +check_expected_after_duplicate_links() { + tmpldif=$PREFIX_ABS/$RELEASE/expected-duplicates-after-link-dbcheck.ldif.tmp + TZ=UTC $ldbsearch -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb '(|(cn=administrator)(cn=enterprise admins))' -s sub -b DC=release-4-5-0-pre1,DC=samba,DC=corp --show-deleted --sorted memberOf member > $tmpldif + diff $tmpldif $release_dir/expected-duplicates-after-link-dbcheck.ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + dbcheck_dangling_multi_valued() { $PYTHON $BINDIR/samba-tool dbcheck -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb --fix --yes @@ -158,6 +193,10 @@ if [ -d $release_dir ]; then testit "check_expected_after_deleted_links" check_expected_after_deleted_links testit "check_expected_after_links" check_expected_after_links testit "check_expected_after_objects" check_expected_after_objects + testit "duplicate_member" duplicate_member + testit "dbcheck_duplicate_member" dbcheck_duplicate_member + testit "check_expected_after_duplicate_links" check_expected_after_duplicate_links + testit "duplicate_clean" dbcheck_clean testit "dangling_one_way_link" dangling_one_way_link testit "dbcheck_one_way" dbcheck_one_way testit "dbcheck_clean2" dbcheck_clean -- 1.9.1 From eb323bad8ceff93f4952b42dfbdcc7c5f13cfde3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 1 Nov 2017 09:02:01 +1300 Subject: [PATCH 17/18] selftest: Add more corruption cases for runtime and dbcheck These tests now confirm we can handle these issues at runtime as well as at dbcheck Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher (cherry picked from commit 4815efc0e3f89079e7c9b868b7514ea7c49a807c) --- .../knownfail.d/delete_member_of_deleted_group | 1 + selftest/knownfail.d/runtime-links | 2 + selftest/tests.py | 5 ++ .../add-deleted-source-backlink.ldif | 6 -- .../expected-dbcheck-link-output.txt | 16 ++--- .../revive-backlink-on-deleted-group.ldif | 5 ++ .../revive-links-on-deleted-group.ldif | 20 ++++++ testprogs/blackbox/common-links.sh | 12 +++- testprogs/blackbox/dbcheck-links.sh | 3 +- testprogs/blackbox/runtime-links.sh | 74 ++++++++++++++++++++++ 10 files changed, 127 insertions(+), 17 deletions(-) create mode 100644 selftest/knownfail.d/delete_member_of_deleted_group create mode 100644 selftest/knownfail.d/runtime-links delete mode 100644 source4/selftest/provisions/release-4-5-0-pre1/add-deleted-source-backlink.ldif create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/revive-backlink-on-deleted-group.ldif create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/revive-links-on-deleted-group.ldif create mode 100755 testprogs/blackbox/runtime-links.sh diff --git a/selftest/knownfail.d/delete_member_of_deleted_group b/selftest/knownfail.d/delete_member_of_deleted_group new file mode 100644 index 0000000..f399d33 --- /dev/null +++ b/selftest/knownfail.d/delete_member_of_deleted_group @@ -0,0 +1 @@ +^samba4\.blackbox\.runtime-links\.release-4-5-0-pre1\.delete_member_of_deleted_group \ No newline at end of file diff --git a/selftest/knownfail.d/runtime-links b/selftest/knownfail.d/runtime-links new file mode 100644 index 0000000..70de8be --- /dev/null +++ b/selftest/knownfail.d/runtime-links @@ -0,0 +1,2 @@ +^samba4\.blackbox\.runtime-links\.release-4-5-0-pre1\.delete_backlink_memberof_deleted_group +^samba4\.blackbox\.runtime-links\.release-4-5-0-pre1\.delete_dangling_backlink_memberof_group \ No newline at end of file diff --git a/selftest/tests.py b/selftest/tests.py index 175b56c..a94fc8c 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -123,6 +123,11 @@ plantestsuite( ["PYTHON=%s" % python, os.path.join(bbdir, "dbcheck-links.sh"), '$PREFIX_ABS/provision', 'release-4-5-0-pre1', configuration]) +plantestsuite( + "samba4.blackbox.runtime-links.release-4-5-0-pre1", "none", + ["PYTHON=%s" % python, + os.path.join(bbdir, "runtime-links.sh"), + '$PREFIX_ABS/provision', 'release-4-5-0-pre1', configuration]) planpythontestsuite("none", "samba.tests.upgradeprovision") planpythontestsuite("none", "samba.tests.xattr") planpythontestsuite("none", "samba.tests.ntacls") diff --git a/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-source-backlink.ldif b/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-source-backlink.ldif deleted file mode 100644 index 40e2f8c..0000000 --- a/source4/selftest/provisions/release-4-5-0-pre1/add-deleted-source-backlink.ldif +++ /dev/null @@ -1,6 +0,0 @@ -dn: CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp -changetype: modify -add: memberOf -memberOf: ;;CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp -- -# in group udg, the link is deleted, so this is sort of a dangling backlink too \ No newline at end of file diff --git a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt index 6f0d2fc..5a083f7 100644 --- a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt +++ b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output.txt @@ -7,6 +7,9 @@ ERROR: target DN is deleted for member in object CN=Allowed RODC Password Replic Target GUID points at deleted DN 'CN=fred\\0ADEL:2301a64c-5b42-4ca8-851e-12d4a711cfb4,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp' Remove DN link? [YES] Removed deleted DN on attribute member +ERROR: orphaned backlink attribute 'memberOf' in CN=dangling-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp for link member in CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +Remove orphaned backlink memberOf [YES] +Fixed orphaned backlink memberOf ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=dsg\0ADEL:6d66d0ef-cad7-4e5d-b1b6-4a233a21c269,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member @@ -19,7 +22,7 @@ Fixed undead forward link memberOf ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=usg\0ADEL:d012e8f5-a4bd-40ea-a2a1-68ff2508847d,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp @@ -28,10 +31,6 @@ Fixed undead forward link member ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=usg\0ADEL:d012e8f5-a4bd-40ea-a2a1-68ff2508847d,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: target DN is deleted for memberOf in object CN=deleted-target-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp - ;;CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp -Target GUID points at deleted DN 'CN=gdg\\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp' -Remove DN link? [YES] -Removed deleted DN on attribute memberOf ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=ddg\0ADEL:fb8c2fe3-5448-43de-99f9-e1d3b9357cfc,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member @@ -48,9 +47,10 @@ Fixed undead forward link member ERROR: linked attribute 'member' to ';;;;;;;;;CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gsg\0ADEL:91aa85cc-fc19-4b8c-9fc7-aaba425439c7,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member -ERROR: orphaned backlink attribute 'memberOf' in CN=dangling-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp for link member in CN=Allowed RODC Password Replication Group,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp -Remove orphaned backlink memberOf [YES] -Fixed orphaned backlink memberOf +ERROR: target DN is deleted for memberOf in object CN=deleted-target-back,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp - ;;CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +Target GUID points at deleted DN 'CN=gdg\\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp' +Remove DN link? [YES] +Removed deleted DN on attribute memberOf ERROR: linked attribute 'member' to ';;;;;;;;;CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp' is present on deleted object CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp Remove linked attribute member [YES] Fixed undead forward link member diff --git a/source4/selftest/provisions/release-4-5-0-pre1/revive-backlink-on-deleted-group.ldif b/source4/selftest/provisions/release-4-5-0-pre1/revive-backlink-on-deleted-group.ldif new file mode 100644 index 0000000..8bfcbb7 --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/revive-backlink-on-deleted-group.ldif @@ -0,0 +1,5 @@ +dn: CN=User UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: modify +add: memberOf +memberOf: ;;CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +- diff --git a/source4/selftest/provisions/release-4-5-0-pre1/revive-links-on-deleted-group.ldif b/source4/selftest/provisions/release-4-5-0-pre1/revive-links-on-deleted-group.ldif new file mode 100644 index 0000000..a4301a0 --- /dev/null +++ b/source4/selftest/provisions/release-4-5-0-pre1/revive-links-on-deleted-group.ldif @@ -0,0 +1,20 @@ +dn: CN=User1 UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: modify +add: memberOf +memberOf: ;;CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +- + +dn: CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp +changetype: modify +delete: member +member: ;;;;;;;;;CN=User1 + UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp +add: member +member: ;;;;;;;;;CN=User1 + UT. Tester,CN=Users,DC=release-4-5-0-pre1,DC=samba,DC=corp \ No newline at end of file diff --git a/testprogs/blackbox/common-links.sh b/testprogs/blackbox/common-links.sh index e36cb0b..ee7310b 100644 --- a/testprogs/blackbox/common-links.sh +++ b/testprogs/blackbox/common-links.sh @@ -96,8 +96,16 @@ add_deleted_target_backlink() { fi } -add_deleted_source_backlink() { - ldif=$release_dir/add-deleted-source-backlink.ldif +revive_links_on_deleted_group() { + ldif=$release_dir/revive-links-on-deleted-group.ldif + TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif + if [ "$?" != "0" ]; then + return 1 + fi +} + +revive_backlink_on_deleted_group() { + ldif=$release_dir/revive-backlink-on-deleted-group.ldif TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif if [ "$?" != "0" ]; then return 1 diff --git a/testprogs/blackbox/dbcheck-links.sh b/testprogs/blackbox/dbcheck-links.sh index 074b601..0aeada0 100755 --- a/testprogs/blackbox/dbcheck-links.sh +++ b/testprogs/blackbox/dbcheck-links.sh @@ -185,7 +185,8 @@ if [ -d $release_dir ]; then testit "add_dangling_link" add_dangling_link testit "add_dangling_backlink" add_dangling_backlink testit "add_deleted_dangling_backlink" add_deleted_dangling_backlink - testit "add_deleted_source_backlink" add_deleted_source_backlink + testit "revive_links_on_deleted_group" revive_links_on_deleted_group + testit "revive_backlink_on_deleted_group" revive_backlink_on_deleted_group testit "add_deleted_target_link" add_deleted_target_link testit "add_deleted_target_backlink" add_deleted_target_backlink testit "dbcheck_dangling" dbcheck_dangling diff --git a/testprogs/blackbox/runtime-links.sh b/testprogs/blackbox/runtime-links.sh new file mode 100755 index 0000000..344b822 --- /dev/null +++ b/testprogs/blackbox/runtime-links.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +if [ $# -lt 1 ]; then +cat < Date: Wed, 1 Nov 2017 08:22:22 +1300 Subject: [PATCH 18/18] repl_meta_data: Allow delete of an object with dangling backlinks This should not happen, but stopping all replication because of it is a pain. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13095 Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Fri Nov 24 19:53:50 CET 2017 on sn-devel-144 (cherry picked from commit 6cf7abbcfdad84fee57852862ebe44aa6115ca25) --- selftest/knownfail.d/runtime-links | 2 -- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 44 ++++++++++++++++++++----- 2 files changed, 36 insertions(+), 10 deletions(-) delete mode 100644 selftest/knownfail.d/runtime-links diff --git a/selftest/knownfail.d/runtime-links b/selftest/knownfail.d/runtime-links deleted file mode 100644 index 70de8be..0000000 --- a/selftest/knownfail.d/runtime-links +++ /dev/null @@ -1,2 +0,0 @@ -^samba4\.blackbox\.runtime-links\.release-4-5-0-pre1\.delete_backlink_memberof_deleted_group -^samba4\.blackbox\.runtime-links\.release-4-5-0-pre1\.delete_dangling_backlink_memberof_group \ No newline at end of file diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 91914a6..2abbbfd 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -3166,9 +3166,22 @@ static int replmd_modify_handle_linked_attribs(struct ldb_module *module, continue; } if ((schema_attr->linkID & 1) == 1) { - if (parent && ldb_request_get_control(parent, DSDB_CONTROL_DBCHECK)) { - continue; + if (parent) { + struct ldb_control *ctrl; + + ctrl = ldb_request_get_control(parent, + DSDB_CONTROL_REPLMD_VANISH_LINKS); + if (ctrl != NULL) { + ctrl->critical = false; + continue; + } + ctrl = ldb_request_get_control(parent, + DSDB_CONTROL_DBCHECK); + if (ctrl != NULL) { + continue; + } } + /* Odd is for the target. Illegal to modify */ ldb_asprintf_errstring(ldb, "attribute %s must not be modified directly, it is a linked attribute", el->name); @@ -4269,6 +4282,7 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request /* don't remove the rDN */ continue; } + if (sa->linkID & 1) { /* we have a backlink in this object @@ -4282,7 +4296,16 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request replmd_private, old_dn, &guid, el, sa, req); - if (ret != LDB_SUCCESS) { + if (ret == LDB_SUCCESS) { + /* + * now we continue, which means we + * won't remove this backlink + * directly + */ + continue; + } + + if (ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { const char *old_dn_str = ldb_dn_get_linearized(old_dn); ldb_asprintf_errstring(ldb, @@ -4295,11 +4318,16 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request talloc_free(tmp_ctx); return LDB_ERR_OPERATIONS_ERROR; } - /* now we continue, which means we - won't remove this backlink - directly - */ - continue; + + /* + * Otherwise vanish the link, we are + * out of sync and the controlling + * object does not have the source + * link any more + */ + + dsdb_flags |= DSDB_REPLMD_VANISH_LINKS; + } else if (sa->linkID == 0) { if (ldb_attr_in_list(preserved_attrs, el->name)) { continue; -- 1.9.1