The branch, master has been updated via 0ca46a37268 ldb: version 2.1.1 via 0b8ab020080 ldb: Add tests aimed at the SCOPE_ONELEVEL bug in particular via 3c7261c43da ldb: Fix search with scope ONE and small result sets via ec34a709570 ldb: Ensure @IDXONE modes is tested in ldb.python (apy.py) tests via 167676973b7 ldb: Add tests aimed at the SCOPE_ONELEVEL particular via 17bd63dbea7 ldb: Add tests for one-level indexes in conjunction with other indexes from a2692b64946 lib:util: Add (PULL|PUSH)_(BE|LE)_I(8|16|32|64) byterarray macros
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 0ca46a37268c8219192abc3ab5f2546a02ed8862 Author: Stefan Metzmacher <me...@samba.org> Date: Tue Feb 25 11:06:27 2020 +0100 ldb: version 2.1.1 * Bug 14270: Samba 4.11 and later give incorrect results for SCOPE_ONE searches Signed-off-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Karolin Seeger <ksee...@samba.org> Autobuild-Date(master): Tue Feb 25 12:59:02 UTC 2020 on sn-devel-184 commit 0b8ab0200805127e36eeb2affe561f3aee59604a Author: Andrew Bartlett <abart...@samba.org> Date: Wed Feb 12 16:28:01 2020 +1300 ldb: Add tests aimed at the SCOPE_ONELEVEL bug in particular BUG: https://bugzilla.samba.org/show_bug.cgi?id=14270 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 3c7261c43da491b57f50e0e64d7050d85c6b973e Author: Andrew Bartlett <abart...@samba.org> Date: Fri Feb 7 16:56:13 2020 +1300 ldb: Fix search with scope ONE and small result sets This changes the LDB behaviour in the combination of a SCOPE_ONE search and an index returning less than 10 results. After b6b5b5fe355fee2a4096e9214831cb88c7a2a4c6 the list->strict flag became set to false in all cases, rather than being left to the value set by the caller. This changes the ldb_kv_index_dn_one() code to force strict mode on success instead. Thanks to Marcus Granér, ICEYE Oy for reporting. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14270 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit ec34a7095705592279647c5046a000e0bf052d1a Author: Andrew Bartlett <abart...@samba.org> Date: Wed Feb 12 13:44:44 2020 +1300 ldb: Ensure @IDXONE modes is tested in ldb.python (apy.py) tests Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 167676973b7f1db563da04d54e8ce5668034081c Author: Andrew Bartlett <abart...@samba.org> Date: Wed Feb 12 11:45:36 2020 +1300 ldb: Add tests aimed at the SCOPE_ONELEVEL particular BUG: https://bugzilla.samba.org/show_bug.cgi?id=14270 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 17bd63dbea7f6e6358f81f0ac5b9392b2321bb32 Author: Andrew Bartlett <abart...@samba.org> Date: Mon Feb 10 14:08:29 2020 +1300 ldb: Add tests for one-level indexes in conjunction with other indexes BUG: https://bugzilla.samba.org/show_bug.cgi?id=14270 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/ldb/ABI/{ldb-2.0.5.sigs => ldb-2.1.1.sigs} | 0 ...pyldb-util-2.1.0.sigs => pyldb-util-2.1.1.sigs} | 0 lib/ldb/ldb_key_value/ldb_kv_index.c | 21 +- lib/ldb/tests/python/api.py | 499 ++++++++++++++++++++- lib/ldb/wscript | 2 +- 5 files changed, 511 insertions(+), 11 deletions(-) copy lib/ldb/ABI/{ldb-2.0.5.sigs => ldb-2.1.1.sigs} (100%) copy lib/ldb/ABI/{pyldb-util-2.1.0.sigs => pyldb-util-2.1.1.sigs} (100%) Changeset truncated at 500 lines: diff --git a/lib/ldb/ABI/ldb-2.0.5.sigs b/lib/ldb/ABI/ldb-2.1.1.sigs similarity index 100% copy from lib/ldb/ABI/ldb-2.0.5.sigs copy to lib/ldb/ABI/ldb-2.1.1.sigs diff --git a/lib/ldb/ABI/pyldb-util-2.1.0.sigs b/lib/ldb/ABI/pyldb-util-2.1.1.sigs similarity index 100% copy from lib/ldb/ABI/pyldb-util-2.1.0.sigs copy to lib/ldb/ABI/pyldb-util-2.1.1.sigs diff --git a/lib/ldb/ldb_key_value/ldb_kv_index.c b/lib/ldb/ldb_key_value/ldb_kv_index.c index 059abef6748..a7e341552ea 100644 --- a/lib/ldb/ldb_key_value/ldb_kv_index.c +++ b/lib/ldb/ldb_key_value/ldb_kv_index.c @@ -2113,16 +2113,19 @@ static int ldb_kv_index_dn_one(struct ldb_module *module, struct dn_list *list, enum key_truncation *truncation) { - /* - * Ensure we do not shortcut on intersection for this list. - * We must never be lazy and return an entry not in this - * list. This allows the index for - * SCOPE_ONELEVEL to be trusted. - */ - - list->strict = true; - return ldb_kv_index_dn_attr( + int ret = ldb_kv_index_dn_attr( module, ldb_kv, LDB_KV_IDXONE, parent_dn, list, truncation); + if (ret == LDB_SUCCESS) { + /* + * Ensure we do not shortcut on intersection for this + * list. We must never be lazy and return an entry + * not in this list. This allows the index for + * SCOPE_ONELEVEL to be trusted. + */ + + list->strict = true; + } + return ret; } /* diff --git a/lib/ldb/tests/python/api.py b/lib/ldb/tests/python/api.py index 4d55566a4ac..1d3d765e607 100755 --- a/lib/ldb/tests/python/api.py +++ b/lib/ldb/tests/python/api.py @@ -774,6 +774,60 @@ class SearchTests(LdbBaseTest): # instead use just the 16 bytes raw, which we just keep # to printable chars here for ease of handling. + self.l.add({"dn": "DC=ORG", + "name": b"org", + "objectUUID": b"0000000000abcdef"}) + self.l.add({"dn": "DC=EXAMPLE,DC=ORG", + "name": b"org", + "objectUUID": b"0000000001abcdef"}) + self.l.add({"dn": "OU=OU1,DC=EXAMPLE,DC=ORG", + "name": b"OU #1", + "x": "y", "y": "a", + "objectUUID": b"0023456789abcde3"}) + self.l.add({"dn": "OU=OU2,DC=EXAMPLE,DC=ORG", + "name": b"OU #2", + "x": "y", "y": "a", + "objectUUID": b"0023456789abcde4"}) + self.l.add({"dn": "OU=OU3,DC=EXAMPLE,DC=ORG", + "name": b"OU #3", + "x": "y", "y": "a", + "objectUUID": b"0023456789abcde5"}) + self.l.add({"dn": "OU=OU4,DC=EXAMPLE,DC=ORG", + "name": b"OU #4", + "x": "z", "y": "b", + "objectUUID": b"0023456789abcde6"}) + self.l.add({"dn": "OU=OU5,DC=EXAMPLE,DC=ORG", + "name": b"OU #5", + "x": "y", "y": "a", + "objectUUID": b"0023456789abcde7"}) + self.l.add({"dn": "OU=OU6,DC=EXAMPLE,DC=ORG", + "name": b"OU #6", + "x": "y", "y": "a", + "objectUUID": b"0023456789abcde8"}) + self.l.add({"dn": "OU=OU7,DC=EXAMPLE,DC=ORG", + "name": b"OU #7", + "x": "y", "y": "c", + "objectUUID": b"0023456789abcde9"}) + self.l.add({"dn": "OU=OU8,DC=EXAMPLE,DC=ORG", + "name": b"OU #8", + "x": "y", "y": "b", + "objectUUID": b"0023456789abcde0"}) + self.l.add({"dn": "OU=OU9,DC=EXAMPLE,DC=ORG", + "name": b"OU #9", + "x": "y", "y": "a", + "objectUUID": b"0023456789abcdea"}) + + self.l.add({"dn": "DC=EXAMPLE,DC=COM", + "name": b"org", + "objectUUID": b"0000000011abcdef"}) + + self.l.add({"dn": "DC=EXAMPLE,DC=NET", + "name": b"org", + "objectUUID": b"0000000021abcdef"}) + + self.l.add({"dn": "OU=UNIQUE,DC=EXAMPLE,DC=NET", + "objectUUID": b"0000000022abcdef"}) + self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": b"samba.org", "objectUUID": b"0123456789abcdef"}) @@ -957,6 +1011,38 @@ class SearchTests(LdbBaseTest): enum = err.args[0] self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) + def test_subtree(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE) + if hasattr(self, 'IDXCHECK'): + self.fail() + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + else: + self.assertEqual(len(res11), 25) + + def test_subtree2(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=ORG", + scope=ldb.SCOPE_SUBTREE) + if hasattr(self, 'IDXCHECK'): + self.fail() + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + else: + self.assertEqual(len(res11), 36) + def test_subtree_and(self): """Testing a search""" @@ -1141,6 +1227,86 @@ class SearchTests(LdbBaseTest): expression="(&(ou=ou10)(y=a))") self.assertEqual(len(res11), 1) + def test_subtree_unique(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(ou=ou10)") + self.assertEqual(len(res11), 1) + + def test_subtree_unique_elsewhere(self): + """Testing a search""" + + res11 = self.l.search(base="DC=EXAMPLE,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(ou=ou10)") + self.assertEqual(len(res11), 0) + + def test_subtree_unique_elsewhere2(self): + """Testing a search""" + + res11 = self.l.search(base="DC=EXAMPLE,DC=COM", + scope=ldb.SCOPE_SUBTREE, + expression="(ou=ou10)") + self.assertEqual(len(res11), 0) + + def test_subtree_unique_elsewhere2(self): + """Testing a search""" + + res11 = self.l.search(base="DC=EXAMPLE,DC=NET", + scope=ldb.SCOPE_SUBTREE, + expression="(ou=unique)") + self.assertEqual(len(res11), 1) + + def test_subtree_unique_elsewhere3(self): + """Testing a search""" + + res11 = self.l.search(base="DC=EXAMPLE,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(ou=unique)") + self.assertEqual(len(res11), 0) + + def test_subtree_unique_elsewhere4(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(ou=unique)") + self.assertEqual(len(res11), 0) + + def test_subtree_unique_elsewhere5(self): + """Testing a search""" + + res11 = self.l.search(base="DC=EXAMPLE,DC=COM", + scope=ldb.SCOPE_SUBTREE, + expression="(ou=unique)") + self.assertEqual(len(res11), 0) + + def test_subtree_unique_elsewhere6(self): + """Testing a search""" + + res11 = self.l.search(base="DC=EXAMPLE,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(ou=unique)") + self.assertEqual(len(res11), 0) + + def test_subtree_unique_here(self): + """Testing a search""" + + res11 = self.l.search(base="OU=UNIQUE,DC=EXAMPLE,DC=NET", + scope=ldb.SCOPE_SUBTREE, + expression="(ou=unique)") + self.assertEqual(len(res11), 1) + + def test_subtree_unique(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(ou=ou10)") + self.assertEqual(len(res11), 1) + def test_subtree_and_none(self): """Testing a search""" @@ -1165,6 +1331,185 @@ class SearchTests(LdbBaseTest): expression="(@IDXONE=DC=SAMBA,DC=ORG)") self.assertEqual(len(res11), 0) + def test_onelevel(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL) + if hasattr(self, 'IDXCHECK') \ + and not hasattr(self, 'IDXONE'): + self.fail() + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + else: + self.assertEqual(len(res11), 24) + + def test_onelevel2(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=EXAMPLE,DC=ORG", + scope=ldb.SCOPE_ONELEVEL) + if hasattr(self, 'IDXCHECK') \ + and not hasattr(self, 'IDXONE'): + self.fail() + self.fail() + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + else: + self.assertEqual(len(res11), 9) + + def test_onelevel_and_or(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(|(x=z)(y=b))(x=x)(y=c))") + self.assertEqual(len(res11), 0) + + def test_onelevel_and_or2(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(x=x)(y=c)(|(x=z)(y=b)))") + self.assertEqual(len(res11), 0) + + def test_onelevel_and_or3(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(|(ou=ou11)(ou=ou10))(|(x=y)(y=b)(y=c)))") + self.assertEqual(len(res11), 2) + + def test_onelevel_and_or4(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(|(x=y)(y=b)(y=c))(|(ou=ou11)(ou=ou10)))") + self.assertEqual(len(res11), 2) + + def test_onelevel_and_or5(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(|(x=y)(y=b)(y=c))(ou=ou11))") + self.assertEqual(len(res11), 1) + + def test_onelevel_or_and(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(|(x=x)(y=c)(&(x=z)(y=b)))") + self.assertEqual(len(res11), 10) + + def test_onelevel_large_and_unique(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(ou=ou10)(y=a))") + self.assertEqual(len(res11), 1) + + def test_onelevel_unique(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(ou=ou10)") + self.assertEqual(len(res11), 1) + + def test_onelevel_unique_elsewhere(self): + """Testing a search""" + + res11 = self.l.search(base="DC=EXAMPLE,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(ou=ou10)") + self.assertEqual(len(res11), 0) + + def test_onelevel_unique_elsewhere2(self): + """Testing a search""" + + res11 = self.l.search(base="DC=EXAMPLE,DC=COM", + scope=ldb.SCOPE_ONELEVEL, + expression="(ou=ou10)") + self.assertEqual(len(res11), 0) + + def test_onelevel_unique_elsewhere2(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=EXAMPLE,DC=NET", + scope=ldb.SCOPE_ONELEVEL, + expression="(ou=unique)") + self.assertEqual(len(res11), 1) + + def test_onelevel_unique_elsewhere3(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=EXAMPLE,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(ou=unique)") + self.assertEqual(len(res11), 0) + + def test_onelevel_unique_elsewhere4(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(ou=unique)") + self.assertEqual(len(res11), 0) + + def test_onelevel_unique_elsewhere5(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=EXAMPLE,DC=COM", + scope=ldb.SCOPE_ONELEVEL, + expression="(ou=unique)") + self.assertEqual(len(res11), 0) + + def test_onelevel_unique_here(self): + """Testing a search""" + + res11 = self.l.search(base="OU=UNIQUE,DC=EXAMPLE,DC=NET", + scope=ldb.SCOPE_ONELEVEL, + expression="(ou=unique)") + self.assertEqual(len(res11), 0) + + def test_onelevel_and_none(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(ou=ouX)(y=a))") + self.assertEqual(len(res11), 0) + + def test_onelevel_and_idx_record(self): + """Testing a search against the index record""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(@IDXDN=DC=SAMBA,DC=ORG)") + self.assertEqual(len(res11), 0) + + def test_onelevel_and_idxone_record(self): + """Testing a search against the index record""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(@IDXONE=DC=SAMBA,DC=ORG)") + self.assertEqual(len(res11), 0) + def test_subtree_unindexable(self): """Testing a search""" @@ -1184,6 +1529,158 @@ class SearchTests(LdbBaseTest): self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) self.assertIn(estr, "ldb FULL SEARCH disabled") + def test_onelevel_only_and_or(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(|(x=z)(y=b))(x=x)(y=c))") + self.assertEqual(len(res11), 0) + + def test_onelevel_only_and_or2(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(x=x)(y=c)(|(x=z)(y=b)))") + self.assertEqual(len(res11), 0) + + def test_onelevel_only_and_or3(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(|(ou=ou11)(ou=ou10))(|(x=y)(y=b)(y=c)))") + self.assertEqual(len(res11), 0) + + def test_onelevel_only_and_or4(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(|(x=y)(y=b)(y=c))(|(ou=ou11)(ou=ou10)))") + self.assertEqual(len(res11), 0) + + def test_onelevel_only_and_or5(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(|(x=y)(y=b)(y=c))(ou=ou11))") + self.assertEqual(len(res11), 0) + + def test_onelevel_only_or_and(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(|(x=x)(y=c)(&(x=z)(y=b)))") + self.assertEqual(len(res11), 0) + + def test_onelevel_only_large_and_unique(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(ou=ou10)(y=a))") + self.assertEqual(len(res11), 0) + + def test_onelevel_only_unique(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(ou=ou10)") + self.assertEqual(len(res11), 0) + + def test_onelevel_only_unique2(self): + """Testing a search""" + + res11 = self.l.search(base="DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(ou=unique)") + self.assertEqual(len(res11), 0) + + def test_onelevel_only_and_none(self): + """Testing a search (showing that onelevel is not subtree)""" + + res11 = self.l.search(base="DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(ou=ouX)(y=a))") -- Samba Shared Repository