From 152a2d033eb83ada10a9e465fdca77fdb8e5e054 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Oct 2019 12:12:32 +0200 Subject: [PATCH 1/2] s4:tests/dirsync: add tests for dirsync with extended_dn This demonstrates a problems that the extended_dn returned by the dirsync module always uses the SDDL format for GUID/SID components. Azure AD connect reports discovery errors: reference-value-not-ldap-conformant for attributes member and manager. The key is that it sends the LDAP_SERVER_EXTENDED_DN_OID without an ExtendedDNRequestValue blob, which means the flag value should be treated as 0 and the HEX string format should be used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14153 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 6d43d82b49c8cd47da2f1489fe8b52d5a873a19c) --- selftest/knownfail.d/dirsync_extended_dn | 1 + source4/dsdb/tests/python/dirsync.py | 31 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 selftest/knownfail.d/dirsync_extended_dn diff --git a/selftest/knownfail.d/dirsync_extended_dn b/selftest/knownfail.d/dirsync_extended_dn new file mode 100644 index 000000000000..0ef6ea563913 --- /dev/null +++ b/selftest/knownfail.d/dirsync_extended_dn @@ -0,0 +1 @@ +^samba4.ldap.dirsync.python.*.__main__.ExtendedDirsyncTests.test_dirsync_extended_dn diff --git a/source4/dsdb/tests/python/dirsync.py b/source4/dsdb/tests/python/dirsync.py index 78117bc364b8..0a22ac4239af 100755 --- a/source4/dsdb/tests/python/dirsync.py +++ b/source4/dsdb/tests/python/dirsync.py @@ -681,6 +681,37 @@ class ExtendedDirsyncTests(SimpleDirsyncTests): self.assertEqual(res[0].get("member;range=1-1"), None) self.assertEqual(len(res[0].get("member;range=0-0")), 2) + def test_dirsync_extended_dn(self): + """Check that dirsync works together with the extended_dn control""" + # Let's search for members + self.ldb_simple = self.get_ldb_connection(self.simple_user, self.user_pass) + res = self.ldb_simple.search(self.base_dn, + expression="(name=Administrators)", + controls=["dirsync:1:1:1"]) + + self.assertTrue(len(res[0].get("member")) > 0) + size = len(res[0].get("member")) + + resEX1 = self.ldb_simple.search(self.base_dn, + expression="(name=Administrators)", + controls=["dirsync:1:1:1","extended_dn:1:1"]) + self.assertTrue(len(resEX1[0].get("member")) > 0) + sizeEX1 = len(resEX1[0].get("member")) + self.assertEqual(sizeEX1, size) + self.assertIn(res[0]["member"][0], resEX1[0]["member"][0]) + self.assertIn(b"; 0) + sizeEX0 = len(resEX0[0].get("member")) + self.assertEqual(sizeEX0, size) + self.assertIn(res[0]["member"][0], resEX0[0]["member"][0]) + self.assertIn(b"; Date: Fri, 4 Oct 2019 14:57:40 +0200 Subject: [PATCH 2/2] s4:dirsync: fix interaction of dirsync and extended_dn controls Azure AD connect reports discovery errors: reference-value-not-ldap-conformant for attributes member and manager. The key is that it sends the LDAP_SERVER_EXTENDED_DN_OID without an ExtendedDNRequestValue blob, which means the flag value should be treated as 0 and the HEX string format should be used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14153 RN: Prevent azure ad connect from reporting discovery errors: reference-value-not-ldap-conformant Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Thu Oct 24 11:06:58 UTC 2019 on sn-devel-184 (cherry picked from commit d0f566c4ad32d69a1cf896e2dde56fc2489bb7fc) --- selftest/knownfail.d/dirsync_extended_dn | 1 - source4/dsdb/samdb/ldb_modules/dirsync.c | 19 +++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) delete mode 100644 selftest/knownfail.d/dirsync_extended_dn diff --git a/selftest/knownfail.d/dirsync_extended_dn b/selftest/knownfail.d/dirsync_extended_dn deleted file mode 100644 index 0ef6ea563913..000000000000 --- a/selftest/knownfail.d/dirsync_extended_dn +++ /dev/null @@ -1 +0,0 @@ -^samba4.ldap.dirsync.python.*.__main__.ExtendedDirsyncTests.test_dirsync_extended_dn diff --git a/source4/dsdb/samdb/ldb_modules/dirsync.c b/source4/dsdb/samdb/ldb_modules/dirsync.c index 96cec7774cf0..dfa72a1d203f 100644 --- a/source4/dsdb/samdb/ldb_modules/dirsync.c +++ b/source4/dsdb/samdb/ldb_modules/dirsync.c @@ -51,6 +51,7 @@ struct dirsync_context { uint64_t fromreqUSN; uint32_t cursor_size; bool noextended; + int extended_type; bool linkIncrVal; bool localonly; bool partial; @@ -481,7 +482,8 @@ skip: } ldb_dn_extended_filter(dn->dn, myaccept); - dn_ln = ldb_dn_get_extended_linearized(dn, dn->dn, 1); + dn_ln = dsdb_dn_get_extended_linearized(dn, dn, + dsc->extended_type); if (dn_ln == NULL) { talloc_free(dn); @@ -998,6 +1000,7 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req struct ldb_control *control; struct ldb_result *acl_res; struct ldb_dirsync_control *dirsync_ctl; + struct ldb_control *extended = NULL; struct ldb_request *down_req; struct dirsync_context *dsc; struct ldb_context *ldb; @@ -1229,7 +1232,19 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req dsc->nbDefaultAttrs = 3; } - if (!ldb_request_get_control(req, LDB_CONTROL_EXTENDED_DN_OID)) { + /* check if there's an extended dn control */ + extended = ldb_request_get_control(req, LDB_CONTROL_EXTENDED_DN_OID); + if (extended != NULL) { + struct ldb_extended_dn_control *extended_ctrl = NULL; + + if (extended->data != NULL) { + extended_ctrl = talloc_get_type(extended->data, + struct ldb_extended_dn_control); + } + if (extended_ctrl != NULL) { + dsc->extended_type = extended_ctrl->type; + } + } else { ret = ldb_request_add_control(req, LDB_CONTROL_EXTENDED_DN_OID, false, NULL); if (ret != LDB_SUCCESS) { return ret; -- 2.17.1