CVE-2019-14847 dsdb: Correct behaviour of ranged_results when combined with dirsync
authorAndrew Bartlett <abartlet@samba.org>
Tue, 15 Oct 2019 02:44:34 +0000 (15:44 +1300)
committerKarolin Seeger <kseeger@samba.org>
Thu, 24 Oct 2019 10:34:28 +0000 (12:34 +0200)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14040

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
selftest/knownfail.d/dirsync [deleted file]
source4/dsdb/samdb/ldb_modules/dirsync.c
source4/dsdb/samdb/ldb_modules/ranged_results.c

diff --git a/selftest/knownfail.d/dirsync b/selftest/knownfail.d/dirsync
deleted file mode 100644 (file)
index bc49fe0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba4.ldap.dirsync.python\(ad_dc_ntvfs\).__main__.ExtendedDirsyncTests.test_dirsync_linkedattributes_range\(
\ No newline at end of file
index 62a66fef8d4931684b98876ec6c3b50d034a8c43..4ac5faad403dd09533be3aa7fed97d19a3c77d6c 100644 (file)
@@ -998,7 +998,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) {
@@ -1327,11 +1327,12 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req
 
        }
        /*
-        * Remove our control from the list of controls
+        * Mark dirsync control as uncritical (done)
+        *
+        * We need this so ranged_results knows how to behave with
+        * dirsync
         */
-       if (!ldb_save_controls(control, req, NULL)) {
-               return ldb_operr(ldb);
-       }
+       control->critical = false;
        dsc->schema = dsdb_get_schema(ldb, dsc);
        /*
         * At the begining we make the hypothesis that we will return a complete
index 13bf3a2d0a93f2e72846fba06b8db63d5ae91f7f..984387999979a869ac86ea9afa7861869365f11a 100644 (file)
 struct rr_context {
        struct ldb_module *module;
        struct ldb_request *req;
+       bool dirsync_in_use;
 };
 
 static struct rr_context *rr_init_context(struct ldb_module *module,
                                          struct ldb_request *req)
 {
-       struct rr_context *ac;
-
-       ac = talloc_zero(req, struct rr_context);
+       struct ldb_control *dirsync_control = NULL;
+       struct rr_context *ac = talloc_zero(req, struct rr_context);
        if (ac == NULL) {
                ldb_set_errstring(ldb_module_get_ctx(module), "Out of Memory");
                return NULL;
@@ -51,6 +51,16 @@ static struct rr_context *rr_init_context(struct ldb_module *module,
        ac->module = module;
        ac->req = req;
 
+       /*
+        * check if there's a dirsync control (as there is an
+        * interaction between these modules)
+        */
+       dirsync_control = ldb_request_get_control(req,
+                                                 LDB_CONTROL_DIRSYNC_OID);
+       if (dirsync_control != NULL) {
+               ac->dirsync_in_use = true;
+       }
+
        return ac;
 }
 
@@ -82,6 +92,15 @@ static int rr_search_callback(struct ldb_request *req, struct ldb_reply *ares)
                                        ares->response, ares->error);
        }
 
+       if (ac->dirsync_in_use) {
+               /*
+                * We return full attribute values when mixed with
+                * dirsync
+                */
+               return ldb_module_send_entry(ac->req,
+                                            ares->message,
+                                            ares->controls);
+       }
        /* LDB_REPLY_ENTRY */
 
        temp_ctx = talloc_new(ac->req);