[SCM] Samba Shared Repository - branch master updated

Garming Sam garming at samba.org
Fri Jul 15 11:41:04 UTC 2016


The branch, master has been updated
       via  9d1883a renamedc: Make a more targeted dbcheck
       via  88eeb3e flapping: Remove dbcheck from flapping
       via  08d602b dbcheck.sh: Remove all the plausible stale links
       via  52ac6d1 dbcheck: Split out valid stale DN links and invalid ones
       via  93be59e dbcheck.sh: Fix the arguments supplied as $@
       via  8859103 tests/dbcheck: One way links are expected to be stale
       via  5361fc6 dbcheck: change argument to specify a partial --yes
       via  58acf51 dbcheck linked attribute tests: save environment with bad links
       via  f2b2eff blackbox/dbcheck-oldrelease: more accurate temp filename
       via  d8e7ffd s4/selftest/provisions/dump.sh: dump to target dir if supplied
       via  0b14050 dbcheck: check for linked atributes that should not exist
       via  8edb8a7 flapping: Add dbcheck to flapping
       via  ca839cf dbcheck: cache linkIDs and reverse attribute names
       via  31ffe97 extended_dn_out: Force showing of one-way links if they exist
       via  00e828a link_attrs: Add tests for one way links (and pseudo one-way)
       via  9d8e766 drs tests: querying linked attribute over DRS
       via  4cb565b dsdb tests: add linked attribute tests
       via  5ce969d dsdb: add vanish links control
       via  b7b229a repl_meta_data: free context on error in replmd_modify_la_delete()
       via  5d20159 replmd_modify_delete: check talloc_new()
       via  ebed182 s4/dsdb/repl_meta_data: use local bool version of flag
       via  4d7c782 match_rules: Make cleanup faster and more efficient
       via  3f04354 match_rules: Fix a duplicated check
       via  2df3fea dbcheck: Script swallows input when given a carriage return
      from  a6ee401 build: avoid -Wtautological-compare errors from gcc6+ by disabling it globally

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 9d1883ae8bc7847e3e36742355510f4fef3aef0b
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Tue Jul 12 12:44:10 2016 +1200

    renamedc: Make a more targeted dbcheck
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Garming Sam <garming at samba.org>
    Autobuild-Date(master): Fri Jul 15 13:40:40 CEST 2016 on sn-devel-144

commit 88eeb3ed39609a3f0c578cb4ab7ef4abd63b6f57
Author: Garming Sam <garming at samba.org>
Date:   Thu Jul 14 13:54:59 2016 +0200

    flapping: Remove dbcheck from flapping
    
    This reverts commit 019bdcd0bbac1e10be75ba37a22d4255bb31ebd6.
    
    The dbcheck should no longer be flapping now that the stale links are
    cleaned up by an earlier check.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 08d602b2ceeed46d850129ef6ff8442ee9c3313a
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 14 10:36:38 2016 +1200

    dbcheck.sh: Remove all the plausible stale links
    
    This ensures the subsequent dbcheck doesn't fail. The reason these stale
    links occur is because they are effectively one-way links at this point
    we have no efficient method of checking the opposite end of a one-way
    link (without doing a full traversal).
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 52ac6d1f95822aacd03fde54c4e6aba5854b6f4b
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 14 10:31:50 2016 +1200

    dbcheck: Split out valid stale DN links and invalid ones
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 93be59ee0ab5cddaad7b5d1e6d6d593acc47597c
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Jul 13 13:30:35 2016 +1200

    dbcheck.sh: Fix the arguments supplied as $@
    
    Signed-off-by: Garming Sam <garming at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 88591030ce52c106d6540c65a128f316971e2d37
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Tue Jul 12 09:54:14 2016 +1200

    tests/dbcheck: One way links are expected to be stale
    
    Run a targeted dbcheck to fix only the one way links.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5361fc68436b4dcd8d1b7174daee27c78d3c7ade
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Mon Jul 11 15:14:47 2016 +1200

    dbcheck: change argument to specify a partial --yes
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 58acf513f93479d4b4c89e05a699e0bbd5320268
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Fri Jul 1 11:19:54 2016 +1200

    dbcheck linked attribute tests: save environment with bad links
    
    We save a database snapshot that contains linked attributes that
    should have been deleted, and make sure dbcheck fixes those links
    without ruining anything else.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f2b2eff6813fcc89195bc0bc5c09917cc5ff7396
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Fri Jul 1 11:22:11 2016 +1200

    blackbox/dbcheck-oldrelease: more accurate temp filename
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d8e7ffd029da32d94e09a9d3bf4605c3485dbb22
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Tue Jun 28 13:58:41 2016 +1200

    s4/selftest/provisions/dump.sh: dump to target dir if supplied
    
    This is clearly what was meant to happen.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 0b1405039ce73f97c3fd79f0517c883c09bbe0ed
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Jun 30 16:17:37 2016 +1200

    dbcheck: check for linked atributes that should not exist
    
    In order to do this we need to use the reveal internals control, which
    breaks the comparison against extended DNs. So we compare the
    components instead.
    
    Because this patch makes our code notice and fix stale one-way-links
    (eg, after a rename) now, the renamedc test needs to be adjusted to
    match.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 8edb8a78ec91225c11b823ec2bd24dbf54d985af
Author: Garming Sam <garming at samba.org>
Date:   Thu Jul 14 13:53:23 2016 +0200

    flapping: Add dbcheck to flapping
    
    This is required as the tests will pass or not depending on if it is run
    solely or not. This will be removed in the later patches.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ca839cf88abded1142891b500f706a5a083ae561
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Jun 30 16:15:35 2016 +1200

    dbcheck: cache linkIDs and reverse attribute names
    
    This avoids fetching the same same schema things again and again.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 31ffe971785333d6afb4885aba41d8be29c6e0e5
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Jul 13 13:29:19 2016 +1200

    extended_dn_out: Force showing of one-way links if they exist
    
    Signed-off-by: Garming Sam <garming at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 00e828a8a8bf56b93fe650faaa9652081ebd27f7
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 14 16:56:50 2016 +1200

    link_attrs: Add tests for one way links (and pseudo one-way)
    
    Tested against Win2012R2. The deactivated link control has no effect on either
    one way links or pseudo ones (only two-way ones presumably).
    
    Signed-off-by: Garming Sam <garming at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 9d8e7666c0daaffca14f88c25af971f6d6c9cfc1
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Jul 14 18:03:33 2016 +1200

    drs tests: querying linked attribute over DRS
    
    Without the deactivated links control, we assert certain conditions over DRS
    instead.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4cb565bc8777fffd3fa9c34117dba1de57c72002
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Jun 30 16:35:08 2016 +1200

    dsdb tests: add linked attribute tests
    
    Note that this test will not work properly across ldap as the
    marked-deleted linked attributes will not appear.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5ce969d0c70afc1f14a9b223edbaec7a847c64de
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jul 6 11:54:25 2016 +1200

    dsdb: add vanish links control
    
    Normally linked attributes are deleted by marking them as with RMD flags,
    but sometimes we want them to vanish without trace. At those times we
    set the DSDB_CONTROL_REPLMD_VANISH_LINKS control.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Pair-programmed-with: Andrew Bartlett <abartlet at samba.org>

commit b7b229a424cfe6a2bbe7b091c93a6f09b2132975
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jul 6 11:53:19 2016 +1200

    repl_meta_data: free context on error in replmd_modify_la_delete()
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5d201591e3955afaae38a1bbeb8f6cb3b8ab8c89
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Jun 30 15:43:33 2016 +1200

    replmd_modify_delete: check talloc_new()
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ebed182e34a5ac3464bb0d1ff9fb3033601c3dee
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Jun 2 09:25:00 2016 +1200

    s4/dsdb/repl_meta_data: use local bool version of flag
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4d7c782e004db299accdb4a955dfe7e53bbc2e57
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 14 12:27:32 2016 +1200

    match_rules: Make cleanup faster and more efficient
    
    Signed-off-by: Garming Sam <garming at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 3f0435452b7353d06c01e01c4e5ec00d033e6c6a
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Jul 14 12:28:58 2016 +1200

    match_rules: Fix a duplicated check
    
    Signed-off-by: Garming Sam <garming at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 2df3feaa785e93f7c8f668cb70e27381b3492393
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Jul 13 17:41:51 2016 +1200

    dbcheck: Script swallows input when given a carriage return
    
    Signed-off-by: Garming Sam <garming at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/ldb-samba/tests/match_rules.py                 |    43 +-
 python/samba/dbchecker.py                          |   205 +-
 python/samba/netcmd/dbcheck.py                     |    25 +-
 selftest/tests.py                                  |     5 +
 simple-dc-steps.sh                                 |    34 +
 source4/dsdb/common/util.c                         |     7 +
 source4/dsdb/common/util.h                         |    33 +-
 source4/dsdb/pydsdb.c                              |     1 +
 source4/dsdb/samdb/ldb_modules/extended_dn_out.c   |    12 +-
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c    |   149 +-
 source4/dsdb/samdb/samdb.h                         |     3 +
 source4/dsdb/tests/python/linked_attributes.py     |   431 +
 source4/selftest/provisions/dump.sh                |     4 +-
 .../release-4-5-0-pre1/add-deleted-user.sh         |    19 +
 ...nge-blackbox-tests-to-make-dbcheck-test-env.txt |    91 +
 .../expected-links-after-dbcheck.ldif              |  1220 +
 .../provisions/release-4-5-0-pre1/names.tdb.dump   |     0
 .../release-4-5-0-pre1/private/eadb.tdb.dump       |    96 +
 .../release-4-5-0-pre1/private/hklm.ldb.dump       |    80 +
 .../release-4-5-0-pre1/private/idmap.ldb.dump      |    48 +
 .../release-4-5-0-pre1/private/privilege.ldb.dump  |   156 +
 ...ELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb.dump | 28980 +++++++++++++
 ...ELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb.dump | 43468 +++++++++++++++++++
 ...CONFIGURATION,DC=FOO,DC=EXAMPLE,DC=COM.ldb.dump | 28980 +++++++++++++
 ...CONFIGURATION,DC=FOO,DC=EXAMPLE,DC=COM.ldb.dump | 43468 +++++++++++++++++++
 ...ELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb.dump |   872 +
 ...ELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb.dump |   468 +
 ...ELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb.dump |  6100 +++
 ...OMAINDNSZONES,DC=FOO,DC=EXAMPLE,DC=COM.ldb.dump |   872 +
 .../sam.ldb.d/DC=FOO,DC=EXAMPLE,DC=COM.ldb.dump    |  6100 +++
 ...ORESTDNSZONES,DC=FOO,DC=EXAMPLE,DC=COM.ldb.dump |   468 +
 .../private/sam.ldb.d/metadata.tdb.dump            |     4 +
 .../release-4-5-0-pre1/private/sam.ldb.dump        |    40 +
 .../release-4-5-0-pre1/private/secrets.ldb.dump    |    44 +
 .../release-4-5-0-pre1/private/secrets.tdb.dump    |    24 +
 .../release-4-5-0-pre1/private/share.ldb.dump      |    32 +
 source4/selftest/tests.py                          |     6 +
 source4/setup/schema_samba4.ldif                   |     1 +
 .../torture/drs/python/linked_attributes_drs.py    |   212 +
 testprogs/blackbox/dbcheck-oldrelease.sh           |    10 +-
 testprogs/blackbox/dbcheck.sh                      |    23 +-
 testprogs/blackbox/renamedc.sh                     |     7 +
 42 files changed, 162683 insertions(+), 158 deletions(-)
 create mode 100755 simple-dc-steps.sh
 create mode 100644 source4/dsdb/tests/python/linked_attributes.py
 create mode 100755 source4/selftest/provisions/release-4-5-0-pre1/add-deleted-user.sh
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/change-blackbox-tests-to-make-dbcheck-test-env.txt
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/expected-links-after-dbcheck.ldif
 copy buildtools/wafsamba/__init__.py => source4/selftest/provisions/release-4-5-0-pre1/names.tdb.dump (100%)
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/eadb.tdb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/hklm.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/idmap.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/privilege.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.d/CN%3DCONFIGURATION,DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.d/CN%3DSCHEMA,CN%3DCONFIGURATION,DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.d/CN=CONFIGURATION,DC=FOO,DC=EXAMPLE,DC=COM.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.d/CN=SCHEMA,CN=CONFIGURATION,DC=FOO,DC=EXAMPLE,DC=COM.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.d/DC%3DDOMAINDNSZONES,DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.d/DC%3DFORESTDNSZONES,DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.d/DC=DOMAINDNSZONES,DC=FOO,DC=EXAMPLE,DC=COM.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.d/DC=FOO,DC=EXAMPLE,DC=COM.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.d/DC=FORESTDNSZONES,DC=FOO,DC=EXAMPLE,DC=COM.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.d/metadata.tdb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/sam.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/secrets.ldb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/secrets.tdb.dump
 create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/private/share.ldb.dump
 create mode 100644 source4/torture/drs/python/linked_attributes_drs.py


Changeset truncated at 500 lines:

diff --git a/lib/ldb-samba/tests/match_rules.py b/lib/ldb-samba/tests/match_rules.py
index 9c92b8b..31132e3 100755
--- a/lib/ldb-samba/tests/match_rules.py
+++ b/lib/ldb-samba/tests/match_rules.py
@@ -271,27 +271,7 @@ class MatchRulesTests(samba.tests.TestCase):
 
     def tearDown(self):
         super(MatchRulesTests, self).tearDown()
-        delete_force(self.ldb, "cn=u4,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=u3,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=u2,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=u1,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=g4,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=g3,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=g2,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=g1,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=c1,%s" % self.ou_computers)
-        delete_force(self.ldb, "cn=c2,%s" % self.ou_computers)
-        delete_force(self.ldb, "cn=c3,%s" % self.ou_computers)
-        delete_force(self.ldb, self.ou_users)
-        delete_force(self.ldb, self.ou_groups)
-        delete_force(self.ldb, self.ou_computers)
-        delete_force(self.ldb, "OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
-        delete_force(self.ldb, "OU=o3,OU=o2,OU=o1,%s" % self.ou)
-        delete_force(self.ldb, "OU=o2,OU=o1,%s" % self.ou)
-        delete_force(self.ldb, "OU=o1,%s" % self.ou)
-        delete_force(self.ldb, "CN=e2,%s" % self.ou)
-        delete_force(self.ldb, "CN=e1,%s" % self.ou)
-        delete_force(self.ldb, self.ou)
+        self.ldb.delete(self.ou, controls=['tree_delete:0'])
 
     def test_u1_member_of_g4(self):
         # Search without transitive match must return 0 results
@@ -722,7 +702,7 @@ class MatchRulesTests(samba.tests.TestCase):
         self.assertEqual(len(res1), 2)
         dn_list = [str(res.dn).lower() for res in res1]
         self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
-        self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
+        self.assertTrue(("CN=e2,%s" % self.ou).lower() in dn_list)
 
         res1 = self.ldb.search(self.ou,
                         scope=SCOPE_ONELEVEL,
@@ -730,7 +710,7 @@ class MatchRulesTests(samba.tests.TestCase):
         self.assertEqual(len(res1), 2)
         dn_list = [str(res.dn).lower() for res in res1]
         self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
-        self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
+        self.assertTrue(("CN=e2,%s" % self.ou).lower() in dn_list)
 
     def test_not_linked_attrs(self):
         res1 = self.ldb.search(self.base_dn,
@@ -1141,22 +1121,7 @@ class MatchRuleConditionTests(samba.tests.TestCase):
 
     def tearDown(self):
         super(MatchRuleConditionTests, self).tearDown()
-        delete_force(self.ldb, "cn=u4,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=u3,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=u2,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=u1,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=g4,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=g3,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=g2,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=g1,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=c1,%s" % self.ou_computers)
-        delete_force(self.ldb, "cn=c2,%s" % self.ou_computers)
-        delete_force(self.ldb, "cn=c3,%s" % self.ou_computers)
-        delete_force(self.ldb, "cn=c4,%s" % self.ou_computers)
-        delete_force(self.ldb, self.ou_users)
-        delete_force(self.ldb, self.ou_groups)
-        delete_force(self.ldb, self.ou_computers)
-        delete_force(self.ldb, self.ou)
+        self.ldb.delete(self.ou, controls=['tree_delete:0'])
 
 
     def test_g1_members(self):
diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py
index 039f841..16258cf 100644
--- a/python/samba/dbchecker.py
+++ b/python/samba/dbchecker.py
@@ -52,10 +52,14 @@ class dbcheck(object):
         self.fix_all_duplicates = False
         self.fix_all_DN_GUIDs = False
         self.fix_all_binary_dn = False
-        self.remove_all_deleted_DN_links = False
-        self.fix_all_target_mismatch = False
+        self.remove_implausible_deleted_DN_links = False
+        self.remove_plausible_deleted_DN_links = False
+        self.fix_all_string_dn_component_mismatch = False
+        self.fix_all_GUID_dn_component_mismatch = False
+        self.fix_all_SID_dn_component_mismatch = False
         self.fix_all_metadata = False
         self.fix_time_metadata = False
+        self.fix_undead_linked_attributes = False
         self.fix_all_missing_backlinks = False
         self.fix_all_orphaned_backlinks = False
         self.fix_rmd_flags = False
@@ -88,7 +92,7 @@ class dbcheck(object):
         self.fix_missing_deleted_objects = False
 
         self.dn_set = set()
-
+        self.link_id_cache = {}
         self.name_map = {}
         try:
             res = samdb.search(base="CN=DnsAdmins,CN=Users,%s" % samdb.domain_dn(), scope=ldb.SCOPE_BASE,
@@ -277,14 +281,14 @@ systemFlags: -1946157056%s""" % (dn, guid_suffix),
         '''confirm a change with support for "all" '''
         if not self.fix:
             return False
-        if self.quiet:
-            return self.yes
         if getattr(self, all_attr) == 'NONE':
             return False
         if getattr(self, all_attr) == 'ALL':
             forced = True
         else:
             forced = self.yes
+        if self.quiet:
+            return forced
         c = common.confirm(msg, forced=forced, allow_all=True)
         if c == 'ALL':
             setattr(self, all_attr, 'ALL')
@@ -335,6 +339,17 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
             return False
         return True
 
+    def get_attr_linkID_and_reverse_name(self, attrname):
+        if attrname in self.link_id_cache:
+            return self.link_id_cache[attrname]
+        linkID = self.samdb_schema.get_linkId_from_lDAPDisplayName(attrname)
+        if linkID:
+            revname = self.samdb_schema.get_backlink_from_lDAPDisplayName(attrname)
+        else:
+            revname = None
+        self.link_id_cache[attrname] = (linkID, revname)
+        return linkID, revname
+
     def err_empty_attribute(self, dn, attrname):
         '''fix empty attributes'''
         self.report("ERROR: Empty attribute %s in %s" % (attrname, dn))
@@ -431,28 +446,35 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
                           "Failed to remove DN %s" % dn):
             self.report("Removed DN %s" % dn)
 
-    def err_deleted_dn(self, dn, attrname, val, dsdb_dn, correct_dn):
+    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 %s" % correct_dn)
-        if not self.confirm_all('Remove DN link?', 'remove_all_deleted_DN_links'):
-            self.report("Not removing")
-            return
+        self.report("Target GUID points at deleted DN %r" % str(correct_dn))
+        if not remove_plausible:
+            if not self.confirm_all('Remove DN link?', 'remove_implausible_deleted_DN_links'):
+                self.report("Not removing")
+                return
+        else:
+            if not self.confirm_all('Remove stale DN link?', 'remove_plausible_deleted_DN_links'):
+                self.report("Not removing")
+                return
+
         m = ldb.Message()
         m.dn = dn
         m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname)
-        if self.do_modify(m, ["show_recycled:1", "local_oid:%s:0" % dsdb.DSDB_CONTROL_DBCHECK],
+        if self.do_modify(m, ["show_recycled:1",
+                              "local_oid:%s:0" % dsdb.DSDB_CONTROL_REPLMD_VANISH_LINKS],
                           "Failed to remove deleted DN attribute %s" % attrname):
             self.report("Removed deleted DN on attribute %s" % attrname)
 
     def err_missing_dn_GUID(self, dn, attrname, val, dsdb_dn):
         """handle a missing target DN (both GUID and DN string form are missing)"""
         # check if its a backlink
-        linkID = self.samdb_schema.get_linkId_from_lDAPDisplayName(attrname)
+        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
-        self.err_deleted_dn(dn, attrname, val, dsdb_dn, dsdb_dn)
+        self.err_deleted_dn(dn, attrname, val, dsdb_dn, dsdb_dn, False)
 
     def err_incorrect_dn_GUID(self, dn, attrname, val, dsdb_dn, errstr):
         """handle a missing GUID extended DN component"""
@@ -500,21 +522,22 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
                           "Failed to fix %s on attribute %s" % (errstr, attrname)):
             self.report("Fixed %s on attribute %s" % (errstr, attrname))
 
-    def err_dn_target_mismatch(self, dn, attrname, val, dsdb_dn, correct_dn, errstr):
+    def err_dn_component_target_mismatch(self, dn, attrname, val, dsdb_dn, correct_dn, mismatch_type):
         """handle a DN string being incorrect"""
-        self.report("ERROR: incorrect DN string component for %s in object %s - %s" % (attrname, dn, val))
+        self.report("ERROR: incorrect DN %s component for %s in object %s - %s" % (mismatch_type, attrname, dn, val))
         dsdb_dn.dn = correct_dn
 
-        if not self.confirm_all('Change DN to %s?' % str(dsdb_dn), 'fix_all_target_mismatch'):
-            self.report("Not fixing %s" % errstr)
+        if not self.confirm_all('Change DN to %s?' % str(dsdb_dn),
+                                'fix_all_%s_dn_component_mismatch' % mismatch_type):
+            self.report("Not fixing %s component mismatch" % mismatch_type)
             return
         m = ldb.Message()
         m.dn = dn
         m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname)
         m['new_value'] = ldb.MessageElement(str(dsdb_dn), ldb.FLAG_MOD_ADD, attrname)
         if self.do_modify(m, ["show_recycled:1"],
-                          "Failed to fix incorrect DN string on attribute %s" % attrname):
-            self.report("Fixed incorrect DN string on attribute %s" % (attrname))
+                          "Failed to fix incorrect DN %s on attribute %s" % (mismatch_type, attrname)):
+            self.report("Fixed incorrect DN %s on attribute %s" % (mismatch_type, attrname))
 
     def err_unknown_attribute(self, obj, attrname):
         '''handle an unknown attribute error'''
@@ -529,6 +552,22 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
                           "Failed to remove unknown attribute %s" % attrname):
             self.report("Removed unknown attribute %s" % (attrname))
 
+    def err_undead_linked_attribute(self, obj, attrname, val):
+        '''handle a link that should not be there on a deleted object'''
+        self.report("ERROR: linked attribute '%s' to '%s' is present on "
+                    "deleted object %s" % (attrname, val, obj.dn))
+        if not self.confirm_all('Remove linked attribute %s' % attrname, 'fix_undead_linked_attributes'):
+            self.report("Not removing linked attribute %s" % attrname)
+            return
+        m = ldb.Message()
+        m.dn = obj.dn
+        m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname)
+
+        if self.do_modify(m, ["show_recycled:1", "show_deleted:1", "reveal_internals:0",
+                              "local_oid:%s:0" % dsdb.DSDB_CONTROL_REPLMD_VANISH_LINKS],
+                          "Failed to delete forward link %s" % attrname):
+            self.report("Fixed undead forward link %s" % (attrname))
+
     def err_missing_backlink(self, obj, attrname, val, backlink_name, target_dn):
         '''handle a missing backlink value'''
         self.report("ERROR: missing backlink attribute '%s' in %s for link %s in %s" % (backlink_name, target_dn, attrname, obj.dn))
@@ -724,6 +763,8 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
     def check_dn(self, obj, attrname, syntax_oid):
         '''check a DN attribute for correctness'''
         error_count = 0
+        obj_guid = obj['objectGUID'][0]
+
         for val in obj[attrname]:
             dsdb_dn = dsdb_Dn(self.samdb, val, syntax_oid)
 
@@ -736,8 +777,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
                 continue
 
             guidstr = str(misc.GUID(guid))
-
-            attrs = ['isDeleted']
+            attrs = ['isDeleted', 'replPropertyMetaData']
 
             if (str(attrname).lower() == 'msds-hasinstantiatedncs') and (obj.dn == self.ntds_dsa):
                 fixing_msDS_HasInstantiatedNCs = True
@@ -745,15 +785,16 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
             else:
                 fixing_msDS_HasInstantiatedNCs = False
 
-            linkID = self.samdb_schema.get_linkId_from_lDAPDisplayName(attrname)
-            reverse_link_name = self.samdb_schema.get_backlink_from_lDAPDisplayName(attrname)
+            linkID, reverse_link_name = self.get_attr_linkID_and_reverse_name(attrname)
             if reverse_link_name is not None:
                 attrs.append(reverse_link_name)
 
             # check its the right GUID
             try:
                 res = self.samdb.search(base="<GUID=%s>" % guidstr, scope=ldb.SCOPE_BASE,
-                                        attrs=attrs, controls=["extended_dn:1:1", "show_recycled:1"])
+                                        attrs=attrs, controls=["extended_dn:1:1", "show_recycled:1",
+                                                               "reveal_internals:0"
+                                        ])
             except ldb.LdbError, (enum, estr):
                 error_count += 1
                 self.err_incorrect_dn_GUID(obj.dn, attrname, val, dsdb_dn, "incorrect GUID")
@@ -772,43 +813,82 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
             is_deleted = 'isDeleted' in obj and obj['isDeleted'][0].upper() == 'TRUE'
             target_is_deleted = 'isDeleted' in res[0] and res[0]['isDeleted'][0].upper() == 'TRUE'
 
-            # the target DN is not allowed to be deleted, unless the target DN is the
-            # special Deleted Objects container
-            if target_is_deleted and not is_deleted and not self.is_deleted_objects_dn(dsdb_dn):
+
+            if is_deleted and not obj.dn in self.deleted_objects_containers and linkID:
+                # A fully deleted object should not have any linked
+                # attributes. (MS-ADTS 3.1.1.5.5.1.1 Tombstone
+                # Requirements and 3.1.1.5.5.1.3 Recycled-Object
+                # Requirements)
+                self.err_undead_linked_attribute(obj, attrname, val)
                 error_count += 1
-                self.err_deleted_dn(obj.dn, attrname, val, dsdb_dn, res[0].dn)
+                continue
+            elif target_is_deleted and not self.is_deleted_objects_dn(dsdb_dn) and linkID:
+                # the target DN is not allowed to be deleted, unless the target DN is the
+                # special Deleted Objects container
+                error_count += 1
+                local_usn = dsdb_dn.dn.get_extended_component("RMD_LOCAL_USN")
+                if local_usn:
+                    if 'replPropertyMetaData' in res[0]:
+                        repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
+                                          str(res[0]['replPropertyMetadata']))
+                        found_data = False
+                        for o in repl.ctr.array:
+                            if o.attid == drsuapi.DRSUAPI_ATTID_isDeleted:
+                                deleted_usn = o.local_usn
+                                if deleted_usn >= int(local_usn):
+                                    # If the object was deleted after the link
+                                    # was last modified then, clean it up here
+                                    found_data = True
+                                    break
+
+                        if found_data:
+                            self.err_deleted_dn(obj.dn, attrname,
+                                                val, dsdb_dn, res[0].dn, True)
+                            continue
+
+                self.err_deleted_dn(obj.dn, attrname, val, dsdb_dn, res[0].dn, False)
                 continue
 
             # check the DN matches in string form
-            if res[0].dn.extended_str() != dsdb_dn.dn.extended_str():
+            if str(res[0].dn) != str(dsdb_dn.dn):
                 error_count += 1
-                self.err_dn_target_mismatch(obj.dn, attrname, val, dsdb_dn,
-                                            res[0].dn, "incorrect string version of DN")
+                self.err_dn_component_target_mismatch(obj.dn, attrname, val, dsdb_dn,
+                                                      res[0].dn, "string")
+                continue
+
+            if res[0].dn.get_extended_component("GUID") != dsdb_dn.dn.get_extended_component("GUID"):
+                error_count += 1
+                self.err_dn_component_target_mismatch(obj.dn, attrname, val, dsdb_dn,
+                                                      res[0].dn, "GUID")
+                continue
+
+            if res[0].dn.get_extended_component("SID") != dsdb_dn.dn.get_extended_component("SID"):
+                error_count += 1
+                self.err_dn_component_target_mismatch(obj.dn, attrname, val, dsdb_dn,
+                                                      res[0].dn, "SID")
                 continue
 
-            if is_deleted and not target_is_deleted and reverse_link_name is not None:
-                revealed_dn = self.find_revealed_link(obj.dn, attrname, guid)
-                rmd_flags = revealed_dn.dn.get_extended_component("RMD_FLAGS")
-                if rmd_flags is not None and (int(rmd_flags) & 1) == 0:
-                    # the RMD_FLAGS for this link should be 1, as the target is deleted
-                    self.err_incorrect_rmd_flags(obj, attrname, revealed_dn)
-                    continue
 
             # check the reverse_link is correct if there should be one
             if reverse_link_name is not None:
                 match_count = 0
                 if reverse_link_name in res[0]:
                     for v in res[0][reverse_link_name]:
-                        if v == obj.dn.extended_str():
+                        v_guid = dsdb_Dn(self.samdb, v).dn.get_extended_component("GUID")
+                        if v_guid == obj_guid:
                             match_count += 1
                 if match_count != 1:
-                    error_count += 1
-                    if linkID & 1:
-                        self.err_orphaned_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn)
-                    else:
-                        self.err_missing_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn)
+                    if target_is_deleted:
+                        error_count += 1
+                        if linkID & 1:
+                            self.err_missing_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn)
+                        else:
+                            self.err_orphaned_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn)
                     continue
 
+
+
+
         return error_count
 
 
@@ -1365,6 +1445,8 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
             attrs.append("systemFlags")
         if '*' in attrs:
             attrs.append("replPropertyMetaData")
+        else:
+            attrs.append("objectGUID")
 
         try:
             sd_flags = 0
@@ -1379,6 +1461,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
                                         "show_recycled:1",
                                         "show_deleted:1",
                                         "sd_flags:1:%d" % sd_flags,
+                                        "reveal_internals:0",
                                     ],
                                     attrs=attrs)
         except ldb.LdbError, (enum, estr):
@@ -1415,7 +1498,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
         systemFlags = 0
 
         for attrname in obj:
-            if attrname == 'dn':
+            if attrname == 'dn' or attrname == "distinguishedName":
                 continue
 
             if str(attrname).lower() == 'objectclass':
@@ -1468,8 +1551,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
 
                 else:
                     # Here we check that the first attid is 0
-                    # (objectClass) and that the last on is the RDN
-                    # from the DN.
+                    # (objectClass).
                     if list_attid_from_md[0] != 0:
                         error_count += 1
                         self.report("ERROR: Not fixing incorrect inital attributeID in '%s' on '%s', it should be objectClass" %
@@ -1583,33 +1665,36 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
                 error_count += 1
                 continue
 
+            linkID, reverse_link_name = self.get_attr_linkID_and_reverse_name(attrname)
+
             flag = self.samdb_schema.get_systemFlags_from_lDAPDisplayName(attrname)
             if (not flag & dsdb.DS_FLAG_ATTR_NOT_REPLICATED
                 and not flag & dsdb.DS_FLAG_ATTR_IS_CONSTRUCTED
-                and not self.samdb_schema.get_linkId_from_lDAPDisplayName(attrname)):
+                and not linkID):
                 set_attrs_seen.add(str(attrname).lower())
 
             if syntax_oid in [ dsdb.DSDB_SYNTAX_BINARY_DN, dsdb.DSDB_SYNTAX_OR_NAME,
                                dsdb.DSDB_SYNTAX_STRING_DN, ldb.SYNTAX_DN ]:
                 # it's some form of DN, do specialised checking on those
                 error_count += self.check_dn(obj, attrname, syntax_oid)
+            else:
 
-            values = set()
-            # check for incorrectly normalised attributes
-            for val in obj[attrname]:
-                values.add(str(val))
+                values = set()
+                # check for incorrectly normalised attributes
+                for val in obj[attrname]:
+                    values.add(str(val))
 
-                normalised = self.samdb.dsdb_normalise_attributes(self.samdb_schema, attrname, [val])
-                if len(normalised) != 1 or normalised[0] != val:
-                    self.err_normalise_mismatch(dn, attrname, obj[attrname])
+                    normalised = self.samdb.dsdb_normalise_attributes(self.samdb_schema, attrname, [val])
+                    if len(normalised) != 1 or normalised[0] != val:
+                        self.err_normalise_mismatch(dn, attrname, obj[attrname])
+                        error_count += 1
+                        break
+
+                if len(obj[attrname]) != len(values):
+                    self.err_duplicate_values(dn, attrname, obj[attrname], list(values))
                     error_count += 1
                     break
 
-            if len(obj[attrname]) != len(values):
-                   self.err_duplicate_values(dn, attrname, obj[attrname], list(values))
-                   error_count += 1
-                   break
-
             if str(attrname).lower() == "instancetype":
                 calculated_instancetype = self.calculate_instancetype(dn)
                 if len(obj["instanceType"]) != 1 or obj["instanceType"][0] != str(calculated_instancetype):
diff --git a/python/samba/netcmd/dbcheck.py b/python/samba/netcmd/dbcheck.py
index 4cc0631..2217366 100644
--- a/python/samba/netcmd/dbcheck.py
+++ b/python/samba/netcmd/dbcheck.py
@@ -38,6 +38,21 @@ class cmd_dbcheck(Command):
         "credopts": options.CredentialsOptionsDouble,
     }
 
+    def process_yes(option, opt, value, parser):
+        assert value is None
+        done = 0
+        rargs = parser.rargs
+        if rargs:
+            arg = rargs[0]
+            if ((arg[:2] == "--" and len(arg) > 2) or
+                (arg[:1] == "-" and len(arg) > 1 and arg[1] != "-")):
+                setattr(parser.values, "yes", True)
+            else:
+                setattr(parser.values, "yes_rules", arg.split())
+                del rargs[0]
+        else:
+            setattr(parser.values, "yes", True)
+
     takes_args = ["DN?"]
 
     takes_options = [
@@ -45,7 +60,7 @@ class cmd_dbcheck(Command):
             help="Pass search scope that builds DN list. Options: SUB, ONE, BASE"),
         Option("--fix", dest="fix", default=False, action='store_true',
                help='Fix any errors found'),
-        Option("--yes", dest="yes", default=False, action='store_true',
+        Option("--yes", action='callback', callback=process_yes,
                help="don't confirm changes, just do them all as a single transaction"),
         Option("--cross-ncs", dest="cross_ncs", default=False, action='store_true',
                help="cross naming context boundaries"),
@@ -65,7 +80,7 @@ class cmd_dbcheck(Command):


-- 
Samba Shared Repository



More information about the samba-cvs mailing list