CVE-2020-10700: dsdb: Do not permit the ASQ control for the GUID search in paged_results
authorAndrew Bartlett <abartlet@samba.org>
Wed, 11 Mar 2020 03:43:31 +0000 (16:43 +1300)
committerKarolin Seeger <kseeger@samba.org>
Tue, 21 Apr 2020 08:21:09 +0000 (10:21 +0200)
ASQ is a very strange control and a BASE search can return multiple results
that are NOT the requested DN, but the DNs pointed to by it!

Thanks to Andrei Popa <andrei.popa@next-gen.ro> for finding,
reporting and working with us to diagnose this issue!

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14331

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
(backported from patch for master due to selftest changes)
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
selftest/knownfail.d/asq [deleted file]
source4/dsdb/samdb/ldb_modules/paged_results.c

diff --git a/selftest/knownfail.d/asq b/selftest/knownfail.d/asq
deleted file mode 100644 (file)
index 5a4848a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-samba4.asq.python\(ad_dc_ntvfs\).__main__.ASQLDAPTest.test_asq_paged
\ No newline at end of file
index 5cad398ab616d6f4df3114daa63447593912bb03..dff247a9a5568b94c9c6cf0518dbc5da4db91985 100644 (file)
@@ -483,8 +483,14 @@ paged_results_copy_down_controls(TALLOC_CTX *mem_ctx,
                if (control->oid == NULL) {
                        continue;
                }
-               if (strncmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID,
-                   sizeof(LDB_CONTROL_PAGED_RESULTS_OID)) == 0) {
+               if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) {
+                       continue;
+               }
+               /*
+                * ASQ changes everything, do not copy it down for the
+                * per-GUID search
+                */
+               if (strcmp(control->oid, LDB_CONTROL_ASQ_OID) == 0) {
                        continue;
                }
                new_controls[j] = talloc_steal(new_controls, control);
@@ -534,21 +540,23 @@ static bool paged_controls_same(struct ldb_request *req,
 
        num_non_null_req_controls = 0;
        for (i=0; req->controls[i] != NULL; i++) {
-               if (req->controls[i]->oid != NULL) {
+               if (req->controls[i]->oid != NULL &&
+                   strcmp(req->controls[i]->oid,
+                          LDB_CONTROL_ASQ_OID) != 0) {
                        num_non_null_req_controls++;
                }
        }
 
        /* At this point we have the number of non-null entries for both
         * control lists and we know that:
-        * 1. down_controls does not contain the paged control
+        * 1. down_controls does not contain the paged control or ASQ
         *      (because paged_results_copy_down_controls excludes it)
         * 2. req->controls does contain the paged control
         *      (because this function is only called if this is true)
         * 3. down_controls is a subset of non-null controls in req->controls
         *      (checked above)
         * So to confirm that the two lists are identical except for the paged
-        * control, all we need to check is: */
+        * control and possibly ASQ, all we need to check is: */
        if (num_non_null_req_controls == num_down_controls + 1) {
                return true;
        }