From 0a49dac5c95d97ea0dff3233dd58baf3c31ab745 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 e7979a7e3abd..38f65f17e35e 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 f6310efc4dcada564be4e54842509887da23f1b6 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 6c46a6130dfc..815422c26772 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 0b74b6c89840..3a903a7eee08 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -1093,7 +1093,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 a27f9c14d880d3d66d0ddd35206a8741c04dadab 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 bbcca7b63984d63d396e8b5d99326c8890b520a9 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 a13f9510ddde3baf8af12d363945e3be7b33191d 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 61d497fdbf6cd0ae39037b0cf3e1fa296630ab9f 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 f653f565f81777023d0395b9114db01256b1d816 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 17dcf81f5075112868d8ded1ed134c99a38de393 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