From 9224a2ff99709fb784d14eef7fea480740cfc6d2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Apr 2020 20:00:51 +0200 Subject: [PATCH 1/8] python/tests: add DynamicTestCase setUpDynamicTestCases() infrastructure This can be used in order to run a sepcific test (coded just once) with an autogenerated set of arguments. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531 Pair-Programmed-With: Douglas Bagnall Signed-off-by: Stefan Metzmacher Signed-off-by: Douglas Bagnall (cherry picked from commit 80347deb544b38be6c6814e5d1b82e48ebe83fd1) --- python/samba/tests/__init__.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 3f22eaa1c94c..9d5128bab0eb 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -63,10 +63,37 @@ BINDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), HEXDUMP_FILTER = bytearray([x if ((len(repr(chr(x))) == 3) and (x < 127)) else ord('.') for x in range(256)]) +def DynamicTestCase(cls): + cls.setUpDynamicTestCases() + return cls class TestCase(unittest.TestCase): """A Samba test case.""" + @classmethod + def generate_dynamic_test(cls, fnname, suffix, *args): + """ + fnname is something like "test_dynamic_sum" + suffix is something like "1plus2" + argstr could be (1, 2) + + This would generate a test case called + "test_dynamic_sum_1plus2(self)" that + calls + self._test_dynamic_sum_with_args(1, 2) + """ + def fn(self): + getattr(self, "_%s_with_args" % fnname)(*args) + setattr(cls, "%s_%s" % (fnname, suffix), fn) + + @classmethod + def setUpDynamicTestCases(cls): + """This can be implemented in order to call cls.generate_dynamic_test() + In order to implement autogenerated testcase permutations. + """ + msg = "%s needs setUpDynamicTestCases() if @DynamicTestCase is used!" % (cls) + raise Exception(msg) + def setUp(self): super(TestCase, self).setUp() test_debug_level = os.getenv("TEST_DEBUG_LEVEL") -- 2.17.1 From 4a4ef305fb3bdd9ed1a033559e1dcbfe7e64d9de Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 7 Oct 2020 13:21:06 +0200 Subject: [PATCH 2/8] s4:dsdb:tests: add AclVisibiltyTests This tests a sorts of combinations in order to demonstrate the visibility of objects depending on: - with or without fDoListObject - with or without explicit DENY ACEs - A hierachy of objects with 4 levels from the base dn - SEC_ADS_LIST (List Children) - SEC_ADS_LIST_LIST_OBJECT (List Object) - SEC_ADS_READ_PROP - all possible scopes and basedns This demonstrates that NO_SUCH_OBJECT doesn't depend purely on the visibility of the base dn, it's still possible to get children returned und an invisible base dn. It also demonstrates the additional behavior with "List Object" mode. See [MS-ADTS] 5.1.3.3.6 Checking Object Visibility BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531 Signed-off-by: Stefan Metzmacher Reviewed-by: Douglas Bagnall (cherry picked from commit 06d134406739e76b97273db3023855150dbaebbc) --- selftest/knownfail.d/ldap-acl-visibility | 154 +++++++++++ source4/dsdb/tests/python/acl.py | 321 ++++++++++++++++++++++- source4/selftest/tests.py | 2 +- 3 files changed, 475 insertions(+), 2 deletions(-) create mode 100644 selftest/knownfail.d/ldap-acl-visibility diff --git a/selftest/knownfail.d/ldap-acl-visibility b/selftest/knownfail.d/ldap-acl-visibility new file mode 100644 index 000000000000..6ecec6587f2b --- /dev/null +++ b/selftest/knownfail.d/ldap-acl-visibility @@ -0,0 +1,154 @@ +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_Cn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_Cn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_Cn_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_CO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_CO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_CO_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_Cn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_Cn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_Cn_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_Cn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_Cn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_Cn_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_CO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_CO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_CO_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_Cn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_Cn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_Cn_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_CO_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_CO_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_CO_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_CO_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_Cn_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_Cn_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_Cn_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_Cn_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_CO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_CO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_CO_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_Cn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_Cn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_Cn_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_CO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_CO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_CO_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_Cn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_Cn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_Cn_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_CO_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_CO_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_CO_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_CO_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_Cn_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_Cn_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_Cn_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_Cn_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_CO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_CO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_CO_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_Cn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_Cn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_Cn_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_nn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_CO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_CO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_CO_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_CO_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_Cn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_Cn_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_Cn_nO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_Cn_nn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_nO_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_nO_Cn +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_nn_CO +^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_nn_Cn diff --git a/source4/dsdb/tests/python/acl.py b/source4/dsdb/tests/python/acl.py index dbad8a36a8d2..daf3849d936b 100755 --- a/source4/dsdb/tests/python/acl.py +++ b/source4/dsdb/tests/python/acl.py @@ -10,6 +10,7 @@ import re sys.path.insert(0, "bin/python") import samba +from samba.tests import DynamicTestCase from samba.tests.subunitrun import SubunitOptions, TestProgram from samba.compat import get_string @@ -17,7 +18,7 @@ import samba.getopt as options from samba.join import DCJoinContext from ldb import ( - SCOPE_BASE, SCOPE_SUBTREE, LdbError, ERR_NO_SUCH_OBJECT, + SCOPE_BASE, SCOPE_ONELEVEL, SCOPE_SUBTREE, LdbError, ERR_NO_SUCH_OBJECT, ERR_UNWILLING_TO_PERFORM, ERR_INSUFFICIENT_ACCESS_RIGHTS) from ldb import ERR_CONSTRAINT_VIOLATION from ldb import ERR_OPERATIONS_ERROR @@ -2189,6 +2190,324 @@ class AclSPNTests(AclTests): def test_spn_rodc(self): self.dc_spn_test(self.rodcctx) +# tests SEC_ADS_LIST vs. SEC_ADS_LIST_OBJECT +@DynamicTestCase +class AclVisibiltyTests(AclTests): + + envs = { + "No": False, + "Do": True, + } + modes = { + "Allow": False, + "Deny": True, + } + perms = { + "nn": 0, + "Cn": security.SEC_ADS_LIST, + "nO": security.SEC_ADS_LIST_OBJECT, + "CO": security.SEC_ADS_LIST | security.SEC_ADS_LIST_OBJECT, + } + + @classmethod + def setUpDynamicTestCases(cls): + for le in cls.envs.keys(): + for lm in cls.modes.keys(): + for l1 in cls.perms.keys(): + for l2 in cls.perms.keys(): + for l3 in cls.perms.keys(): + tname = "%s_%s_%s_%s_%s" % (le, lm, l1, l2, l3) + ve = cls.envs[le] + vm = cls.modes[lm] + v1 = cls.perms[l1] + v2 = cls.perms[l2] + v3 = cls.perms[l3] + targs = (tname, ve, vm, v1, v2, v3) + cls.generate_dynamic_test("test_visibility", + tname, *targs) + return + + def setUp(self): + super(AclVisibiltyTests, self).setUp() + + strict_checking = samba.tests.env_get_var_value('STRICT_CHECKING', allow_missing=True) + if strict_checking is None: + strict_checking = '1' + self.strict_checking = bool(int(strict_checking)) + + # Get the old "dSHeuristics" if it was set + self.dsheuristics = self.ldb_admin.get_dsheuristics() + # Reset the "dSHeuristics" as they were before + self.addCleanup(self.ldb_admin.set_dsheuristics, self.dsheuristics) + + # Domain Admins and SYSTEM get full access + self.sddl_dacl = "D:PAI(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" + self.set_dacl_control = ["sd_flags:1:%d" % security.SECINFO_DACL] + + self.level_idxs = [ 1, 2, 3, 4 ] + self.oul1 = "OU=acl_visibility_oul1" + self.oul1_dn_str = "%s,%s" % (self.oul1, self.base_dn) + self.oul2 = "OU=oul2,%s" % self.oul1 + self.oul2_dn_str = "%s,%s" % (self.oul2, self.base_dn) + self.oul3 = "OU=oul3,%s" % self.oul2 + self.oul3_dn_str = "%s,%s" % (self.oul3, self.base_dn) + self.user_name = "acl_visibility_user" + self.user_dn_str = "CN=%s,%s" % (self.user_name, self.oul3_dn_str) + delete_force(self.ldb_admin, self.user_dn_str) + delete_force(self.ldb_admin, self.oul3_dn_str) + delete_force(self.ldb_admin, self.oul2_dn_str) + delete_force(self.ldb_admin, self.oul1_dn_str) + self.ldb_admin.create_ou(self.oul1_dn_str) + self.sd_utils.modify_sd_on_dn(self.oul1_dn_str, + self.sddl_dacl, + controls=self.set_dacl_control) + self.ldb_admin.create_ou(self.oul2_dn_str) + self.sd_utils.modify_sd_on_dn(self.oul2_dn_str, + self.sddl_dacl, + controls=self.set_dacl_control) + self.ldb_admin.create_ou(self.oul3_dn_str) + self.sd_utils.modify_sd_on_dn(self.oul3_dn_str, + self.sddl_dacl, + controls=self.set_dacl_control) + + self.ldb_admin.newuser(self.user_name, self.user_pass, userou=self.oul3) + self.user_sid = self.sd_utils.get_object_sid(self.user_dn_str) + self.ldb_user = self.get_ldb_connection(self.user_name, self.user_pass) + + def tearDown(self): + super(AclVisibiltyTests, self).tearDown() + delete_force(self.ldb_admin, self.user_dn_str) + delete_force(self.ldb_admin, self.oul3_dn_str) + delete_force(self.ldb_admin, self.oul2_dn_str) + delete_force(self.ldb_admin, self.oul1_dn_str) + + del self.ldb_user + + def _test_visibility_with_args(self, + tname, + fDoListObject, + modeDeny, + l1_allow, + l2_allow, + l3_allow): + l1_deny = 0 + l2_deny = 0 + l3_deny = 0 + if modeDeny: + l1_deny = ~l1_allow + l2_deny = ~l2_allow + l3_deny = ~l3_allow + print("Testing: fDoListObject=%s, modeDeny=%s, l1_allow=0x%02x, l2_allow=0x%02x, l3_allow=0x%02x)" % ( + fDoListObject, modeDeny, l1_allow, l2_allow, l3_allow)) + if fDoListObject: + self.ldb_admin.set_dsheuristics("001") + else: + self.ldb_admin.set_dsheuristics("000") + + def _generate_dacl(allow, deny): + dacl = self.sddl_dacl + drights = "" + if deny & security.SEC_ADS_LIST: + drights += "LC" + if deny & security.SEC_ADS_LIST_OBJECT: + drights += "LO" + if len(drights) > 0: + dacl += "(D;;%s;;;%s)" % (drights, self.user_sid) + arights = "" + if allow & security.SEC_ADS_LIST: + arights += "LC" + if allow & security.SEC_ADS_LIST_OBJECT: + arights += "LO" + if len(arights) > 0: + dacl += "(A;;%s;;;%s)" % (arights, self.user_sid) + print("dacl: %s" % dacl) + return dacl + + l1_dacl = _generate_dacl(l1_allow, l1_deny) + l2_dacl = _generate_dacl(l2_allow, l2_deny) + l3_dacl = _generate_dacl(l3_allow, l3_deny) + self.sd_utils.modify_sd_on_dn(self.oul1_dn_str, + l1_dacl, + controls=self.set_dacl_control) + self.sd_utils.modify_sd_on_dn(self.oul2_dn_str, + l2_dacl, + controls=self.set_dacl_control) + self.sd_utils.modify_sd_on_dn(self.oul3_dn_str, + l3_dacl, + controls=self.set_dacl_control) + + def _generate_levels(_l1_allow, + _l1_deny, + _l2_allow, + _l2_deny, + _l3_allow, + _l3_deny): + _l0_allow = security.SEC_ADS_LIST | security.SEC_ADS_LIST_OBJECT | security.SEC_ADS_READ_PROP + _l0_deny = 0 + _l4_allow = security.SEC_ADS_LIST | security.SEC_ADS_LIST_OBJECT | security.SEC_ADS_READ_PROP + _l4_deny = 0 + _levels = [{ + "dn": str(self.base_dn), + "allow": _l0_allow, + "deny": _l0_deny, + },{ + "dn": str(self.oul1_dn_str), + "allow": _l1_allow, + "deny": _l1_deny, + },{ + "dn": str(self.oul2_dn_str), + "allow": _l2_allow, + "deny": _l2_deny, + },{ + "dn": str(self.oul3_dn_str), + "allow": _l3_allow, + "deny": _l3_deny, + },{ + "dn": str(self.user_dn_str), + "allow": _l4_allow, + "deny": _l4_deny, + }] + return _levels + + def _generate_admin_levels(): + _l1_allow = security.SEC_ADS_LIST | security.SEC_ADS_READ_PROP + _l1_deny = 0 + _l2_allow = security.SEC_ADS_LIST | security.SEC_ADS_READ_PROP + _l2_deny = 0 + _l3_allow = security.SEC_ADS_LIST | security.SEC_ADS_READ_PROP + _l3_deny = 0 + return _generate_levels(_l1_allow, _l1_deny, + _l2_allow, _l2_deny, + _l3_allow, _l3_deny) + + def _generate_user_levels(): + return _generate_levels(l1_allow, l1_deny, + l2_allow, l2_deny, + l3_allow, l3_deny) + + admin_levels = _generate_admin_levels() + user_levels = _generate_user_levels() + + def _msg_require_name(msg, idx, e): + self.assertIn("name", msg) + self.assertEqual(len(msg["name"]), 1) + + def _msg_no_name(msg, idx, e): + self.assertNotIn("name", msg) + + def _has_right(allow, deny, bit): + if allow & bit: + if not (deny & bit): + return True + return False + + def _is_visible(p_allow, p_deny, o_allow, o_deny): + plc = _has_right(p_allow, p_deny, security.SEC_ADS_LIST) + if plc: + return True + if not fDoListObject: + return False + plo = _has_right(p_allow, p_deny, security.SEC_ADS_LIST_OBJECT) + if not plo: + return False + olo = _has_right(o_allow, o_deny, security.SEC_ADS_LIST_OBJECT) + if not olo: + return False + return True + + def _generate_expected(scope, base_level, levels): + expected = {} + + p = levels[base_level-1] + o = levels[base_level] + base_visible = _is_visible(p["allow"], p["deny"], + o["allow"], o["deny"]) + + if scope == SCOPE_BASE: + lmin = base_level + lmax = base_level + elif scope == SCOPE_ONELEVEL: + lmin = base_level+1 + lmax = base_level+1 + else: + lmin = base_level + lmax = len(levels) + + next_idx = 0 + for li in self.level_idxs: + if li < lmin: + continue + if li > lmax: + break + p = levels[li-1] + o = levels[li] + visible = _is_visible(p["allow"], p["deny"], + o["allow"], o["deny"]) + if not visible: + continue + read = _has_right(o["allow"], o["deny"], security.SEC_ADS_READ_PROP) + if read: + check_msg_fn = _msg_require_name + else: + check_msg_fn = _msg_no_name + expected[o["dn"]] = { + "idx": next_idx, + "check_msg_fn": check_msg_fn, + } + next_idx += 1 + + if len(expected) == 0 and not base_visible: + # This means we're expecting NO_SUCH_OBJECT + return None + return expected + + def _verify_result_array(results, + description, + expected): + print("%s Results: %d" % (description, len(results))) + for msg in results: + print("%s" % msg) + self.assertIsNotNone(expected) + print("%s Expected: %d" % (description, len(expected))) + for e in expected: + print("%s" % e) + self.assertEqual(len(results), len(expected)) + idx = 0 + found = {} + for msg in results: + dn_str = str(msg.dn) + self.assertIn(dn_str, expected) + self.assertNotIn(dn_str, found) + found[dn_str] = idx + e = expected[dn_str] + if self.strict_checking: + self.assertEqual(idx, int(e["idx"])) + if "check_msg_fn" in e: + check_msg_fn = e["check_msg_fn"] + check_msg_fn(msg, idx, e) + idx += 1 + + return + + for li in self.level_idxs: + base_dn = admin_levels[li]["dn"] + for scope in [SCOPE_BASE, SCOPE_ONELEVEL, SCOPE_SUBTREE]: + print("\nTesting SCOPE[%d] %s" % (scope, base_dn)) + admin_expected = _generate_expected(scope, li, admin_levels) + admin_res = self.ldb_admin.search(base_dn, scope=scope, attrs=["name"]) + _verify_result_array(admin_res, "Admin", admin_expected) + + user_expected = _generate_expected(scope, li, user_levels) + try: + user_res = self.ldb_user.search(base_dn, scope=scope, attrs=["name"]) + except LdbError as e: + (num, _) = e.args + if user_expected is None: + self.assertEqual(num, ERR_NO_SUCH_OBJECT) + print("User: NO_SUCH_OBJECT") + continue + self.fail(e) + _verify_result_array(user_res, "User", user_expected) # Important unit running information diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 308da8d06b0a..7d55aed89b48 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -1029,7 +1029,7 @@ for env in all_fl_envs + ["schema_dc"]: plantestsuite_loadlist("samba4.ldap_schema.python(%s)" % env, env, [python, os.path.join(DSDB_PYTEST_DIR, "ldap_schema.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) plantestsuite("samba4.ldap.possibleInferiors.python(%s)" % env, env, [python, os.path.join(samba4srcdir, "dsdb/samdb/ldb_modules/tests/possibleinferiors.py"), "ldap://$SERVER", '-U"$USERNAME%$PASSWORD"', "-W$DOMAIN"]) plantestsuite_loadlist("samba4.ldap.secdesc.python(%s)" % env, env, [python, os.path.join(DSDB_PYTEST_DIR, "sec_descriptor.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) - plantestsuite_loadlist("samba4.ldap.acl.python(%s)" % env, env, [python, os.path.join(DSDB_PYTEST_DIR, "acl.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) + plantestsuite_loadlist("samba4.ldap.acl.python(%s)" % env, env, ["STRICT_CHECKING=0", python, os.path.join(DSDB_PYTEST_DIR, "acl.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) if env != "fl2000dc": # This test makes excessive use of the "userPassword" attribute which # isn't available on DCs with Windows 2000 domain function level - -- 2.17.1 From fc29efe0ce2be9e4690fe15d4acad3acc0e09cb6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Oct 2020 15:07:19 +0200 Subject: [PATCH 3/8] s4:dsdb:acl_read: introduce aclread_check_object_visible() helper In future this will do more than aclread_check_parent(), if we implement fDoListObject and SEC_ADS_LIST_OBJECT handling. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531 Signed-off-by: Stefan Metzmacher Reviewed-by: Douglas Bagnall (cherry picked from commit d2dd7c2a5c1f8ee30f0f3b41f933d082b0c75f7c) --- source4/dsdb/samdb/ldb_modules/acl_read.c | 34 +++++++++++++++++------ 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c index 1e016b970ee4..9d088698e8c3 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_read.c +++ b/source4/dsdb/samdb/ldb_modules/acl_read.c @@ -152,6 +152,25 @@ static int aclread_check_parent(struct aclread_context *ac, return ret; } +static int aclread_check_object_visible(struct aclread_context *ac, + struct ldb_message *msg, + struct ldb_request *req) +{ + uint32_t instanceType; + + /* get the object instance type */ + instanceType = ldb_msg_find_attr_as_uint(msg, + "instanceType", 0); + if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) { + /* + * NC_HEAD objects are always visible + */ + return LDB_SUCCESS; + } + + return aclread_check_parent(ac, msg, req); +} + /* * The sd returned from this function is valid until the next call on * this module context @@ -464,7 +483,6 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares) struct security_descriptor *sd = NULL; struct dom_sid *sid = NULL; TALLOC_CTX *tmp_ctx; - uint32_t instanceType; const struct dsdb_class *objectclass; bool suppress_result = false; @@ -507,14 +525,12 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares) } sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid"); - /* get the object instance type */ - instanceType = ldb_msg_find_attr_as_uint(msg, - "instanceType", 0); - if (!ldb_dn_is_null(msg->dn) && !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) - { - /* the object has a parent, so we have to check for visibility */ - ret = aclread_check_parent(ac, msg, req); - + if (!ldb_dn_is_null(msg->dn)) { + /* + * this is a real object, so we have + * to check for visibility + */ + ret = aclread_check_object_visible(ac, msg, req); if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { talloc_free(tmp_ctx); return LDB_SUCCESS; -- 2.17.1 From 76305e5cbbcc0c864bdec5f40cbed525cedd7bab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Oct 2020 15:10:33 +0200 Subject: [PATCH 4/8] s4:dsdb:acl_read: fully set up 'struct aclread_context' before the search base acl check This makes further change much easier. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531 Signed-off-by: Stefan Metzmacher Reviewed-by: Douglas Bagnall (cherry picked from commit c4a3028de726d6708f57d02f9162a4d62d1b6ae7) --- source4/dsdb/samdb/ldb_modules/acl_read.c | 62 ++++++++++++----------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c index 9d088698e8c3..dca43bcab76b 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_read.c +++ b/source4/dsdb/samdb/ldb_modules/acl_read.c @@ -763,36 +763,6 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req) return ldb_next_request(module, req); } - /* check accessibility of base */ - if (!ldb_dn_is_null(req->op.search.base)) { - ret = dsdb_module_search_dn(module, req, &res, req->op.search.base, - acl_attrs, - DSDB_FLAG_NEXT_MODULE | - DSDB_FLAG_AS_SYSTEM | - DSDB_SEARCH_SHOW_RECYCLED, - req); - if (ret != LDB_SUCCESS) { - return ldb_error(ldb, ret, - "acl_read: Error retrieving instanceType for base."); - } - instanceType = ldb_msg_find_attr_as_uint(res->msgs[0], - "instanceType", 0); - if (instanceType != 0 && !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) - { - /* the object has a parent, so we have to check for visibility */ - struct ldb_dn *parent_dn = ldb_dn_get_parent(req, req->op.search.base); - ret = dsdb_module_check_access_on_dn(module, - req, - parent_dn, - SEC_ADS_LIST, - NULL, req); - if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { - return ldb_module_done(req, NULL, NULL, LDB_ERR_NO_SUCH_OBJECT); - } else if (ret != LDB_SUCCESS) { - return ldb_module_done(req, NULL, NULL, ret); - } - } - } ac = talloc_zero(req, struct aclread_context); if (ac == NULL) { return ldb_oom(ldb); @@ -865,6 +835,38 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req) } ac->attrs = req->op.search.attrs; + + /* check accessibility of base */ + if (!ldb_dn_is_null(req->op.search.base)) { + ret = dsdb_module_search_dn(module, req, &res, req->op.search.base, + acl_attrs, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED, + req); + if (ret != LDB_SUCCESS) { + return ldb_error(ldb, ret, + "acl_read: Error retrieving instanceType for base."); + } + instanceType = ldb_msg_find_attr_as_uint(res->msgs[0], + "instanceType", 0); + if (instanceType != 0 && !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) + { + /* the object has a parent, so we have to check for visibility */ + struct ldb_dn *parent_dn = ldb_dn_get_parent(req, req->op.search.base); + ret = dsdb_module_check_access_on_dn(module, + req, + parent_dn, + SEC_ADS_LIST, + NULL, req); + if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { + return ldb_module_done(req, NULL, NULL, LDB_ERR_NO_SUCH_OBJECT); + } else if (ret != LDB_SUCCESS) { + return ldb_module_done(req, NULL, NULL, ret); + } + } + } + ret = ldb_build_search_req_ex(&down_req, ldb, ac, req->op.search.base, -- 2.17.1 From 09623eada5969cee74acf8dfad0f31811a86fb3f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Oct 2020 15:10:33 +0200 Subject: [PATCH 5/8] s4:dsdb:acl_read: make use of aclread_check_object_visible() for the search base We should only have one place to do access checks. Use 'git show -w' to see the minimal diff. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531 Signed-off-by: Stefan Metzmacher Reviewed-by: Douglas Bagnall (cherry picked from commit faff8e6c89777c38443e561235073c336cfb2e9c) --- source4/dsdb/samdb/ldb_modules/acl_read.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c index dca43bcab76b..e9b3694c63cc 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_read.c +++ b/source4/dsdb/samdb/ldb_modules/acl_read.c @@ -742,7 +742,6 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req) static const char * const _all_attrs[] = { "*", NULL }; bool all_attrs = false; const char * const *attrs = NULL; - uint32_t instanceType; static const char *acl_attrs[] = { "instanceType", NULL @@ -848,22 +847,11 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req) return ldb_error(ldb, ret, "acl_read: Error retrieving instanceType for base."); } - instanceType = ldb_msg_find_attr_as_uint(res->msgs[0], - "instanceType", 0); - if (instanceType != 0 && !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) - { - /* the object has a parent, so we have to check for visibility */ - struct ldb_dn *parent_dn = ldb_dn_get_parent(req, req->op.search.base); - ret = dsdb_module_check_access_on_dn(module, - req, - parent_dn, - SEC_ADS_LIST, - NULL, req); - if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { - return ldb_module_done(req, NULL, NULL, LDB_ERR_NO_SUCH_OBJECT); - } else if (ret != LDB_SUCCESS) { - return ldb_module_done(req, NULL, NULL, ret); - } + ret = aclread_check_object_visible(ac, res->msgs[0], req); + if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { + return ldb_module_done(req, NULL, NULL, LDB_ERR_NO_SUCH_OBJECT); + } else if (ret != LDB_SUCCESS) { + return ldb_module_done(req, NULL, NULL, ret); } } -- 2.17.1 From 4cfbe8b1a7ca071fef090ad18292401a3acedcbe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 12 Oct 2020 17:59:34 +0200 Subject: [PATCH 6/8] s4:dsdb:acl_read: defer LDB_ERR_NO_SUCH_OBJECT We may need to return child objects even if the base dn is invisible. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531 Signed-off-by: Stefan Metzmacher Reviewed-by: Douglas Bagnall (cherry picked from commit e1529bedb2b6c8553e69a42537ac0cffd03af6d6) --- selftest/knownfail.d/ldap-acl-visibility | 104 ---------------------- source4/dsdb/samdb/ldb_modules/acl_read.c | 24 ++++- 2 files changed, 23 insertions(+), 105 deletions(-) diff --git a/selftest/knownfail.d/ldap-acl-visibility b/selftest/knownfail.d/ldap-acl-visibility index 6ecec6587f2b..b580b2e8caed 100644 --- a/selftest/knownfail.d/ldap-acl-visibility +++ b/selftest/knownfail.d/ldap-acl-visibility @@ -1,154 +1,50 @@ ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_CO_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_Cn_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nn_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_CO_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_Cn_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nn_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_CO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_Cn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_Cn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_Cn_nn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_CO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_CO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_CO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_CO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_Cn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_Cn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_Cn_nn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nn_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_CO_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_Cn_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nn_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_CO_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_Cn_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nn_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_CO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_Cn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_Cn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_Cn_nn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_CO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_nO ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_CO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_CO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_CO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_Cn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_Cn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_Cn_nn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nO_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nn_Cn ^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_CO_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_CO_nO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_CO_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_CO_nn_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_Cn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_Cn_nO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_Cn_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_Cn_nn_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_CO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_CO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_CO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_Cn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_Cn_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_Cn_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_nO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nO_nn_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_CO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_CO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_CO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_Cn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_Cn_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_Cn_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_nO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Allow_nn_nn_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_CO_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_CO_nO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_CO_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_CO_nn_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_Cn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_Cn_nO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_Cn_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_Cn_nn_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_CO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_CO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_CO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_Cn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_Cn_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_Cn_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_nO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nO_nn_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_CO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_CO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_CO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_Cn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_Cn_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_Cn_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_nO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_nn_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_No_Deny_nn_nn_Cn diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c index e9b3694c63cc..d3cd5d5e1bdf 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_read.c +++ b/source4/dsdb/samdb/ldb_modules/acl_read.c @@ -50,6 +50,9 @@ struct aclread_context { bool added_objectClass; bool indirsync; + bool base_invisible; + uint64_t num_entries; + /* cache on the last parent we checked in this search */ struct ldb_dn *last_parent_dn; int last_parent_check_ret; @@ -711,10 +714,21 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares) } talloc_free(tmp_ctx); + ac->num_entries++; return ldb_module_send_entry(ac->req, ret_msg, ares->controls); case LDB_REPLY_REFERRAL: return ldb_module_send_referral(ac->req, ares->referral); case LDB_REPLY_DONE: + if (ac->base_invisible && ac->num_entries == 0) { + /* + * If the base is invisible and we didn't + * returned any object, we need to return + * NO_SUCH_OBJECT. + */ + return ldb_module_done(ac->req, + NULL, NULL, + LDB_ERR_NO_SUCH_OBJECT); + } return ldb_module_done(ac->req, ares->controls, ares->response, LDB_SUCCESS); @@ -849,7 +863,15 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req) } ret = aclread_check_object_visible(ac, res->msgs[0], req); if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { - return ldb_module_done(req, NULL, NULL, LDB_ERR_NO_SUCH_OBJECT); + if (req->op.search.scope == LDB_SCOPE_BASE) { + return ldb_module_done(req, NULL, NULL, + LDB_ERR_NO_SUCH_OBJECT); + } + /* + * Defer LDB_ERR_NO_SUCH_OBJECT, + * we may return sub objects + */ + ac->base_invisible = true; } else if (ret != LDB_SUCCESS) { return ldb_module_done(req, NULL, NULL, ret); } -- 2.17.1 From 788033bd901be6b321dc770b8d2216b9a64e7228 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 6 Oct 2020 11:21:34 +0200 Subject: [PATCH 7/8] s4:dsdb:util: add dsdb_do_list_object() helper BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531 Signed-off-by: Stefan Metzmacher Reviewed-by: Douglas Bagnall (cherry picked from commit ffc0bdc6d49e88da1ee408956365da163ff3e1b2) --- source4/dsdb/samdb/ldb_modules/util.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c index 20c854f0b9ae..9519ecfa9285 100644 --- a/source4/dsdb/samdb/ldb_modules/util.c +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -1410,6 +1410,27 @@ bool dsdb_user_password_support(struct ldb_module *module, return result; } +bool dsdb_do_list_object(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_request *parent) +{ + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + bool result; + const struct ldb_val *hr_val = dsdb_module_find_dsheuristics(module, + tmp_ctx, + parent); + if (hr_val == NULL || hr_val->length < DS_HR_DOLISTOBJECT) { + result = false; + } else if (hr_val->data[DS_HR_DOLISTOBJECT -1] == '1') { + result = true; + } else { + result = false; + } + + talloc_free(tmp_ctx); + return result; +} + /* show the chain of requests, useful for debugging async requests */ -- 2.17.1 From 4989ca8617ed1cf21f4096be9e0a755986cf7c27 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 13 Oct 2020 12:43:39 +0200 Subject: [PATCH 8/8] s4:dsdb:acl_read: Implement "List Object" mode feature See [MS-ADTS] 5.1.3.3.6 Checking Object Visibility I tried to avoid any possible overhead for the common cases: - SEC_ADS_LIST (List Children) is already granted by default - fDoListObject is off by default Overhead is only added if the administrator turned on the fDoListObject feature and removed SEC_ADS_LIST (List Children) from a parent object. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531 Signed-off-by: Stefan Metzmacher Reviewed-by: Douglas Bagnall Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Wed Oct 21 08:48:02 UTC 2020 on sn-devel-184 (cherry picked from commit 7223f6453b1b38c933c9480c637ffd06d9f39b97) --- selftest/knownfail.d/ldap-acl-visibility | 50 -------------- source4/dsdb/samdb/ldb_modules/acl_read.c | 79 ++++++++++++++++++++++- 2 files changed, 78 insertions(+), 51 deletions(-) delete mode 100644 selftest/knownfail.d/ldap-acl-visibility diff --git a/selftest/knownfail.d/ldap-acl-visibility b/selftest/knownfail.d/ldap-acl-visibility deleted file mode 100644 index b580b2e8caed..000000000000 --- a/selftest/knownfail.d/ldap-acl-visibility +++ /dev/null @@ -1,50 +0,0 @@ -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_CO_nn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_Cn_nn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_CO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nO_nn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Allow_nn_nn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_CO_nn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_Cn_nn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_CO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_Cn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nO_nn -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nO_nn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_CO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_Cn_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nO_CO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nO_nO -^samba4.ldap.acl.python.*.__main__.AclVisibiltyTests.test_visibility_Do_Deny_nn_nn_nO diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c index d3cd5d5e1bdf..f3acf08c0215 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_read.c +++ b/source4/dsdb/samdb/ldb_modules/acl_read.c @@ -50,6 +50,8 @@ struct aclread_context { bool added_objectClass; bool indirsync; + bool do_list_object_initialized; + bool do_list_object; bool base_invisible; uint64_t num_entries; @@ -160,6 +162,7 @@ static int aclread_check_object_visible(struct aclread_context *ac, struct ldb_request *req) { uint32_t instanceType; + int ret; /* get the object instance type */ instanceType = ldb_msg_find_attr_as_uint(msg, @@ -171,7 +174,81 @@ static int aclread_check_object_visible(struct aclread_context *ac, return LDB_SUCCESS; } - return aclread_check_parent(ac, msg, req); + ret = aclread_check_parent(ac, msg, req); + if (ret == LDB_SUCCESS) { + /* + * SEC_ADS_LIST (List Children) alone + * on the parent is enough to make the + * object visible. + */ + return LDB_SUCCESS; + } + if (ret != LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { + return ret; + } + + if (!ac->do_list_object_initialized) { + /* + * We only call dsdb_do_list_object() once + * and only when needed in order to + * check the dSHeuristics for fDoListObject. + */ + ac->do_list_object = dsdb_do_list_object(ac->module, ac, req); + ac->do_list_object_initialized = true; + } + + if (ac->do_list_object) { + TALLOC_CTX *frame = talloc_stackframe(); + struct ldb_dn *parent_dn = NULL; + + /* + * Here we're in "List Object" mode (fDoListObject=true). + * + * If SEC_ADS_LIST (List Children) is not + * granted on the parent, we need to check if + * SEC_ADS_LIST_OBJECT (List Object) is granted + * on the parent and also on the object itself. + * + * We could optimize this similar to aclread_check_parent(), + * but that would require quite a bit of restructuring, + * so that we cache the granted access bits instead + * of just the result for 'SEC_ADS_LIST (List Children)'. + * + * But as this is the uncommon case and + * 'SEC_ADS_LIST (List Children)' is most likely granted + * on most of the objects, we'll just implement what + * we have to. + */ + + parent_dn = ldb_dn_get_parent(frame, msg->dn); + if (parent_dn == NULL) { + TALLOC_FREE(frame); + return ldb_oom(ldb_module_get_ctx(ac->module)); + } + ret = dsdb_module_check_access_on_dn(ac->module, + frame, + parent_dn, + SEC_ADS_LIST_OBJECT, + NULL, req); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(frame); + return ret; + } + ret = dsdb_module_check_access_on_dn(ac->module, + frame, + msg->dn, + SEC_ADS_LIST_OBJECT, + NULL, req); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(frame); + return ret; + } + + TALLOC_FREE(frame); + return LDB_SUCCESS; + } + + return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; } /* -- 2.17.1