s4:dirsync: fix interaction of dirsync and extended_dn controls
authorStefan Metzmacher <metze@samba.org>
Fri, 4 Oct 2019 12:57:40 +0000 (14:57 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 24 Oct 2019 11:06:58 +0000 (11:06 +0000)
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 <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Thu Oct 24 11:06:58 UTC 2019 on sn-devel-184

selftest/knownfail.d/dirsync_extended_dn [deleted file]
source4/dsdb/samdb/ldb_modules/dirsync.c

diff --git a/selftest/knownfail.d/dirsync_extended_dn b/selftest/knownfail.d/dirsync_extended_dn
deleted file mode 100644 (file)
index 0ef6ea5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba4.ldap.dirsync.python.*.__main__.ExtendedDirsyncTests.test_dirsync_extended_dn
index 60e8eae464253c78aa8b1575b50abe5d5f61f559..87da4a6a0ec47a8df613eb78bfe1a1f9a4a4eb1d 100644 (file)
@@ -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;
@@ -1014,7 +1017,7 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req
        }
 
        /*
-        * check if there's an extended dn control
+        * check if there's a dirsync control
         */
        control = ldb_request_get_control(req, LDB_CONTROL_DIRSYNC_OID);
        if (control == NULL) {
@@ -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;