!17 fix CVE-2020-10730 CVE-2020-10745 CVE-2020-10760 CVE-2020-14303
Merge pull request !17 from yu_boyun/openEuler-20.03-LTS
This commit is contained in:
commit
12efca8953
35
CVE-2020-10730-1.patch
Normal file
35
CVE-2020-10730-1.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From b8628cb44766ac4c4817b1a50f09ca316425bd8b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Date: Tue, 5 May 2020 12:54:59 +1200
|
||||||
|
Subject: [PATCH 01/22] CVE-2020-10730: vlv: Use strcmp(), not strncmp()
|
||||||
|
checking the NULL terminated control OIDs
|
||||||
|
|
||||||
|
The end result is the same, as sizeof() includes the trailing NUL, but this
|
||||||
|
avoids having to think about that.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14364
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
source4/dsdb/samdb/ldb_modules/vlv_pagination.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
index 980177cb05e..31e64b4bd78 100644
|
||||||
|
--- a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
+++ b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
@@ -682,8 +682,8 @@ vlv_copy_down_controls(TALLOC_CTX *mem_ctx, struct ldb_control **controls)
|
||||||
|
if (control->oid == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- if (strncmp(control->oid, LDB_CONTROL_VLV_REQ_OID, sizeof(LDB_CONTROL_VLV_REQ_OID)) == 0 ||
|
||||||
|
- strncmp(control->oid, LDB_CONTROL_SERVER_SORT_OID, sizeof(LDB_CONTROL_SERVER_SORT_OID)) == 0) {
|
||||||
|
+ if (strcmp(control->oid, LDB_CONTROL_VLV_REQ_OID) == 0 ||
|
||||||
|
+ strcmp(control->oid, LDB_CONTROL_SERVER_SORT_OID) == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
new_controls[j] = talloc_steal(new_controls, control);
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
49
CVE-2020-10730-10.patch
Normal file
49
CVE-2020-10730-10.patch
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
From 303947c58abf9311a666fe63ebd4ce26655ff36e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
Date: Wed, 13 May 2020 10:56:56 +1200
|
||||||
|
Subject: [PATCH 10/22] CVE-2020-10730: lib ldb: Check if
|
||||||
|
ldb_lock_backend_callback called twice
|
||||||
|
|
||||||
|
Prevent use after free issues if ldb_lock_backend_callback is called
|
||||||
|
twice, usually due to ldb_module_done being called twice. This can happen if a
|
||||||
|
module ignores the return value from function a function that calls
|
||||||
|
ldb_module_done as part of it's error handling.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14364
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
---
|
||||||
|
lib/ldb/common/ldb.c | 9 ++++++++-
|
||||||
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/lib/ldb/common/ldb.c b/lib/ldb/common/ldb.c
|
||||||
|
index 95e9138a56b..2d0926ffaf9 100644
|
||||||
|
--- a/lib/ldb/common/ldb.c
|
||||||
|
+++ b/lib/ldb/common/ldb.c
|
||||||
|
@@ -1018,6 +1018,13 @@ static int ldb_lock_backend_callback(struct ldb_request *req,
|
||||||
|
struct ldb_db_lock_context *lock_context;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
+ if (req->context == NULL) {
|
||||||
|
+ /*
|
||||||
|
+ * The usual way to get here is to ignore the return codes
|
||||||
|
+ * and continuing processing after an error.
|
||||||
|
+ */
|
||||||
|
+ abort();
|
||||||
|
+ }
|
||||||
|
lock_context = talloc_get_type(req->context,
|
||||||
|
struct ldb_db_lock_context);
|
||||||
|
|
||||||
|
@@ -1032,7 +1039,7 @@ static int ldb_lock_backend_callback(struct ldb_request *req,
|
||||||
|
* If this is a LDB_REPLY_DONE or an error, unlock the
|
||||||
|
* DB by calling the destructor on this context
|
||||||
|
*/
|
||||||
|
- talloc_free(lock_context);
|
||||||
|
+ TALLOC_FREE(req->context);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
46
CVE-2020-10730-2.patch
Normal file
46
CVE-2020-10730-2.patch
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
From 2041c05d9b41fb0255c3492d118628c14a0c4b3d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Date: Tue, 5 May 2020 12:55:57 +1200
|
||||||
|
Subject: [PATCH 02/22] CVE-2020-10730: vlv: Do not re-ASQ search the results
|
||||||
|
of an ASQ search with VLV
|
||||||
|
|
||||||
|
This is a silly combination, but at least try and keep the results sensible
|
||||||
|
and avoid a double-dereference.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14364
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
source4/dsdb/samdb/ldb_modules/vlv_pagination.c | 11 +++++++++++
|
||||||
|
1 file changed, 11 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
index 31e64b4bd78..d58a62482c9 100644
|
||||||
|
--- a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
+++ b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
@@ -682,10 +682,21 @@ vlv_copy_down_controls(TALLOC_CTX *mem_ctx, struct ldb_control **controls)
|
||||||
|
if (control->oid == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+ /*
|
||||||
|
+ * Do not re-use VLV, nor the server-sort, both are
|
||||||
|
+ * already handled here.
|
||||||
|
+ */
|
||||||
|
if (strcmp(control->oid, LDB_CONTROL_VLV_REQ_OID) == 0 ||
|
||||||
|
strcmp(control->oid, LDB_CONTROL_SERVER_SORT_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);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
57
CVE-2020-10730-3.patch
Normal file
57
CVE-2020-10730-3.patch
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
From cf10f9b9a9a2f94afc526995a4034c1c6f05f5b4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Date: Tue, 5 May 2020 13:16:48 +1200
|
||||||
|
Subject: [PATCH 03/22] CVE-2020-10730: selftest: Add test to confirm VLV
|
||||||
|
interaction with ASQ
|
||||||
|
|
||||||
|
Tested against Windows 1709.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14364
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
source4/dsdb/tests/python/asq.py | 27 +++++++++++++++++++++++++++
|
||||||
|
1 file changed, 27 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/source4/dsdb/tests/python/asq.py b/source4/dsdb/tests/python/asq.py
|
||||||
|
index a32c9f40cd3..1c93a45f131 100644
|
||||||
|
--- a/source4/dsdb/tests/python/asq.py
|
||||||
|
+++ b/source4/dsdb/tests/python/asq.py
|
||||||
|
@@ -162,6 +162,33 @@ class ASQLDAPTest(samba.tests.TestCase):
|
||||||
|
self.assertIn(ldb.Dn(self.ldb, str(group)),
|
||||||
|
self.members)
|
||||||
|
|
||||||
|
+ def test_asq_vlv(self):
|
||||||
|
+ """Testing ASQ behaviour with VLV set.
|
||||||
|
+
|
||||||
|
+ ASQ is very strange, it turns a BASE search into a search for
|
||||||
|
+ all the objects pointed to by the specified attribute,
|
||||||
|
+ returning multiple entries!
|
||||||
|
+
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ sort_control = "server_sort:1:0:cn"
|
||||||
|
+
|
||||||
|
+ msgs = self.ldb.search(base=self.top_dn,
|
||||||
|
+ scope=ldb.SCOPE_BASE,
|
||||||
|
+ attrs=["objectGUID", "cn", "member"],
|
||||||
|
+ controls=["asq:1:member",
|
||||||
|
+ sort_control,
|
||||||
|
+ "vlv:1:20:20:11:0"])
|
||||||
|
+
|
||||||
|
+ self.assertEqual(len(msgs), 20)
|
||||||
|
+
|
||||||
|
+ for msg in msgs:
|
||||||
|
+ self.assertNotEqual(msg.dn, self.top_dn)
|
||||||
|
+ self.assertIn(msg.dn, self.members2)
|
||||||
|
+ for group in msg["member"]:
|
||||||
|
+ self.assertIn(ldb.Dn(self.ldb, str(group)),
|
||||||
|
+ self.members)
|
||||||
|
+
|
||||||
|
if "://" not in url:
|
||||||
|
if os.path.isfile(url):
|
||||||
|
url = "tdb://%s" % url
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
53
CVE-2020-10730-4.patch
Normal file
53
CVE-2020-10730-4.patch
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
From 3fd7ce69761fd2e21a85101772196aafc5ae57df Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Date: Tue, 5 May 2020 16:34:11 +1200
|
||||||
|
Subject: [PATCH 04/22] CVE-2020-10730: vlv: Another workaround for mixing ASQ
|
||||||
|
and VLV
|
||||||
|
|
||||||
|
This is essentially an alternative patch, but without the correct
|
||||||
|
behaviour. Instead this just avoids a segfault.
|
||||||
|
|
||||||
|
Included in case we have something simialr again in
|
||||||
|
another module.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14364
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
.../dsdb/samdb/ldb_modules/vlv_pagination.c | 19 +++++++++++++++----
|
||||||
|
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
index d58a62482c9..720b5e95638 100644
|
||||||
|
--- a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
+++ b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
@@ -442,10 +442,21 @@ static int vlv_results(struct vlv_context *ac)
|
||||||
|
ret = vlv_search_by_dn_guid(ac->module, ac, &result, guid,
|
||||||
|
ac->req->op.search.attrs);
|
||||||
|
|
||||||
|
- if (ret == LDAP_NO_SUCH_OBJECT) {
|
||||||
|
- /* The thing isn't there, which we quietly
|
||||||
|
- ignore and go on to send an extra one
|
||||||
|
- instead. */
|
||||||
|
+ if (ret == LDAP_NO_SUCH_OBJECT
|
||||||
|
+ || result->count != 1) {
|
||||||
|
+ /*
|
||||||
|
+ * The thing isn't there, which we quietly
|
||||||
|
+ * ignore and go on to send an extra one
|
||||||
|
+ * instead.
|
||||||
|
+ *
|
||||||
|
+ * result->count == 0 or > 1 can only
|
||||||
|
+ * happen if ASQ (which breaks all the
|
||||||
|
+ * rules) is somehow invoked (as this
|
||||||
|
+ * is a BASE search).
|
||||||
|
+ *
|
||||||
|
+ * (We skip the ASQ cookie for the
|
||||||
|
+ * GUID searches)
|
||||||
|
+ */
|
||||||
|
if (last_i < ac->store->num_entries - 1) {
|
||||||
|
last_i++;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
92
CVE-2020-10730-5.patch
Normal file
92
CVE-2020-10730-5.patch
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
From 01cce3d1fc69f04cdc237425b2f2ad1f2ac973d4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Date: Wed, 6 May 2020 16:19:01 +1200
|
||||||
|
Subject: [PATCH 05/22] CVE-2020-10730: selftest: Add test to show that VLV and
|
||||||
|
paged_results are incompatible
|
||||||
|
|
||||||
|
As tested against Windows Server 1709
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14364
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
source4/dsdb/tests/python/asq.py | 27 +++++++++++++++++++++++++++
|
||||||
|
source4/dsdb/tests/python/vlv.py | 23 +++++++++++++++++++++++
|
||||||
|
2 files changed, 50 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/source4/dsdb/tests/python/asq.py b/source4/dsdb/tests/python/asq.py
|
||||||
|
index 1c93a45f131..33973d66c37 100644
|
||||||
|
--- a/source4/dsdb/tests/python/asq.py
|
||||||
|
+++ b/source4/dsdb/tests/python/asq.py
|
||||||
|
@@ -189,6 +189,33 @@ class ASQLDAPTest(samba.tests.TestCase):
|
||||||
|
self.assertIn(ldb.Dn(self.ldb, str(group)),
|
||||||
|
self.members)
|
||||||
|
|
||||||
|
+ def test_asq_vlv_paged(self):
|
||||||
|
+ """Testing ASQ behaviour with VLV and paged_results set.
|
||||||
|
+
|
||||||
|
+ ASQ is very strange, it turns a BASE search into a search for
|
||||||
|
+ all the objects pointed to by the specified attribute,
|
||||||
|
+ returning multiple entries!
|
||||||
|
+
|
||||||
|
+ Thankfully combining both of these gives
|
||||||
|
+ unavailable-critical-extension against Windows 1709
|
||||||
|
+
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ sort_control = "server_sort:1:0:cn"
|
||||||
|
+
|
||||||
|
+ try:
|
||||||
|
+ msgs = self.ldb.search(base=self.top_dn,
|
||||||
|
+ scope=ldb.SCOPE_BASE,
|
||||||
|
+ attrs=["objectGUID", "cn", "member"],
|
||||||
|
+ controls=["asq:1:member",
|
||||||
|
+ sort_control,
|
||||||
|
+ "vlv:1:20:20:11:0",
|
||||||
|
+ "paged_results:1:1024"])
|
||||||
|
+ self.fail("should have failed with LDAP_UNAVAILABLE_CRITICAL_EXTENSION")
|
||||||
|
+ except ldb.LdbError as e:
|
||||||
|
+ (enum, estr) = e.args
|
||||||
|
+ self.assertEqual(enum, ldb.ERR_UNSUPPORTED_CRITICAL_EXTENSION)
|
||||||
|
+
|
||||||
|
if "://" not in url:
|
||||||
|
if os.path.isfile(url):
|
||||||
|
url = "tdb://%s" % url
|
||||||
|
diff --git a/source4/dsdb/tests/python/vlv.py b/source4/dsdb/tests/python/vlv.py
|
||||||
|
index 2efcaa5e7a3..f3c603e3a39 100644
|
||||||
|
--- a/source4/dsdb/tests/python/vlv.py
|
||||||
|
+++ b/source4/dsdb/tests/python/vlv.py
|
||||||
|
@@ -1644,6 +1644,29 @@ class PagedResultsTests(TestsWithUserOU):
|
||||||
|
page_size=len(self.users))
|
||||||
|
self.assertEqual(results, set_2[ps*2:])
|
||||||
|
|
||||||
|
+ def test_vlv_paged(self):
|
||||||
|
+ """Testing behaviour with VLV and paged_results set.
|
||||||
|
+
|
||||||
|
+ A strange combination, certainly
|
||||||
|
+
|
||||||
|
+ Thankfully combining both of these gives
|
||||||
|
+ unavailable-critical-extension against Windows 1709
|
||||||
|
+
|
||||||
|
+ """
|
||||||
|
+ sort_control = "server_sort:1:0:cn"
|
||||||
|
+
|
||||||
|
+ try:
|
||||||
|
+ msgs = self.ldb.search(base=self.base_dn,
|
||||||
|
+ scope=ldb.SCOPE_SUBTREE,
|
||||||
|
+ attrs=["objectGUID", "cn", "member"],
|
||||||
|
+ controls=["vlv:1:20:20:11:0",
|
||||||
|
+ sort_control,
|
||||||
|
+ "paged_results:1:1024"])
|
||||||
|
+ self.fail("should have failed with LDAP_UNAVAILABLE_CRITICAL_EXTENSION")
|
||||||
|
+ except ldb.LdbError as e:
|
||||||
|
+ (enum, estr) = e.args
|
||||||
|
+ self.assertEqual(enum, ldb.ERR_UNSUPPORTED_CRITICAL_EXTENSION)
|
||||||
|
+
|
||||||
|
|
||||||
|
if "://" not in host:
|
||||||
|
if os.path.isfile(host):
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
35
CVE-2020-10730-6.patch
Normal file
35
CVE-2020-10730-6.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From c7608e43c933d9a33d94e32371080e64cc1d4fcb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Date: Wed, 6 May 2020 17:05:30 +1200
|
||||||
|
Subject: [PATCH 06/22] CVE-2020-10730: dsdb: Fix crash when vlv and
|
||||||
|
paged_results are combined
|
||||||
|
|
||||||
|
The GUID is not returned in the DN for some reason in this (to be banned)
|
||||||
|
combination.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14364
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
source4/dsdb/samdb/ldb_modules/paged_results.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/source4/dsdb/samdb/ldb_modules/paged_results.c b/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
index dc211dd18ce..f720a2e4337 100644
|
||||||
|
--- a/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
+++ b/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
@@ -416,6 +416,10 @@ static int paged_search_callback(struct ldb_request *req,
|
||||||
|
|
||||||
|
guid_blob = ldb_dn_get_extended_component(ares->message->dn,
|
||||||
|
"GUID");
|
||||||
|
+ if (guid_blob == NULL) {
|
||||||
|
+ return ldb_module_done(ac->req, NULL, NULL,
|
||||||
|
+ LDB_ERR_OPERATIONS_ERROR);
|
||||||
|
+ }
|
||||||
|
status = GUID_from_ndr_blob(guid_blob, &guid);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
return ldb_module_done(ac->req, NULL, NULL,
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
48
CVE-2020-10730-7.patch
Normal file
48
CVE-2020-10730-7.patch
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
From 0c8cd0a9fbd9d17c1d7219f977ca35f88f0a2ea3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Date: Wed, 6 May 2020 16:18:19 +1200
|
||||||
|
Subject: [PATCH 07/22] CVE-2020-10730: dsdb: Ban the combination of
|
||||||
|
paged_results and VLV
|
||||||
|
|
||||||
|
This (two different paging controls) makes no sense and fails against
|
||||||
|
Windows Server 1709.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14364
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
source4/dsdb/samdb/ldb_modules/paged_results.c | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/source4/dsdb/samdb/ldb_modules/paged_results.c b/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
index f720a2e4337..aa49a6e4aa5 100644
|
||||||
|
--- a/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
+++ b/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
@@ -589,6 +589,7 @@ static int paged_search(struct ldb_module *module, struct ldb_request *req)
|
||||||
|
{
|
||||||
|
struct ldb_context *ldb;
|
||||||
|
struct ldb_control *control;
|
||||||
|
+ struct ldb_control *vlv_control;
|
||||||
|
struct private_data *private_data;
|
||||||
|
struct ldb_paged_control *paged_ctrl;
|
||||||
|
struct ldb_request *search_req;
|
||||||
|
@@ -612,6 +613,15 @@ static int paged_search(struct ldb_module *module, struct ldb_request *req)
|
||||||
|
private_data = talloc_get_type(ldb_module_get_private(module),
|
||||||
|
struct private_data);
|
||||||
|
|
||||||
|
+ vlv_control = ldb_request_get_control(req, LDB_CONTROL_VLV_REQ_OID);
|
||||||
|
+ if (vlv_control != NULL) {
|
||||||
|
+ /*
|
||||||
|
+ * VLV and paged_results are not allowed at the same
|
||||||
|
+ * time
|
||||||
|
+ */
|
||||||
|
+ return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ac = talloc_zero(req, struct paged_context);
|
||||||
|
if (ac == NULL) {
|
||||||
|
ldb_set_errstring(ldb, "Out of Memory");
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
138
CVE-2020-10730-8.patch
Normal file
138
CVE-2020-10730-8.patch
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
From dcf713038ff10e35a74ee255f1634be81103e360 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
Date: Mon, 18 May 2020 12:36:57 +1200
|
||||||
|
Subject: [PATCH 08/22] CVE-2020-10730: s4 dsdb paged_results: Prevent repeat
|
||||||
|
call of ldb_module_done
|
||||||
|
|
||||||
|
Check the return code from paged_results, if it is not LDB_SUCCESS
|
||||||
|
ldb_module_done has already been called, and SHOULD NOT be called again.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14364
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
---
|
||||||
|
.../dsdb/samdb/ldb_modules/paged_results.c | 43 +++++++++++++++----
|
||||||
|
1 file changed, 34 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/source4/dsdb/samdb/ldb_modules/paged_results.c b/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
index aa49a6e4aa5..735883e8802 100644
|
||||||
|
--- a/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
+++ b/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
@@ -237,14 +237,16 @@ static int paged_search_by_dn_guid(struct ldb_module *module,
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int paged_results(struct paged_context *ac)
|
||||||
|
+static int paged_results(struct paged_context *ac, struct ldb_reply *ares)
|
||||||
|
{
|
||||||
|
struct ldb_paged_control *paged;
|
||||||
|
unsigned int i, num_ctrls;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (ac->store == NULL) {
|
||||||
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req, ac->controls, ares->response, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ac->store->last_i < ac->store->num_entries && ac->size > 0) {
|
||||||
|
@@ -273,12 +275,17 @@ static int paged_results(struct paged_context *ac)
|
||||||
|
instead. */
|
||||||
|
continue;
|
||||||
|
} else if (ret != LDB_SUCCESS) {
|
||||||
|
- return ret;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req, ac->controls, ares->response, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ldb_module_send_entry(ac->req, result->msgs[0],
|
||||||
|
NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
+ /*
|
||||||
|
+ * ldb_module_send_entry will have called
|
||||||
|
+ * ldb_module_done if an error occurred.
|
||||||
|
+ */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -289,6 +296,10 @@ static int paged_results(struct paged_context *ac)
|
||||||
|
*/
|
||||||
|
ret = send_referrals(ac->store, ac->req);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
+ /*
|
||||||
|
+ * send_referrals will have called ldb_module_done
|
||||||
|
+ * if an error occurred.
|
||||||
|
+ */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -305,7 +316,9 @@ static int paged_results(struct paged_context *ac)
|
||||||
|
|
||||||
|
ac->controls = talloc_array(ac, struct ldb_control *, num_ctrls +1);
|
||||||
|
if (ac->controls == NULL) {
|
||||||
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req, ac->controls, ares->response, ret);
|
||||||
|
}
|
||||||
|
ac->controls[num_ctrls] = NULL;
|
||||||
|
|
||||||
|
@@ -316,20 +329,26 @@ static int paged_results(struct paged_context *ac)
|
||||||
|
|
||||||
|
ac->controls[i] = talloc(ac->controls, struct ldb_control);
|
||||||
|
if (ac->controls[i] == NULL) {
|
||||||
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req, ac->controls, ares->response, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ac->controls[i]->oid = talloc_strdup(ac->controls[i],
|
||||||
|
LDB_CONTROL_PAGED_RESULTS_OID);
|
||||||
|
if (ac->controls[i]->oid == NULL) {
|
||||||
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req, ac->controls, ares->response, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ac->controls[i]->critical = 0;
|
||||||
|
|
||||||
|
paged = talloc(ac->controls[i], struct ldb_paged_control);
|
||||||
|
if (paged == NULL) {
|
||||||
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req, ac->controls, ares->response, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ac->controls[i]->data = paged;
|
||||||
|
@@ -456,7 +475,13 @@ static int paged_search_callback(struct ldb_request *req,
|
||||||
|
store->result_array_size = store->num_entries;
|
||||||
|
|
||||||
|
ac->store->controls = talloc_move(ac->store, &ares->controls);
|
||||||
|
- ret = paged_results(ac);
|
||||||
|
+ ret = paged_results(ac, ares);
|
||||||
|
+ if (ret != LDB_SUCCESS) {
|
||||||
|
+ /* paged_results will have called ldb_module_done
|
||||||
|
+ * if an error occurred
|
||||||
|
+ */
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
return ldb_module_done(ac->req, ac->controls,
|
||||||
|
ares->response, ret);
|
||||||
|
}
|
||||||
|
@@ -768,7 +793,7 @@ static int paged_search(struct ldb_module *module, struct ldb_request *req)
|
||||||
|
LDB_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = paged_results(ac);
|
||||||
|
+ ret = paged_results(ac, NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
return ldb_module_done(req, NULL, NULL, ret);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
171
CVE-2020-10730-9.patch
Normal file
171
CVE-2020-10730-9.patch
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
From ae6e9445ac8bf8f6870a8caa24406153cd2ee2bf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
Date: Mon, 18 May 2020 12:37:39 +1200
|
||||||
|
Subject: [PATCH 09/22] CVE-2020-10730: s4 dsdb vlv_pagination: Prevent repeat
|
||||||
|
call of ldb_module_done
|
||||||
|
|
||||||
|
Check the return code from vlv_results, if it is not LDB_SUCCESS
|
||||||
|
ldb_module_done has already been called, and SHOULD NOT be called again.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14364
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
---
|
||||||
|
.../dsdb/samdb/ldb_modules/vlv_pagination.c | 61 +++++++++++++++----
|
||||||
|
1 file changed, 49 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
index 720b5e95638..b103bda5f52 100644
|
||||||
|
--- a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
+++ b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
@@ -387,7 +387,7 @@ static int vlv_calc_real_offset(int offset, int denominator, int n_entries)
|
||||||
|
has been prepared earlier and saved -- or by vlv_search_callback() when a
|
||||||
|
search has just been completed. */
|
||||||
|
|
||||||
|
-static int vlv_results(struct vlv_context *ac)
|
||||||
|
+static int vlv_results(struct vlv_context *ac, struct ldb_reply *ares)
|
||||||
|
{
|
||||||
|
struct ldb_vlv_resp_control *vlv;
|
||||||
|
unsigned int num_ctrls;
|
||||||
|
@@ -397,7 +397,9 @@ static int vlv_results(struct vlv_context *ac)
|
||||||
|
int target = 0;
|
||||||
|
|
||||||
|
if (ac->store == NULL) {
|
||||||
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req, ac->controls, ares->response, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ac->store->first_ref) {
|
||||||
|
@@ -406,6 +408,10 @@ static int vlv_results(struct vlv_context *ac)
|
||||||
|
*/
|
||||||
|
ret = send_referrals(ac->store, ac->req);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
+ /*
|
||||||
|
+ * send_referrals will have called ldb_module_done
|
||||||
|
+ * if there was an error.
|
||||||
|
+ */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -419,14 +425,23 @@ static int vlv_results(struct vlv_context *ac)
|
||||||
|
vlv_details,
|
||||||
|
sort_details, &ret);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
- return ret;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req,
|
||||||
|
+ ac->controls,
|
||||||
|
+ ares->response,
|
||||||
|
+ ret);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
target = vlv_calc_real_offset(vlv_details->match.byOffset.offset,
|
||||||
|
vlv_details->match.byOffset.contentCount,
|
||||||
|
ac->store->num_entries);
|
||||||
|
if (target == -1) {
|
||||||
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req,
|
||||||
|
+ ac->controls,
|
||||||
|
+ ares->response,
|
||||||
|
+ ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -462,12 +477,20 @@ static int vlv_results(struct vlv_context *ac)
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else if (ret != LDB_SUCCESS) {
|
||||||
|
- return ret;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req,
|
||||||
|
+ ac->controls,
|
||||||
|
+ ares->response,
|
||||||
|
+ ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ldb_module_send_entry(ac->req, result->msgs[0],
|
||||||
|
NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
+ /*
|
||||||
|
+ * ldb_module_send_entry will have called
|
||||||
|
+ * ldb_module_done if there was an error
|
||||||
|
+ */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -488,7 +511,9 @@ static int vlv_results(struct vlv_context *ac)
|
||||||
|
|
||||||
|
ac->controls = talloc_array(ac, struct ldb_control *, num_ctrls + 1);
|
||||||
|
if (ac->controls == NULL) {
|
||||||
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req, ac->controls, ares->response, ret);
|
||||||
|
}
|
||||||
|
ac->controls[num_ctrls] = NULL;
|
||||||
|
|
||||||
|
@@ -498,20 +523,26 @@ static int vlv_results(struct vlv_context *ac)
|
||||||
|
|
||||||
|
ac->controls[i] = talloc(ac->controls, struct ldb_control);
|
||||||
|
if (ac->controls[i] == NULL) {
|
||||||
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req, ac->controls, ares->response, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ac->controls[i]->oid = talloc_strdup(ac->controls[i],
|
||||||
|
LDB_CONTROL_VLV_RESP_OID);
|
||||||
|
if (ac->controls[i]->oid == NULL) {
|
||||||
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req, ac->controls, ares->response, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ac->controls[i]->critical = 0;
|
||||||
|
|
||||||
|
vlv = talloc(ac->controls[i], struct ldb_vlv_resp_control);
|
||||||
|
if (vlv == NULL) {
|
||||||
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ ret = LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
+ return ldb_module_done(
|
||||||
|
+ ac->req, ac->controls, ares->response, ret);
|
||||||
|
}
|
||||||
|
ac->controls[i]->data = vlv;
|
||||||
|
|
||||||
|
@@ -600,7 +631,13 @@ static int vlv_search_callback(struct ldb_request *req, struct ldb_reply *ares)
|
||||||
|
store->result_array_size = store->num_entries;
|
||||||
|
|
||||||
|
ac->store->controls = talloc_move(ac->store, &ares->controls);
|
||||||
|
- ret = vlv_results(ac);
|
||||||
|
+ ret = vlv_results(ac, ares);
|
||||||
|
+ if (ret != LDB_SUCCESS) {
|
||||||
|
+ /* vlv_results will have called ldb_module_done
|
||||||
|
+ * if there was an error.
|
||||||
|
+ */
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
return ldb_module_done(ac->req, ac->controls,
|
||||||
|
ares->response, ret);
|
||||||
|
}
|
||||||
|
@@ -845,9 +882,9 @@ static int vlv_search(struct ldb_module *module, struct ldb_request *req)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = vlv_results(ac);
|
||||||
|
+ ret = vlv_results(ac, NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
- return ldb_module_done(req, NULL, NULL, ret);
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
return ldb_module_done(req, ac->controls, NULL,
|
||||||
|
LDB_SUCCESS);
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
272
CVE-2020-10745-1.patch
Normal file
272
CVE-2020-10745-1.patch
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
From ddd3ed7ce2e2776839c463010bd975f01dd0977d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
Date: Thu, 11 Jun 2020 17:38:51 +1200
|
||||||
|
Subject: [PATCH 12/22] CVE-2020-10745: pytests: hand-rolled invalid dns/nbt
|
||||||
|
packet tests
|
||||||
|
|
||||||
|
The client libraries don't allow us to make packets that are broken in
|
||||||
|
certain ways, so we need to construct them as byte strings.
|
||||||
|
|
||||||
|
These tests all fail at present, proving the server is rendered
|
||||||
|
unresponsive, which is the crux of CVE-2020-10745.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14378
|
||||||
|
|
||||||
|
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
python/samba/tests/dns_packet.py | 211 +++++++++++++++++++++++++++++++
|
||||||
|
selftest/knownfail.d/dns_packet | 2 +
|
||||||
|
source4/selftest/tests.py | 10 ++
|
||||||
|
3 files changed, 223 insertions(+)
|
||||||
|
create mode 100644 python/samba/tests/dns_packet.py
|
||||||
|
create mode 100644 selftest/knownfail.d/dns_packet
|
||||||
|
|
||||||
|
diff --git a/python/samba/tests/dns_packet.py b/python/samba/tests/dns_packet.py
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..c4f843eb613
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/python/samba/tests/dns_packet.py
|
||||||
|
@@ -0,0 +1,211 @@
|
||||||
|
+# Tests of malformed DNS packets
|
||||||
|
+# Copyright (C) Catalyst.NET ltd
|
||||||
|
+#
|
||||||
|
+# written by Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
+#
|
||||||
|
+# This program is free software; you can redistribute it and/or modify
|
||||||
|
+# it under the terms of the GNU General Public License as published by
|
||||||
|
+# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
+# (at your option) any later version.
|
||||||
|
+#
|
||||||
|
+# This program is distributed in the hope that it will be useful,
|
||||||
|
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+# GNU General Public License for more details.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU General Public License
|
||||||
|
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
+
|
||||||
|
+"""Sanity tests for DNS and NBT server parsing.
|
||||||
|
+
|
||||||
|
+We don't use a proper client library so we can make improper packets.
|
||||||
|
+"""
|
||||||
|
+
|
||||||
|
+import os
|
||||||
|
+import struct
|
||||||
|
+import socket
|
||||||
|
+import select
|
||||||
|
+from samba.dcerpc import dns, nbt
|
||||||
|
+
|
||||||
|
+from samba.tests import TestCase
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def _msg_id():
|
||||||
|
+ while True:
|
||||||
|
+ for i in range(1, 0xffff):
|
||||||
|
+ yield i
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+SERVER = os.environ['SERVER_IP']
|
||||||
|
+SERVER_NAME = f"{os.environ['SERVER']}.{os.environ['REALM']}"
|
||||||
|
+TIMEOUT = 0.5
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def encode_netbios_bytes(chars):
|
||||||
|
+ """Even RFC 1002 uses distancing quotes when calling this "compression"."""
|
||||||
|
+ out = []
|
||||||
|
+ chars = (chars + b' ')[:16]
|
||||||
|
+ for c in chars:
|
||||||
|
+ out.append((c >> 4) + 65)
|
||||||
|
+ out.append((c & 15) + 65)
|
||||||
|
+ return bytes(out)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class TestDnsPacketBase(TestCase):
|
||||||
|
+ msg_id = _msg_id()
|
||||||
|
+
|
||||||
|
+ def tearDown(self):
|
||||||
|
+ # we need to ensure the DNS server is responsive before
|
||||||
|
+ # continuing.
|
||||||
|
+ for i in range(40):
|
||||||
|
+ ok = self._known_good_query()
|
||||||
|
+ if ok:
|
||||||
|
+ return
|
||||||
|
+ print(f"the server is STILL unresponsive after {40 * TIMEOUT} seconds")
|
||||||
|
+
|
||||||
|
+ def decode_reply(self, data):
|
||||||
|
+ header = data[:12]
|
||||||
|
+ id, flags, n_q, n_a, n_rec, n_exta = struct.unpack('!6H',
|
||||||
|
+ header)
|
||||||
|
+ return {
|
||||||
|
+ 'rcode': flags & 0xf
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ def construct_query(self, names):
|
||||||
|
+ """Create a query packet containing one query record.
|
||||||
|
+
|
||||||
|
+ *names* is either a single string name in the usual dotted
|
||||||
|
+ form, or a list of names. In the latter case, each name can
|
||||||
|
+ be a dotted string or a list of byte components, which allows
|
||||||
|
+ dots in components. Where I say list, I mean non-string
|
||||||
|
+ iterable.
|
||||||
|
+
|
||||||
|
+ Examples:
|
||||||
|
+
|
||||||
|
+ # these 3 are all the same
|
||||||
|
+ "example.com"
|
||||||
|
+ ["example.com"]
|
||||||
|
+ [[b"example", b"com"]]
|
||||||
|
+
|
||||||
|
+ # this is three names in the same request
|
||||||
|
+ ["example.com",
|
||||||
|
+ [b"example", b"com", b"..!"],
|
||||||
|
+ (b"first component", b" 2nd component")]
|
||||||
|
+ """
|
||||||
|
+ header = struct.pack('!6H',
|
||||||
|
+ next(self.msg_id),
|
||||||
|
+ 0x0100, # query, with recursion
|
||||||
|
+ len(names), # number of queries
|
||||||
|
+ 0x0000, # no answers
|
||||||
|
+ 0x0000, # no records
|
||||||
|
+ 0x0000, # no extra records
|
||||||
|
+ )
|
||||||
|
+ tail = struct.pack('!BHH',
|
||||||
|
+ 0x00, # root node
|
||||||
|
+ self.qtype,
|
||||||
|
+ 0x0001, # class IN-ternet
|
||||||
|
+ )
|
||||||
|
+ encoded_bits = []
|
||||||
|
+ for name in names:
|
||||||
|
+ if isinstance(name, str):
|
||||||
|
+ bits = name.encode('utf8').split(b'.')
|
||||||
|
+ else:
|
||||||
|
+ bits = name
|
||||||
|
+
|
||||||
|
+ for b in bits:
|
||||||
|
+ encoded_bits.append(b'%c%s' % (len(b), b))
|
||||||
|
+ encoded_bits.append(tail)
|
||||||
|
+
|
||||||
|
+ return header + b''.join(encoded_bits)
|
||||||
|
+
|
||||||
|
+ def _test_query(self, names=(), expected_rcode=None):
|
||||||
|
+
|
||||||
|
+ if isinstance(names, str):
|
||||||
|
+ names = [names]
|
||||||
|
+
|
||||||
|
+ packet = self.construct_query(names)
|
||||||
|
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
+ s.sendto(packet, self.server)
|
||||||
|
+ r, _, _ = select.select([s], [], [], TIMEOUT)
|
||||||
|
+ s.close()
|
||||||
|
+ # It is reasonable to not reply to these packets (Windows
|
||||||
|
+ # doesn't), but it is not reasonable to render the server
|
||||||
|
+ # unresponsive.
|
||||||
|
+ if r != [s]:
|
||||||
|
+ ok = self._known_good_query()
|
||||||
|
+ self.assertTrue(ok, f"the server is unresponsive")
|
||||||
|
+
|
||||||
|
+ def _known_good_query(self):
|
||||||
|
+ if self.server[1] == 53:
|
||||||
|
+ name = SERVER_NAME
|
||||||
|
+ expected_rcode = dns.DNS_RCODE_OK
|
||||||
|
+ else:
|
||||||
|
+ name = [encode_netbios_bytes(b'nxdomain'), b'nxdomain']
|
||||||
|
+ expected_rcode = nbt.NBT_RCODE_NAM
|
||||||
|
+
|
||||||
|
+ packet = self.construct_query([name])
|
||||||
|
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
+ s.sendto(packet, self.server)
|
||||||
|
+ r, _, _ = select.select([s], [], [], TIMEOUT)
|
||||||
|
+ if r != [s]:
|
||||||
|
+ s.close()
|
||||||
|
+ return False
|
||||||
|
+
|
||||||
|
+ data, addr = s.recvfrom(4096)
|
||||||
|
+ s.close()
|
||||||
|
+ rcode = self.decode_reply(data)['rcode']
|
||||||
|
+ return expected_rcode == rcode
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class TestDnsPackets(TestDnsPacketBase):
|
||||||
|
+ server = (SERVER, 53)
|
||||||
|
+ qtype = 1 # dns type A
|
||||||
|
+
|
||||||
|
+ def _test_many_repeated_components(self, label, n, expected_rcode=None):
|
||||||
|
+ name = [label] * n
|
||||||
|
+ self._test_query([name],
|
||||||
|
+ expected_rcode=expected_rcode)
|
||||||
|
+
|
||||||
|
+ def test_127_very_dotty_components(self):
|
||||||
|
+ label = b'.' * 63
|
||||||
|
+ self._test_many_repeated_components(label, 127)
|
||||||
|
+
|
||||||
|
+ def test_127_half_dotty_components(self):
|
||||||
|
+ label = b'x.' * 31 + b'x'
|
||||||
|
+ self._test_many_repeated_components(label, 127)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class TestNbtPackets(TestDnsPacketBase):
|
||||||
|
+ server = (SERVER, 137)
|
||||||
|
+ qtype = 0x20 # NBT_QTYPE_NETBIOS
|
||||||
|
+
|
||||||
|
+ def _test_nbt_encode_query(self, names, *args, **kwargs):
|
||||||
|
+ if isinstance(names, str):
|
||||||
|
+ names = [names]
|
||||||
|
+
|
||||||
|
+ nbt_names = []
|
||||||
|
+ for name in names:
|
||||||
|
+ if isinstance(name, str):
|
||||||
|
+ bits = name.encode('utf8').split(b'.')
|
||||||
|
+ else:
|
||||||
|
+ bits = name
|
||||||
|
+
|
||||||
|
+ encoded = [encode_netbios_bytes(bits[0])]
|
||||||
|
+ encoded.extend(bits[1:])
|
||||||
|
+ nbt_names.append(encoded)
|
||||||
|
+
|
||||||
|
+ self._test_query(nbt_names, *args, **kwargs)
|
||||||
|
+
|
||||||
|
+ def _test_many_repeated_components(self, label, n, expected_rcode=None):
|
||||||
|
+ name = [label] * n
|
||||||
|
+ name[0] = encode_netbios_bytes(label)
|
||||||
|
+ self._test_query([name],
|
||||||
|
+ expected_rcode=expected_rcode)
|
||||||
|
+
|
||||||
|
+ def test_127_very_dotty_components(self):
|
||||||
|
+ label = b'.' * 63
|
||||||
|
+ self._test_many_repeated_components(label, 127)
|
||||||
|
+
|
||||||
|
+ def test_127_half_dotty_components(self):
|
||||||
|
+ label = b'x.' * 31 + b'x'
|
||||||
|
+ self._test_many_repeated_components(label, 127)
|
||||||
|
diff --git a/selftest/knownfail.d/dns_packet b/selftest/knownfail.d/dns_packet
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..6e2e5a699de
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/selftest/knownfail.d/dns_packet
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+samba.tests.dns_packet.samba.tests.dns_packet.TestDnsPackets.test_127_very_dotty_components
|
||||||
|
+samba.tests.dns_packet.samba.tests.dns_packet.TestNbtPackets.test_127_very_dotty_components
|
||||||
|
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
|
||||||
|
index f7645365384..6281b7e8f12 100755
|
||||||
|
--- a/source4/selftest/tests.py
|
||||||
|
+++ b/source4/selftest/tests.py
|
||||||
|
@@ -421,6 +421,16 @@ plantestsuite_loadlist("samba.tests.dns_wildcard", "ad_dc", [python, os.path.joi
|
||||||
|
|
||||||
|
plantestsuite_loadlist("samba.tests.dns_invalid", "ad_dc", [python, os.path.join(srcdir(), "python/samba/tests/dns_invalid.py"), '$SERVER_IP', '--machine-pass', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT'])
|
||||||
|
|
||||||
|
+plantestsuite_loadlist("samba.tests.dns_packet",
|
||||||
|
+ "ad_dc",
|
||||||
|
+ [python,
|
||||||
|
+ '-msamba.subunit.run',
|
||||||
|
+ '$LOADLIST',
|
||||||
|
+ "$LISTOPT"
|
||||||
|
+ "samba.tests.dns_packet"
|
||||||
|
+ ])
|
||||||
|
+
|
||||||
|
+
|
||||||
|
for t in smbtorture4_testsuites("dns_internal."):
|
||||||
|
plansmbtorture4testsuite(t, "ad_dc_default:local", '//$SERVER/whavever')
|
||||||
|
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
316
CVE-2020-10745-2.patch
Normal file
316
CVE-2020-10745-2.patch
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
From ddeabf87957ce73e12030977948418c93436a05c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
Date: Fri, 12 Jun 2020 14:26:38 +1200
|
||||||
|
Subject: [PATCH 13/22] CVE-2020-10745: librpc/tests: cmocka tests of dns and
|
||||||
|
ndr strings
|
||||||
|
|
||||||
|
These time the push and pull function in isolation.
|
||||||
|
|
||||||
|
Timing should be under 0.0001 seconds on even quite old hardware; we
|
||||||
|
assert it must be under 0.2 seconds.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14378
|
||||||
|
|
||||||
|
(backported from master commit)
|
||||||
|
[abartlet@samba.org: backported due to differences in pre-existing
|
||||||
|
tests - eg test_ndr - mentioned in wscript_build and tests.py]
|
||||||
|
|
||||||
|
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
librpc/tests/test_ndr_dns_nbt.c | 236 +++++++++++++++++++++++++++++++
|
||||||
|
librpc/wscript_build | 13 ++
|
||||||
|
selftest/knownfail.d/ndr_dns_nbt | 4 +
|
||||||
|
source4/selftest/tests.py | 2 +
|
||||||
|
4 files changed, 255 insertions(+)
|
||||||
|
create mode 100644 librpc/tests/test_ndr_dns_nbt.c
|
||||||
|
create mode 100644 selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
|
||||||
|
diff --git a/librpc/tests/test_ndr_dns_nbt.c b/librpc/tests/test_ndr_dns_nbt.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..1e2ef45c10d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/librpc/tests/test_ndr_dns_nbt.c
|
||||||
|
@@ -0,0 +1,236 @@
|
||||||
|
+/*
|
||||||
|
+ * Tests for librpc ndr functions
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) Catalyst.NET Ltd 2020
|
||||||
|
+ *
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the GNU General Public License as published by
|
||||||
|
+ * the Free Software Foundation; either version 3 of the License, or
|
||||||
|
+ * (at your option) any later version.
|
||||||
|
+ *
|
||||||
|
+ * This program is distributed in the hope that it will be useful,
|
||||||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+ * GNU General Public License for more details.
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU General Public License
|
||||||
|
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "replace.h"
|
||||||
|
+#include <setjmp.h>
|
||||||
|
+#include <cmocka.h>
|
||||||
|
+
|
||||||
|
+#include "includes.h"
|
||||||
|
+#include "librpc/ndr/libndr.h"
|
||||||
|
+#include "librpc/gen_ndr/ndr_dns.h"
|
||||||
|
+#include "librpc/gen_ndr/ndr_nbt.h"
|
||||||
|
+#include "lib/util/time.h"
|
||||||
|
+
|
||||||
|
+#define NBT_NAME "EOGFGLGPCACACACACACACACACACACACA" /* "neko" */
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static DATA_BLOB generate_obnoxious_dns_name(TALLOC_CTX *mem_ctx,
|
||||||
|
+ size_t n_labels,
|
||||||
|
+ size_t dot_every,
|
||||||
|
+ bool is_nbt)
|
||||||
|
+{
|
||||||
|
+ size_t i, j;
|
||||||
|
+ char *s;
|
||||||
|
+ DATA_BLOB name = data_blob_talloc(mem_ctx, NULL, 64 * n_labels + 1);
|
||||||
|
+ assert_non_null(name.data);
|
||||||
|
+
|
||||||
|
+ s = (char*)name.data;
|
||||||
|
+ if (is_nbt) {
|
||||||
|
+ size_t len = strlen(NBT_NAME);
|
||||||
|
+ *s = len;
|
||||||
|
+ s++;
|
||||||
|
+ memcpy(s, NBT_NAME, len);
|
||||||
|
+ s += len;
|
||||||
|
+ n_labels--;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < n_labels; i++) {
|
||||||
|
+ *s = 63;
|
||||||
|
+ s++;
|
||||||
|
+ for (j = 0; j < 63; j++) {
|
||||||
|
+ if (j % dot_every == (dot_every - 1)) {
|
||||||
|
+ *s = '.';
|
||||||
|
+ } else {
|
||||||
|
+ *s = 'x';
|
||||||
|
+ }
|
||||||
|
+ s++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ *s = 0;
|
||||||
|
+ s++;
|
||||||
|
+ name.length = s - (char*)name.data;
|
||||||
|
+ return name;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static char *_test_ndr_pull_dns_string_list(TALLOC_CTX *mem_ctx,
|
||||||
|
+ size_t n_labels,
|
||||||
|
+ size_t dot_every,
|
||||||
|
+ bool is_nbt)
|
||||||
|
+{
|
||||||
|
+ enum ndr_err_code ndr_err;
|
||||||
|
+ DATA_BLOB blob = generate_obnoxious_dns_name(mem_ctx,
|
||||||
|
+ n_labels,
|
||||||
|
+ dot_every,
|
||||||
|
+ is_nbt);
|
||||||
|
+
|
||||||
|
+ char *name;
|
||||||
|
+ ndr_pull_flags_fn_t fn;
|
||||||
|
+
|
||||||
|
+ if (is_nbt) {
|
||||||
|
+ fn = (ndr_pull_flags_fn_t)ndr_pull_nbt_string;
|
||||||
|
+ } else {
|
||||||
|
+ fn = (ndr_pull_flags_fn_t)ndr_pull_dns_string;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ndr_err = ndr_pull_struct_blob(&blob,
|
||||||
|
+ mem_ctx,
|
||||||
|
+ &name,
|
||||||
|
+ fn);
|
||||||
|
+ /* Success here is not expected, but we let it go to measure timing. */
|
||||||
|
+ if (ndr_err == NDR_ERR_SUCCESS) {
|
||||||
|
+ printf("pull succeed\n");
|
||||||
|
+ } else {
|
||||||
|
+ assert_int_equal(ndr_err, NDR_ERR_STRING);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ TALLOC_FREE(blob.data);
|
||||||
|
+ return name;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void _test_ndr_push_dns_string_list(TALLOC_CTX *mem_ctx,
|
||||||
|
+ char *name,
|
||||||
|
+ bool is_nbt)
|
||||||
|
+{
|
||||||
|
+ DATA_BLOB blob;
|
||||||
|
+ enum ndr_err_code ndr_err;
|
||||||
|
+ ndr_push_flags_fn_t fn;
|
||||||
|
+
|
||||||
|
+ if (is_nbt) {
|
||||||
|
+ fn = (ndr_push_flags_fn_t)ndr_push_nbt_string;
|
||||||
|
+ } else {
|
||||||
|
+ fn = (ndr_push_flags_fn_t)ndr_push_dns_string;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ndr_err = ndr_push_struct_blob(&blob,
|
||||||
|
+ mem_ctx,
|
||||||
|
+ name,
|
||||||
|
+ fn);
|
||||||
|
+
|
||||||
|
+ /* Success here is not expected, but we let it go to measure timing. */
|
||||||
|
+ if (ndr_err == NDR_ERR_SUCCESS) {
|
||||||
|
+ printf("push succeed\n");
|
||||||
|
+ } else {
|
||||||
|
+ assert_int_equal(ndr_err, NDR_ERR_STRING);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static uint64_t elapsed_time(struct timespec start, const char *print)
|
||||||
|
+{
|
||||||
|
+ struct timespec end;
|
||||||
|
+ unsigned long long microsecs;
|
||||||
|
+ clock_gettime_mono(&end);
|
||||||
|
+ end.tv_sec -= start.tv_sec;
|
||||||
|
+ if (end.tv_nsec < start.tv_nsec) {
|
||||||
|
+ /* we need to borrow */
|
||||||
|
+ end.tv_nsec += 1000 * 1000 * 1000;
|
||||||
|
+ end.tv_sec -= 1;
|
||||||
|
+ }
|
||||||
|
+ end.tv_nsec -= start.tv_nsec;
|
||||||
|
+ microsecs = end.tv_sec * 1000000;
|
||||||
|
+ microsecs += end.tv_nsec / 1000;
|
||||||
|
+
|
||||||
|
+ if (print != NULL) {
|
||||||
|
+ printf(" %s: %llu microseconds\n", print, microsecs);
|
||||||
|
+ }
|
||||||
|
+ return microsecs;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void test_ndr_dns_string_half_dots(void **state)
|
||||||
|
+{
|
||||||
|
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||||
|
+ char *name;
|
||||||
|
+ struct timespec start;
|
||||||
|
+ uint64_t elapsed;
|
||||||
|
+
|
||||||
|
+ clock_gettime_mono(&start);
|
||||||
|
+ name =_test_ndr_pull_dns_string_list(mem_ctx, 127, 2, false);
|
||||||
|
+ elapsed_time(start, "pull");
|
||||||
|
+ _test_ndr_push_dns_string_list(mem_ctx, name, false);
|
||||||
|
+ elapsed = elapsed_time(start, "total");
|
||||||
|
+ assert_in_range(elapsed, 0, 200000);
|
||||||
|
+ talloc_free(mem_ctx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void test_ndr_nbt_string_half_dots(void **state)
|
||||||
|
+{
|
||||||
|
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||||
|
+ char *name;
|
||||||
|
+ struct timespec start;
|
||||||
|
+ uint64_t elapsed;
|
||||||
|
+
|
||||||
|
+ clock_gettime_mono(&start);
|
||||||
|
+ name =_test_ndr_pull_dns_string_list(mem_ctx, 127, 2, true);
|
||||||
|
+ elapsed_time(start, "pull");
|
||||||
|
+ _test_ndr_push_dns_string_list(mem_ctx, name, true);
|
||||||
|
+ elapsed = elapsed_time(start, "total");
|
||||||
|
+ assert_in_range(elapsed, 0, 200000);
|
||||||
|
+ talloc_free(mem_ctx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void test_ndr_dns_string_all_dots(void **state)
|
||||||
|
+{
|
||||||
|
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||||
|
+ char *name;
|
||||||
|
+ struct timespec start;
|
||||||
|
+ uint64_t elapsed;
|
||||||
|
+
|
||||||
|
+ clock_gettime_mono(&start);
|
||||||
|
+ name =_test_ndr_pull_dns_string_list(mem_ctx, 127, 1, false);
|
||||||
|
+ elapsed_time(start, "pull");
|
||||||
|
+ _test_ndr_push_dns_string_list(mem_ctx, name, false);
|
||||||
|
+ elapsed = elapsed_time(start, "total");
|
||||||
|
+ assert_in_range(elapsed, 0, 200000);
|
||||||
|
+ talloc_free(mem_ctx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void test_ndr_nbt_string_all_dots(void **state)
|
||||||
|
+{
|
||||||
|
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||||
|
+ char *name;
|
||||||
|
+ struct timespec start;
|
||||||
|
+ uint64_t elapsed;
|
||||||
|
+
|
||||||
|
+ clock_gettime_mono(&start);
|
||||||
|
+ name =_test_ndr_pull_dns_string_list(mem_ctx, 127, 1, true);
|
||||||
|
+ elapsed_time(start, "pull");
|
||||||
|
+ _test_ndr_push_dns_string_list(mem_ctx, name, true);
|
||||||
|
+ elapsed = elapsed_time(start, "total");
|
||||||
|
+ assert_in_range(elapsed, 0, 200000);
|
||||||
|
+ talloc_free(mem_ctx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+int main(int argc, const char **argv)
|
||||||
|
+{
|
||||||
|
+ const struct CMUnitTest tests[] = {
|
||||||
|
+ cmocka_unit_test(test_ndr_nbt_string_half_dots),
|
||||||
|
+ cmocka_unit_test(test_ndr_dns_string_half_dots),
|
||||||
|
+ cmocka_unit_test(test_ndr_nbt_string_all_dots),
|
||||||
|
+ cmocka_unit_test(test_ndr_dns_string_all_dots),
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
|
||||||
|
+ return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
|
+}
|
||||||
|
diff --git a/librpc/wscript_build b/librpc/wscript_build
|
||||||
|
index 70fe8c2f7fe..e3be298c725 100644
|
||||||
|
--- a/librpc/wscript_build
|
||||||
|
+++ b/librpc/wscript_build
|
||||||
|
@@ -656,3 +656,16 @@ bld.SAMBA_SUBSYSTEM('NDR_FSRVP_STATE',
|
||||||
|
source='gen_ndr/ndr_fsrvp_state.c',
|
||||||
|
public_deps='ndr'
|
||||||
|
)
|
||||||
|
+#
|
||||||
|
+# Cmocka tests
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+bld.SAMBA_BINARY('test_ndr_dns_nbt',
|
||||||
|
+ source='tests/test_ndr_dns_nbt.c',
|
||||||
|
+ deps='''
|
||||||
|
+ cmocka
|
||||||
|
+ ndr
|
||||||
|
+ ndr_nbt
|
||||||
|
+ NDR_DNS
|
||||||
|
+ ''',
|
||||||
|
+ install=False)
|
||||||
|
diff --git a/selftest/knownfail.d/ndr_dns_nbt b/selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..f30217c4033
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
@@ -0,0 +1,4 @@
|
||||||
|
+librpc.ndr.ndr_dns_nbt.test_ndr_dns_string_all_dots
|
||||||
|
+librpc.ndr.ndr_dns_nbt.test_ndr_dns_string_half_dots
|
||||||
|
+librpc.ndr.ndr_dns_nbt.test_ndr_nbt_string_all_dots
|
||||||
|
+librpc.ndr.ndr_dns_nbt.test_ndr_nbt_string_half_dots
|
||||||
|
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
|
||||||
|
index 6281b7e8f12..e8dbed71a18 100755
|
||||||
|
--- a/source4/selftest/tests.py
|
||||||
|
+++ b/source4/selftest/tests.py
|
||||||
|
@@ -1337,6 +1337,8 @@ plantestsuite("samba4.dcerpc.dnsserver.dnsutils", "none",
|
||||||
|
[os.path.join(bindir(), "test_rpc_dns_server_dnsutils")])
|
||||||
|
plantestsuite("libcli.drsuapi.repl_decrypt", "none",
|
||||||
|
[os.path.join(bindir(), "test_repl_decrypt")])
|
||||||
|
+plantestsuite("librpc.ndr.ndr_dns_nbt", "none",
|
||||||
|
+ [os.path.join(bindir(), "test_ndr_dns_nbt")])
|
||||||
|
|
||||||
|
# process restart and limit tests, these break the environment so need to run
|
||||||
|
# in their own specific environment
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
241
CVE-2020-10745-3.patch
Normal file
241
CVE-2020-10745-3.patch
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
From 37cacb8f41b9b2ea19a9c1bbfade4ea250dced46 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
Date: Sat, 25 Apr 2020 11:02:08 +1200
|
||||||
|
Subject: [PATCH 14/22] CVE-2020-10745: ndr_dns: move ndr_push_dns_string core
|
||||||
|
into sharable function
|
||||||
|
|
||||||
|
This is because ndr_nbt.c does almost exactly the same thing with
|
||||||
|
almost exactly the same code, and they both do it wrong. Soon they
|
||||||
|
will both be using the better version that this will become. Though in
|
||||||
|
this patch we just move the code, not fix it.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14378
|
||||||
|
|
||||||
|
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
librpc/ndr/ndr_dns.c | 79 +++-------------------------------
|
||||||
|
librpc/ndr/ndr_dns_utils.c | 88 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
librpc/ndr/ndr_dns_utils.h | 5 +++
|
||||||
|
librpc/wscript_build | 2 +-
|
||||||
|
4 files changed, 99 insertions(+), 75 deletions(-)
|
||||||
|
create mode 100644 librpc/ndr/ndr_dns_utils.c
|
||||||
|
create mode 100644 librpc/ndr/ndr_dns_utils.h
|
||||||
|
|
||||||
|
diff --git a/librpc/ndr/ndr_dns.c b/librpc/ndr/ndr_dns.c
|
||||||
|
index d37c8cc2ece..68a3c9de782 100644
|
||||||
|
--- a/librpc/ndr/ndr_dns.c
|
||||||
|
+++ b/librpc/ndr/ndr_dns.c
|
||||||
|
@@ -33,6 +33,7 @@
|
||||||
|
#include "librpc/gen_ndr/ndr_dnsp.h"
|
||||||
|
#include "system/locale.h"
|
||||||
|
#include "lib/util/util_net.h"
|
||||||
|
+#include "ndr_dns_utils.h"
|
||||||
|
|
||||||
|
/* don't allow an unlimited number of name components */
|
||||||
|
#define MAX_COMPONENTS 128
|
||||||
|
@@ -159,80 +160,10 @@ _PUBLIC_ enum ndr_err_code ndr_push_dns_string(struct ndr_push *ndr,
|
||||||
|
int ndr_flags,
|
||||||
|
const char *s)
|
||||||
|
{
|
||||||
|
- if (!(ndr_flags & NDR_SCALARS)) {
|
||||||
|
- return NDR_ERR_SUCCESS;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- while (s && *s) {
|
||||||
|
- enum ndr_err_code ndr_err;
|
||||||
|
- char *compname;
|
||||||
|
- size_t complen;
|
||||||
|
- uint32_t offset;
|
||||||
|
-
|
||||||
|
- if (!(ndr->flags & LIBNDR_FLAG_NO_COMPRESSION)) {
|
||||||
|
- /* see if we have pushed the remaining string already,
|
||||||
|
- * if so we use a label pointer to this string
|
||||||
|
- */
|
||||||
|
- ndr_err = ndr_token_retrieve_cmp_fn(&ndr->dns_string_list, s,
|
||||||
|
- &offset,
|
||||||
|
- (comparison_fn_t)strcmp,
|
||||||
|
- false);
|
||||||
|
- if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
|
- uint8_t b[2];
|
||||||
|
-
|
||||||
|
- if (offset > 0x3FFF) {
|
||||||
|
- return ndr_push_error(ndr, NDR_ERR_STRING,
|
||||||
|
- "offset for dns string " \
|
||||||
|
- "label pointer " \
|
||||||
|
- "%u[%08X] > 0x00003FFF",
|
||||||
|
- offset, offset);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- b[0] = 0xC0 | (offset>>8);
|
||||||
|
- b[1] = (offset & 0xFF);
|
||||||
|
-
|
||||||
|
- return ndr_push_bytes(ndr, b, 2);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- complen = strcspn(s, ".");
|
||||||
|
-
|
||||||
|
- /* we need to make sure the length fits into 6 bytes */
|
||||||
|
- if (complen > 0x3F) {
|
||||||
|
- return ndr_push_error(ndr, NDR_ERR_STRING,
|
||||||
|
- "component length %u[%08X] > " \
|
||||||
|
- "0x0000003F",
|
||||||
|
- (unsigned)complen,
|
||||||
|
- (unsigned)complen);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- compname = talloc_asprintf(ndr, "%c%*.*s",
|
||||||
|
- (unsigned char)complen,
|
||||||
|
- (unsigned char)complen,
|
||||||
|
- (unsigned char)complen, s);
|
||||||
|
- NDR_ERR_HAVE_NO_MEMORY(compname);
|
||||||
|
-
|
||||||
|
- /* remember the current component + the rest of the string
|
||||||
|
- * so it can be reused later
|
||||||
|
- */
|
||||||
|
- if (!(ndr->flags & LIBNDR_FLAG_NO_COMPRESSION)) {
|
||||||
|
- NDR_CHECK(ndr_token_store(ndr, &ndr->dns_string_list, s,
|
||||||
|
- ndr->offset));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* push just this component into the blob */
|
||||||
|
- NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname,
|
||||||
|
- complen+1));
|
||||||
|
- talloc_free(compname);
|
||||||
|
-
|
||||||
|
- s += complen;
|
||||||
|
- if (*s == '.') s++;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* if we reach the end of the string and have pushed the last component
|
||||||
|
- * without using a label pointer, we need to terminate the string
|
||||||
|
- */
|
||||||
|
- return ndr_push_bytes(ndr, (const uint8_t *)"", 1);
|
||||||
|
+ return ndr_push_dns_string_list(ndr,
|
||||||
|
+ &ndr->dns_string_list,
|
||||||
|
+ ndr_flags,
|
||||||
|
+ s);
|
||||||
|
}
|
||||||
|
|
||||||
|
_PUBLIC_ enum ndr_err_code ndr_pull_dns_txt_record(struct ndr_pull *ndr, int ndr_flags, struct dns_txt_record *r)
|
||||||
|
diff --git a/librpc/ndr/ndr_dns_utils.c b/librpc/ndr/ndr_dns_utils.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..2d9b5f1bc1e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/librpc/ndr/ndr_dns_utils.c
|
||||||
|
@@ -0,0 +1,88 @@
|
||||||
|
+#include "includes.h"
|
||||||
|
+#include "../librpc/ndr/libndr.h"
|
||||||
|
+#include "ndr_dns_utils.h"
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ push a dns/nbt string list to the wire
|
||||||
|
+*/
|
||||||
|
+enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
+ struct ndr_token_list *string_list,
|
||||||
|
+ int ndr_flags,
|
||||||
|
+ const char *s)
|
||||||
|
+{
|
||||||
|
+ if (!(ndr_flags & NDR_SCALARS)) {
|
||||||
|
+ return NDR_ERR_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while (s && *s) {
|
||||||
|
+ enum ndr_err_code ndr_err;
|
||||||
|
+ char *compname;
|
||||||
|
+ size_t complen;
|
||||||
|
+ uint32_t offset;
|
||||||
|
+
|
||||||
|
+ if (!(ndr->flags & LIBNDR_FLAG_NO_COMPRESSION)) {
|
||||||
|
+ /* see if we have pushed the remaining string already,
|
||||||
|
+ * if so we use a label pointer to this string
|
||||||
|
+ */
|
||||||
|
+ ndr_err = ndr_token_retrieve_cmp_fn(string_list, s,
|
||||||
|
+ &offset,
|
||||||
|
+ (comparison_fn_t)strcmp,
|
||||||
|
+ false);
|
||||||
|
+ if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
|
+ uint8_t b[2];
|
||||||
|
+
|
||||||
|
+ if (offset > 0x3FFF) {
|
||||||
|
+ return ndr_push_error(ndr, NDR_ERR_STRING,
|
||||||
|
+ "offset for dns string " \
|
||||||
|
+ "label pointer " \
|
||||||
|
+ "%u[%08X] > 0x00003FFF",
|
||||||
|
+ offset, offset);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ b[0] = 0xC0 | (offset>>8);
|
||||||
|
+ b[1] = (offset & 0xFF);
|
||||||
|
+
|
||||||
|
+ return ndr_push_bytes(ndr, b, 2);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ complen = strcspn(s, ".");
|
||||||
|
+
|
||||||
|
+ /* we need to make sure the length fits into 6 bytes */
|
||||||
|
+ if (complen > 0x3F) {
|
||||||
|
+ return ndr_push_error(ndr, NDR_ERR_STRING,
|
||||||
|
+ "component length %u[%08X] > " \
|
||||||
|
+ "0x0000003F",
|
||||||
|
+ (unsigned)complen,
|
||||||
|
+ (unsigned)complen);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ compname = talloc_asprintf(ndr, "%c%*.*s",
|
||||||
|
+ (unsigned char)complen,
|
||||||
|
+ (unsigned char)complen,
|
||||||
|
+ (unsigned char)complen, s);
|
||||||
|
+ NDR_ERR_HAVE_NO_MEMORY(compname);
|
||||||
|
+
|
||||||
|
+ /* remember the current component + the rest of the string
|
||||||
|
+ * so it can be reused later
|
||||||
|
+ */
|
||||||
|
+ if (!(ndr->flags & LIBNDR_FLAG_NO_COMPRESSION)) {
|
||||||
|
+ NDR_CHECK(ndr_token_store(ndr, string_list, s,
|
||||||
|
+ ndr->offset));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* push just this component into the blob */
|
||||||
|
+ NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname,
|
||||||
|
+ complen+1));
|
||||||
|
+ talloc_free(compname);
|
||||||
|
+
|
||||||
|
+ s += complen;
|
||||||
|
+ if (*s == '.') s++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* if we reach the end of the string and have pushed the last component
|
||||||
|
+ * without using a label pointer, we need to terminate the string
|
||||||
|
+ */
|
||||||
|
+ return ndr_push_bytes(ndr, (const uint8_t *)"", 1);
|
||||||
|
+}
|
||||||
|
diff --git a/librpc/ndr/ndr_dns_utils.h b/librpc/ndr/ndr_dns_utils.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..823e3201112
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/librpc/ndr/ndr_dns_utils.h
|
||||||
|
@@ -0,0 +1,5 @@
|
||||||
|
+
|
||||||
|
+enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
+ struct ndr_token_list *string_list,
|
||||||
|
+ int ndr_flags,
|
||||||
|
+ const char *s);
|
||||||
|
diff --git a/librpc/wscript_build b/librpc/wscript_build
|
||||||
|
index e3be298c725..c165500644b 100644
|
||||||
|
--- a/librpc/wscript_build
|
||||||
|
+++ b/librpc/wscript_build
|
||||||
|
@@ -31,7 +31,7 @@ bld.SAMBA_SUBSYSTEM('NDR_DNSSERVER',
|
||||||
|
)
|
||||||
|
|
||||||
|
bld.SAMBA_SUBSYSTEM('NDR_DNS',
|
||||||
|
- source='gen_ndr/ndr_dns.c ndr/ndr_dns.c',
|
||||||
|
+ source='gen_ndr/ndr_dns.c ndr/ndr_dns.c ndr/ndr_dns_utils.c',
|
||||||
|
public_deps='ndr NDR_DNSP'
|
||||||
|
)
|
||||||
|
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
28
CVE-2020-10745-4.patch
Normal file
28
CVE-2020-10745-4.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
From b687813ac362ff71085d192a4b7821235345feea Mon Sep 17 00:00:00 2001
|
||||||
|
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
Date: Sat, 25 Apr 2020 11:03:30 +1200
|
||||||
|
Subject: [PATCH 15/22] CVE-2020-10745: ndr/dns_utils: correct a comment
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14378
|
||||||
|
|
||||||
|
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
librpc/ndr/ndr_dns_utils.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/librpc/ndr/ndr_dns_utils.c b/librpc/ndr/ndr_dns_utils.c
|
||||||
|
index 2d9b5f1bc1e..2ce300863bc 100644
|
||||||
|
--- a/librpc/ndr/ndr_dns_utils.c
|
||||||
|
+++ b/librpc/ndr/ndr_dns_utils.c
|
||||||
|
@@ -49,7 +49,7 @@ enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
|
||||||
|
complen = strcspn(s, ".");
|
||||||
|
|
||||||
|
- /* we need to make sure the length fits into 6 bytes */
|
||||||
|
+ /* the length must fit into 6 bits (i.e. <= 63) */
|
||||||
|
if (complen > 0x3F) {
|
||||||
|
return ndr_push_error(ndr, NDR_ERR_STRING,
|
||||||
|
"component length %u[%08X] > " \
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
54
CVE-2020-10745-5.patch
Normal file
54
CVE-2020-10745-5.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
From 507503f80e8913450364dcd8ab080f3211b6f855 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
Date: Sat, 25 Apr 2020 11:10:18 +1200
|
||||||
|
Subject: [PATCH 16/22] CVE-2020-10745: ndr_dns: do not allow consecutive dots
|
||||||
|
|
||||||
|
The empty subdomain component is reserved for the root domain, which we
|
||||||
|
should only (and always) see at the end of the list. That is, we expect
|
||||||
|
"example.com.", but never "example..com".
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14378
|
||||||
|
|
||||||
|
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
librpc/ndr/ndr_dns_utils.c | 6 ++++++
|
||||||
|
selftest/knownfail.d/dns_packet | 1 -
|
||||||
|
selftest/knownfail.d/ndr_dns_nbt | 1 -
|
||||||
|
3 files changed, 6 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/librpc/ndr/ndr_dns_utils.c b/librpc/ndr/ndr_dns_utils.c
|
||||||
|
index 2ce300863bc..6931dac422d 100644
|
||||||
|
--- a/librpc/ndr/ndr_dns_utils.c
|
||||||
|
+++ b/librpc/ndr/ndr_dns_utils.c
|
||||||
|
@@ -58,6 +58,12 @@ enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
(unsigned)complen);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (complen == 0 && s[complen] == '.') {
|
||||||
|
+ return ndr_push_error(ndr, NDR_ERR_STRING,
|
||||||
|
+ "component length is 0 "
|
||||||
|
+ "(consecutive dots)");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
compname = talloc_asprintf(ndr, "%c%*.*s",
|
||||||
|
(unsigned char)complen,
|
||||||
|
(unsigned char)complen,
|
||||||
|
diff --git a/selftest/knownfail.d/dns_packet b/selftest/knownfail.d/dns_packet
|
||||||
|
index 6e2e5a699de..0662266f689 100644
|
||||||
|
--- a/selftest/knownfail.d/dns_packet
|
||||||
|
+++ b/selftest/knownfail.d/dns_packet
|
||||||
|
@@ -1,2 +1 @@
|
||||||
|
-samba.tests.dns_packet.samba.tests.dns_packet.TestDnsPackets.test_127_very_dotty_components
|
||||||
|
samba.tests.dns_packet.samba.tests.dns_packet.TestNbtPackets.test_127_very_dotty_components
|
||||||
|
diff --git a/selftest/knownfail.d/ndr_dns_nbt b/selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
index f30217c4033..e11c121b7a7 100644
|
||||||
|
--- a/selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
+++ b/selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
@@ -1,4 +1,3 @@
|
||||||
|
-librpc.ndr.ndr_dns_nbt.test_ndr_dns_string_all_dots
|
||||||
|
librpc.ndr.ndr_dns_nbt.test_ndr_dns_string_half_dots
|
||||||
|
librpc.ndr.ndr_dns_nbt.test_ndr_nbt_string_all_dots
|
||||||
|
librpc.ndr.ndr_dns_nbt.test_ndr_nbt_string_half_dots
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
55
CVE-2020-10745-6.patch
Normal file
55
CVE-2020-10745-6.patch
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
From 83b00656ea0e8cfdce8a9c1cef71e41477e8e6f0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
Date: Fri, 15 May 2020 00:06:08 +1200
|
||||||
|
Subject: [PATCH 17/22] CVE-2020-10745: dns_util/push: forbid names longer than
|
||||||
|
255 bytes
|
||||||
|
|
||||||
|
As per RFC 1035.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14378
|
||||||
|
|
||||||
|
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
librpc/ndr/ndr_dns_utils.c | 10 +++++++++-
|
||||||
|
selftest/knownfail.d/ndr_dns_nbt | 1 -
|
||||||
|
2 files changed, 9 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/librpc/ndr/ndr_dns_utils.c b/librpc/ndr/ndr_dns_utils.c
|
||||||
|
index 6931dac422d..b7f11dbab4e 100644
|
||||||
|
--- a/librpc/ndr/ndr_dns_utils.c
|
||||||
|
+++ b/librpc/ndr/ndr_dns_utils.c
|
||||||
|
@@ -11,6 +11,8 @@ enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
int ndr_flags,
|
||||||
|
const char *s)
|
||||||
|
{
|
||||||
|
+ const char *start = s;
|
||||||
|
+
|
||||||
|
if (!(ndr_flags & NDR_SCALARS)) {
|
||||||
|
return NDR_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
@@ -84,7 +86,13 @@ enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
talloc_free(compname);
|
||||||
|
|
||||||
|
s += complen;
|
||||||
|
- if (*s == '.') s++;
|
||||||
|
+ if (*s == '.') {
|
||||||
|
+ s++;
|
||||||
|
+ }
|
||||||
|
+ if (s - start > 255) {
|
||||||
|
+ return ndr_push_error(ndr, NDR_ERR_STRING,
|
||||||
|
+ "name > 255 character long");
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we reach the end of the string and have pushed the last component
|
||||||
|
diff --git a/selftest/knownfail.d/ndr_dns_nbt b/selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
index e11c121b7a7..603395c8c50 100644
|
||||||
|
--- a/selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
+++ b/selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
@@ -1,3 +1,2 @@
|
||||||
|
-librpc.ndr.ndr_dns_nbt.test_ndr_dns_string_half_dots
|
||||||
|
librpc.ndr.ndr_dns_nbt.test_ndr_nbt_string_all_dots
|
||||||
|
librpc.ndr.ndr_dns_nbt.test_ndr_nbt_string_half_dots
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
267
CVE-2020-10745-7.patch
Normal file
267
CVE-2020-10745-7.patch
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
From 23e9eb71052e02aecf726609db0256c0d93e0b57 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
Date: Fri, 15 May 2020 10:52:45 +1200
|
||||||
|
Subject: [PATCH 18/22] CVE-2020-10745: ndr/dns-utils: prepare for NBT
|
||||||
|
compatibility
|
||||||
|
|
||||||
|
NBT has a funny thing where it sometimes needs to send a trailing dot as
|
||||||
|
part of the last component, because the string representation is a user
|
||||||
|
name. In DNS, "example.com", and "example.com." are the same, both
|
||||||
|
having three components ("example", "com", ""); in NBT, we want to treat
|
||||||
|
them differently, with the second form having the three components
|
||||||
|
("example", "com.", "").
|
||||||
|
|
||||||
|
This retains the logic of e6e2ec0001fe3c010445e26cc0efddbc1f73416b.
|
||||||
|
|
||||||
|
Also DNS compression cannot be turned off for NBT.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14378
|
||||||
|
|
||||||
|
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
librpc/ndr/ndr_dns.c | 3 +-
|
||||||
|
librpc/ndr/ndr_dns_utils.c | 42 ++++++++++++++++---
|
||||||
|
librpc/ndr/ndr_dns_utils.h | 3 +-
|
||||||
|
librpc/ndr/ndr_nbt.c | 72 ++++----------------------------
|
||||||
|
librpc/wscript_build | 3 +-
|
||||||
|
selftest/knownfail.d/dns_packet | 1 -
|
||||||
|
selftest/knownfail.d/ndr_dns_nbt | 2 -
|
||||||
|
7 files changed, 49 insertions(+), 77 deletions(-)
|
||||||
|
delete mode 100644 selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
|
||||||
|
diff --git a/librpc/ndr/ndr_dns.c b/librpc/ndr/ndr_dns.c
|
||||||
|
index 68a3c9de782..966e0b59786 100644
|
||||||
|
--- a/librpc/ndr/ndr_dns.c
|
||||||
|
+++ b/librpc/ndr/ndr_dns.c
|
||||||
|
@@ -163,7 +163,8 @@ _PUBLIC_ enum ndr_err_code ndr_push_dns_string(struct ndr_push *ndr,
|
||||||
|
return ndr_push_dns_string_list(ndr,
|
||||||
|
&ndr->dns_string_list,
|
||||||
|
ndr_flags,
|
||||||
|
- s);
|
||||||
|
+ s,
|
||||||
|
+ false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_PUBLIC_ enum ndr_err_code ndr_pull_dns_txt_record(struct ndr_pull *ndr, int ndr_flags, struct dns_txt_record *r)
|
||||||
|
diff --git a/librpc/ndr/ndr_dns_utils.c b/librpc/ndr/ndr_dns_utils.c
|
||||||
|
index b7f11dbab4e..325d9c68bea 100644
|
||||||
|
--- a/librpc/ndr/ndr_dns_utils.c
|
||||||
|
+++ b/librpc/ndr/ndr_dns_utils.c
|
||||||
|
@@ -9,9 +9,32 @@
|
||||||
|
enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
struct ndr_token_list *string_list,
|
||||||
|
int ndr_flags,
|
||||||
|
- const char *s)
|
||||||
|
+ const char *s,
|
||||||
|
+ bool is_nbt)
|
||||||
|
{
|
||||||
|
const char *start = s;
|
||||||
|
+ bool use_compression;
|
||||||
|
+ size_t max_length;
|
||||||
|
+ if (is_nbt) {
|
||||||
|
+ use_compression = true;
|
||||||
|
+ /*
|
||||||
|
+ * Max length is longer in NBT/Wins, because Windows counts
|
||||||
|
+ * the semi-decompressed size of the netbios name (16 bytes)
|
||||||
|
+ * rather than the wire size of 32, which is what you'd expect
|
||||||
|
+ * if it followed RFC1002 (it uses the short form in
|
||||||
|
+ * [MS-WINSRA]). In other words the maximum size of the
|
||||||
|
+ * "scope" is 237, not 221.
|
||||||
|
+ *
|
||||||
|
+ * We make the size limit slightly larger than 255 + 16,
|
||||||
|
+ * because the 237 scope limit is already enforced in the
|
||||||
|
+ * winsserver code with a specific return value; bailing out
|
||||||
|
+ * here would muck with that.
|
||||||
|
+ */
|
||||||
|
+ max_length = 274;
|
||||||
|
+ } else {
|
||||||
|
+ use_compression = !(ndr->flags & LIBNDR_FLAG_NO_COMPRESSION);
|
||||||
|
+ max_length = 255;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!(ndr_flags & NDR_SCALARS)) {
|
||||||
|
return NDR_ERR_SUCCESS;
|
||||||
|
@@ -23,7 +46,7 @@ enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
size_t complen;
|
||||||
|
uint32_t offset;
|
||||||
|
|
||||||
|
- if (!(ndr->flags & LIBNDR_FLAG_NO_COMPRESSION)) {
|
||||||
|
+ if (use_compression) {
|
||||||
|
/* see if we have pushed the remaining string already,
|
||||||
|
* if so we use a label pointer to this string
|
||||||
|
*/
|
||||||
|
@@ -66,6 +89,14 @@ enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
"(consecutive dots)");
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (is_nbt && s[complen] == '.' && s[complen + 1] == '\0') {
|
||||||
|
+ /* nbt names are sometimes usernames, and we need to
|
||||||
|
+ * keep a trailing dot to ensure it is byte-identical,
|
||||||
|
+ * (not just semantically identical given DNS
|
||||||
|
+ * semantics). */
|
||||||
|
+ complen++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
compname = talloc_asprintf(ndr, "%c%*.*s",
|
||||||
|
(unsigned char)complen,
|
||||||
|
(unsigned char)complen,
|
||||||
|
@@ -75,7 +106,7 @@ enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
/* remember the current component + the rest of the string
|
||||||
|
* so it can be reused later
|
||||||
|
*/
|
||||||
|
- if (!(ndr->flags & LIBNDR_FLAG_NO_COMPRESSION)) {
|
||||||
|
+ if (use_compression) {
|
||||||
|
NDR_CHECK(ndr_token_store(ndr, string_list, s,
|
||||||
|
ndr->offset));
|
||||||
|
}
|
||||||
|
@@ -89,9 +120,10 @@ enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
if (*s == '.') {
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
- if (s - start > 255) {
|
||||||
|
+ if (s - start > max_length) {
|
||||||
|
return ndr_push_error(ndr, NDR_ERR_STRING,
|
||||||
|
- "name > 255 character long");
|
||||||
|
+ "name > %zu character long",
|
||||||
|
+ max_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/librpc/ndr/ndr_dns_utils.h b/librpc/ndr/ndr_dns_utils.h
|
||||||
|
index 823e3201112..71a65433bbb 100644
|
||||||
|
--- a/librpc/ndr/ndr_dns_utils.h
|
||||||
|
+++ b/librpc/ndr/ndr_dns_utils.h
|
||||||
|
@@ -2,4 +2,5 @@
|
||||||
|
enum ndr_err_code ndr_push_dns_string_list(struct ndr_push *ndr,
|
||||||
|
struct ndr_token_list *string_list,
|
||||||
|
int ndr_flags,
|
||||||
|
- const char *s);
|
||||||
|
+ const char *s,
|
||||||
|
+ bool is_nbt);
|
||||||
|
diff --git a/librpc/ndr/ndr_nbt.c b/librpc/ndr/ndr_nbt.c
|
||||||
|
index 838f947a168..e8dd7549a53 100644
|
||||||
|
--- a/librpc/ndr/ndr_nbt.c
|
||||||
|
+++ b/librpc/ndr/ndr_nbt.c
|
||||||
|
@@ -25,6 +25,8 @@
|
||||||
|
#include "includes.h"
|
||||||
|
#include "../libcli/nbt/libnbt.h"
|
||||||
|
#include "../libcli/netlogon/netlogon.h"
|
||||||
|
+#include "ndr_dns_utils.h"
|
||||||
|
+
|
||||||
|
|
||||||
|
/* don't allow an unlimited number of name components */
|
||||||
|
#define MAX_COMPONENTS 128
|
||||||
|
@@ -141,71 +143,11 @@ _PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_fla
|
||||||
|
*/
|
||||||
|
_PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s)
|
||||||
|
{
|
||||||
|
- if (!(ndr_flags & NDR_SCALARS)) {
|
||||||
|
- return NDR_ERR_SUCCESS;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- while (s && *s) {
|
||||||
|
- enum ndr_err_code ndr_err;
|
||||||
|
- char *compname;
|
||||||
|
- size_t complen;
|
||||||
|
- uint32_t offset;
|
||||||
|
-
|
||||||
|
- /* see if we have pushed the remaining string already,
|
||||||
|
- * if so we use a label pointer to this string
|
||||||
|
- */
|
||||||
|
- ndr_err = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, false);
|
||||||
|
- if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
|
- uint8_t b[2];
|
||||||
|
-
|
||||||
|
- if (offset > 0x3FFF) {
|
||||||
|
- return ndr_push_error(ndr, NDR_ERR_STRING,
|
||||||
|
- "offset for nbt string label pointer %u[%08X] > 0x00003FFF",
|
||||||
|
- offset, offset);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- b[0] = 0xC0 | (offset>>8);
|
||||||
|
- b[1] = (offset & 0xFF);
|
||||||
|
-
|
||||||
|
- return ndr_push_bytes(ndr, b, 2);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- complen = strcspn(s, ".");
|
||||||
|
-
|
||||||
|
- /* we need to make sure the length fits into 6 bytes */
|
||||||
|
- if (complen > 0x3F) {
|
||||||
|
- return ndr_push_error(ndr, NDR_ERR_STRING,
|
||||||
|
- "component length %u[%08X] > 0x0000003F",
|
||||||
|
- (unsigned)complen, (unsigned)complen);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (s[complen] == '.' && s[complen+1] == '\0') {
|
||||||
|
- complen++;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- compname = talloc_asprintf(ndr, "%c%*.*s",
|
||||||
|
- (unsigned char)complen,
|
||||||
|
- (unsigned char)complen,
|
||||||
|
- (unsigned char)complen, s);
|
||||||
|
- NDR_ERR_HAVE_NO_MEMORY(compname);
|
||||||
|
-
|
||||||
|
- /* remember the current componemt + the rest of the string
|
||||||
|
- * so it can be reused later
|
||||||
|
- */
|
||||||
|
- NDR_CHECK(ndr_token_store(ndr, &ndr->nbt_string_list, s, ndr->offset));
|
||||||
|
-
|
||||||
|
- /* push just this component into the blob */
|
||||||
|
- NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname, complen+1));
|
||||||
|
- talloc_free(compname);
|
||||||
|
-
|
||||||
|
- s += complen;
|
||||||
|
- if (*s == '.') s++;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* if we reach the end of the string and have pushed the last component
|
||||||
|
- * without using a label pointer, we need to terminate the string
|
||||||
|
- */
|
||||||
|
- return ndr_push_bytes(ndr, (const uint8_t *)"", 1);
|
||||||
|
+ return ndr_push_dns_string_list(ndr,
|
||||||
|
+ &ndr->dns_string_list,
|
||||||
|
+ ndr_flags,
|
||||||
|
+ s,
|
||||||
|
+ true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/librpc/wscript_build b/librpc/wscript_build
|
||||||
|
index c165500644b..4917928a9c4 100644
|
||||||
|
--- a/librpc/wscript_build
|
||||||
|
+++ b/librpc/wscript_build
|
||||||
|
@@ -401,7 +401,7 @@ bld.SAMBA_SUBSYSTEM('NDR_SCHANNEL',
|
||||||
|
|
||||||
|
bld.SAMBA_LIBRARY('ndr_nbt',
|
||||||
|
source='gen_ndr/ndr_nbt.c ndr/ndr_nbt.c',
|
||||||
|
- public_deps='ndr NDR_NBT_BUF NDR_SECURITY',
|
||||||
|
+ public_deps='ndr NDR_NBT_BUF NDR_SECURITY NDR_DNS',
|
||||||
|
public_headers='gen_ndr/nbt.h gen_ndr/ndr_nbt.h ndr/ndr_nbt.h',
|
||||||
|
header_path=[ ('gen_ndr*', 'gen_ndr'), ('ndr*', 'ndr')],
|
||||||
|
pc_files='ndr_nbt.pc',
|
||||||
|
@@ -666,6 +666,5 @@ bld.SAMBA_BINARY('test_ndr_dns_nbt',
|
||||||
|
cmocka
|
||||||
|
ndr
|
||||||
|
ndr_nbt
|
||||||
|
- NDR_DNS
|
||||||
|
''',
|
||||||
|
install=False)
|
||||||
|
diff --git a/selftest/knownfail.d/dns_packet b/selftest/knownfail.d/dns_packet
|
||||||
|
index 0662266f689..e69de29bb2d 100644
|
||||||
|
--- a/selftest/knownfail.d/dns_packet
|
||||||
|
+++ b/selftest/knownfail.d/dns_packet
|
||||||
|
@@ -1 +0,0 @@
|
||||||
|
-samba.tests.dns_packet.samba.tests.dns_packet.TestNbtPackets.test_127_very_dotty_components
|
||||||
|
diff --git a/selftest/knownfail.d/ndr_dns_nbt b/selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
deleted file mode 100644
|
||||||
|
index 603395c8c50..00000000000
|
||||||
|
--- a/selftest/knownfail.d/ndr_dns_nbt
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-librpc.ndr.ndr_dns_nbt.test_ndr_nbt_string_all_dots
|
||||||
|
-librpc.ndr.ndr_dns_nbt.test_ndr_nbt_string_half_dots
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
74
CVE-2020-10760-1.patch
Normal file
74
CVE-2020-10760-1.patch
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
From 4def2dc554754033174c60f5860f51b46d8502c1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Date: Fri, 5 Jun 2020 22:14:48 +1200
|
||||||
|
Subject: [PATCH 21/22] CVE-2020-10760 dsdb: Ensure a proper talloc tree for
|
||||||
|
saved controls
|
||||||
|
|
||||||
|
Otherwise a paged search on the GC port will fail as the ->data was
|
||||||
|
not kept around for the second page of searches.
|
||||||
|
|
||||||
|
An example command to produce this is
|
||||||
|
bin/ldbsearch --paged -H ldap://$SERVER:3268 -U$USERNAME%$PASSWORD
|
||||||
|
|
||||||
|
This shows up later in the partition module as:
|
||||||
|
|
||||||
|
ERROR: AddressSanitizer: heap-use-after-free on address 0x60b00151ef20 at pc 0x7fec3f801aac bp 0x7ffe8472c270 sp 0x7ffe8472c260
|
||||||
|
READ of size 4 at 0x60b00151ef20 thread T0 (ldap(0))
|
||||||
|
#0 0x7fec3f801aab in talloc_chunk_from_ptr ../../lib/talloc/talloc.c:526
|
||||||
|
#1 0x7fec3f801aab in __talloc_get_name ../../lib/talloc/talloc.c:1559
|
||||||
|
#2 0x7fec3f801aab in talloc_check_name ../../lib/talloc/talloc.c:1582
|
||||||
|
#3 0x7fec1b86b2e1 in partition_search ../../source4/dsdb/samdb/ldb_modules/partition.c:780
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
smb_panic_default: PANIC (pid 13287): Bad talloc magic value - unknown value
|
||||||
|
(from source4/dsdb/samdb/ldb_modules/partition.c:780)
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14402
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
---
|
||||||
|
source4/dsdb/samdb/ldb_modules/paged_results.c | 8 ++++++++
|
||||||
|
source4/dsdb/samdb/ldb_modules/vlv_pagination.c | 7 +++++++
|
||||||
|
2 files changed, 15 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/source4/dsdb/samdb/ldb_modules/paged_results.c b/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
index 735883e8802..3eea3236e7d 100644
|
||||||
|
--- a/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
+++ b/source4/dsdb/samdb/ldb_modules/paged_results.c
|
||||||
|
@@ -523,6 +523,14 @@ paged_results_copy_down_controls(TALLOC_CTX *mem_ctx,
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
new_controls[j] = talloc_steal(new_controls, control);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Sadly the caller is not obliged to make this a
|
||||||
|
+ * proper talloc tree, so we do so here.
|
||||||
|
+ */
|
||||||
|
+ if (control->data) {
|
||||||
|
+ talloc_steal(control, control->data);
|
||||||
|
+ }
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
new_controls[j] = NULL;
|
||||||
|
diff --git a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
index b103bda5f52..d6d6039e849 100644
|
||||||
|
--- a/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
+++ b/source4/dsdb/samdb/ldb_modules/vlv_pagination.c
|
||||||
|
@@ -746,6 +746,13 @@ vlv_copy_down_controls(TALLOC_CTX *mem_ctx, struct ldb_control **controls)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
new_controls[j] = talloc_steal(new_controls, control);
|
||||||
|
+ /*
|
||||||
|
+ * Sadly the caller is not obliged to make this a
|
||||||
|
+ * proper talloc tree, so we do so here.
|
||||||
|
+ */
|
||||||
|
+ if (control->data) {
|
||||||
|
+ talloc_steal(control, control->data);
|
||||||
|
+ }
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
new_controls[j] = NULL;
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
247
CVE-2020-10760-2.patch
Normal file
247
CVE-2020-10760-2.patch
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
From df599b6b79010759279eb7f52486f1d0a59d06d3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Date: Mon, 8 Jun 2020 16:32:14 +1200
|
||||||
|
Subject: [PATCH 22/22] CVE-2020-10760 dsdb: Add tests for paged_results and
|
||||||
|
VLV over the Global Catalog port
|
||||||
|
|
||||||
|
This should avoid a regression.
|
||||||
|
|
||||||
|
(backported from master patch)
|
||||||
|
[abartlet@samba.org: sort=True parameter on test_paged_delete_during_search
|
||||||
|
is not in 4.11]
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
---
|
||||||
|
selftest/knownfail.d/vlv | 2 +-
|
||||||
|
source4/dsdb/tests/python/vlv.py | 171 +++++++++++++++++++------------
|
||||||
|
2 files changed, 107 insertions(+), 66 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/selftest/knownfail.d/vlv b/selftest/knownfail.d/vlv
|
||||||
|
index f187a2ed55e..7ae02baf17b 100644
|
||||||
|
--- a/selftest/knownfail.d/vlv
|
||||||
|
+++ b/selftest/knownfail.d/vlv
|
||||||
|
@@ -1,2 +1,2 @@
|
||||||
|
samba4.ldap.vlv.python.*__main__.VLVTests.test_vlv_change_search_expr
|
||||||
|
-samba4.ldap.vlv.python.*__main__.PagedResultsTests.test_paged_cant_change_controls_data
|
||||||
|
+samba4.ldap.vlv.python.*__main__.PagedResultsTestsRW.test_paged_cant_change_controls_data
|
||||||
|
diff --git a/source4/dsdb/tests/python/vlv.py b/source4/dsdb/tests/python/vlv.py
|
||||||
|
index f3c603e3a39..ba03b425a5b 100644
|
||||||
|
--- a/source4/dsdb/tests/python/vlv.py
|
||||||
|
+++ b/source4/dsdb/tests/python/vlv.py
|
||||||
|
@@ -152,7 +152,7 @@ class TestsWithUserOU(samba.tests.TestCase):
|
||||||
|
super(TestsWithUserOU, self).setUp()
|
||||||
|
self.ldb = SamDB(host, credentials=creds,
|
||||||
|
session_info=system_session(lp), lp=lp)
|
||||||
|
-
|
||||||
|
+ self.ldb_ro = self.ldb
|
||||||
|
self.base_dn = self.ldb.domain_dn()
|
||||||
|
self.tree_dn = "ou=vlvtesttree,%s" % self.base_dn
|
||||||
|
self.ou = "ou=vlvou,%s" % self.tree_dn
|
||||||
|
@@ -199,8 +199,60 @@ class TestsWithUserOU(samba.tests.TestCase):
|
||||||
|
self.ldb.delete(self.tree_dn, ['tree_delete:1'])
|
||||||
|
|
||||||
|
|
||||||
|
-class VLVTests(TestsWithUserOU):
|
||||||
|
+class VLVTestsBase(TestsWithUserOU):
|
||||||
|
+
|
||||||
|
+ # Run a vlv search and return important fields of the response control
|
||||||
|
+ def vlv_search(self, attr, expr, cookie="", after_count=0, offset=1):
|
||||||
|
+ sort_ctrl = "server_sort:1:0:%s" % attr
|
||||||
|
+ ctrl = "vlv:1:0:%d:%d:0" % (after_count, offset)
|
||||||
|
+ if cookie:
|
||||||
|
+ ctrl += ":" + cookie
|
||||||
|
+
|
||||||
|
+ res = self.ldb_ro.search(self.ou,
|
||||||
|
+ expression=expr,
|
||||||
|
+ scope=ldb.SCOPE_ONELEVEL,
|
||||||
|
+ attrs=[attr],
|
||||||
|
+ controls=[ctrl, sort_ctrl])
|
||||||
|
+ results = [str(x[attr][0]) for x in res]
|
||||||
|
+
|
||||||
|
+ ctrls = [str(c) for c in res.controls if
|
||||||
|
+ str(c).startswith('vlv')]
|
||||||
|
+ self.assertEqual(len(ctrls), 1)
|
||||||
|
+
|
||||||
|
+ spl = ctrls[0].rsplit(':')
|
||||||
|
+ cookie = ""
|
||||||
|
+ if len(spl) == 6:
|
||||||
|
+ cookie = spl[-1]
|
||||||
|
+
|
||||||
|
+ return results, cookie
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class VLVTestsRO(VLVTestsBase):
|
||||||
|
+ def test_vlv_simple_double_run(self):
|
||||||
|
+ """Do the simplest possible VLV query to confirm if VLV
|
||||||
|
+ works at all. Useful for showing VLV as a whole works
|
||||||
|
+ on Global Catalog (for example)"""
|
||||||
|
+ attr = 'roomNumber'
|
||||||
|
+ expr = "(objectclass=user)"
|
||||||
|
|
||||||
|
+ # Start new search
|
||||||
|
+ full_results, cookie = self.vlv_search(attr, expr,
|
||||||
|
+ after_count=len(self.users))
|
||||||
|
+
|
||||||
|
+ results, cookie = self.vlv_search(attr, expr, cookie=cookie,
|
||||||
|
+ after_count=len(self.users))
|
||||||
|
+ expected_results = full_results
|
||||||
|
+ self.assertEqual(results, expected_results)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class VLVTestsGC(VLVTestsRO):
|
||||||
|
+ def setUp(self):
|
||||||
|
+ super(VLVTestsRO, self).setUp()
|
||||||
|
+ self.ldb_ro = SamDB(host + ":3268", credentials=creds,
|
||||||
|
+ session_info=system_session(lp), lp=lp)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class VLVTests(VLVTestsBase):
|
||||||
|
def get_full_list(self, attr, include_cn=False):
|
||||||
|
"""Fetch the whole list sorted on the attribute, using the VLV.
|
||||||
|
This way you get a VLV cookie."""
|
||||||
|
@@ -1081,31 +1133,6 @@ class VLVTests(TestsWithUserOU):
|
||||||
|
controls=[sort_control,
|
||||||
|
"vlv:0:1:1:1:0:%s" % vlv_cookies[-1]])
|
||||||
|
|
||||||
|
- # Run a vlv search and return important fields of the response control
|
||||||
|
- def vlv_search(self, attr, expr, cookie="", after_count=0, offset=1):
|
||||||
|
- sort_ctrl = "server_sort:1:0:%s" % attr
|
||||||
|
- ctrl = "vlv:1:0:%d:%d:0" % (after_count, offset)
|
||||||
|
- if cookie:
|
||||||
|
- ctrl += ":" + cookie
|
||||||
|
-
|
||||||
|
- res = self.ldb.search(self.ou,
|
||||||
|
- expression=expr,
|
||||||
|
- scope=ldb.SCOPE_ONELEVEL,
|
||||||
|
- attrs=[attr],
|
||||||
|
- controls=[ctrl, sort_ctrl])
|
||||||
|
- results = [str(x[attr][0]) for x in res]
|
||||||
|
-
|
||||||
|
- ctrls = [str(c) for c in res.controls if
|
||||||
|
- str(c).startswith('vlv')]
|
||||||
|
- self.assertEqual(len(ctrls), 1)
|
||||||
|
-
|
||||||
|
- spl = ctrls[0].rsplit(':')
|
||||||
|
- cookie = ""
|
||||||
|
- if len(spl) == 6:
|
||||||
|
- cookie = spl[-1]
|
||||||
|
-
|
||||||
|
- return results, cookie
|
||||||
|
-
|
||||||
|
def test_vlv_modify_during_view(self):
|
||||||
|
attr = 'roomNumber'
|
||||||
|
expr = "(objectclass=user)"
|
||||||
|
@@ -1218,11 +1245,11 @@ class PagedResultsTests(TestsWithUserOU):
|
||||||
|
if subtree:
|
||||||
|
scope = ldb.SCOPE_SUBTREE
|
||||||
|
|
||||||
|
- res = self.ldb.search(ou,
|
||||||
|
- expression=expr,
|
||||||
|
- scope=scope,
|
||||||
|
- controls=controls,
|
||||||
|
- **kwargs)
|
||||||
|
+ res = self.ldb_ro.search(ou,
|
||||||
|
+ expression=expr,
|
||||||
|
+ scope=scope,
|
||||||
|
+ controls=controls,
|
||||||
|
+ **kwargs)
|
||||||
|
results = [str(r['cn'][0]) for r in res]
|
||||||
|
|
||||||
|
ctrls = [str(c) for c in res.controls if
|
||||||
|
@@ -1235,6 +1262,53 @@ class PagedResultsTests(TestsWithUserOU):
|
||||||
|
cookie = spl[-1]
|
||||||
|
return results, cookie
|
||||||
|
|
||||||
|
+
|
||||||
|
+class PagedResultsTestsRO(PagedResultsTests):
|
||||||
|
+
|
||||||
|
+ def test_paged_search_lockstep(self):
|
||||||
|
+ expr = "(objectClass=*)"
|
||||||
|
+ ps = 3
|
||||||
|
+
|
||||||
|
+ all_results, _ = self.paged_search(expr, page_size=len(self.users)+1)
|
||||||
|
+
|
||||||
|
+ # Run two different but overlapping paged searches simultaneously.
|
||||||
|
+ set_1_index = int((len(all_results))//3)
|
||||||
|
+ set_2_index = int((2*len(all_results))//3)
|
||||||
|
+ set_1 = all_results[set_1_index:]
|
||||||
|
+ set_2 = all_results[:set_2_index+1]
|
||||||
|
+ set_1_expr = "(cn>=%s)" % (all_results[set_1_index])
|
||||||
|
+ set_2_expr = "(cn<=%s)" % (all_results[set_2_index])
|
||||||
|
+
|
||||||
|
+ results, cookie1 = self.paged_search(set_1_expr, page_size=ps)
|
||||||
|
+ self.assertEqual(results, set_1[:ps])
|
||||||
|
+ results, cookie2 = self.paged_search(set_2_expr, page_size=ps)
|
||||||
|
+ self.assertEqual(results, set_2[:ps])
|
||||||
|
+
|
||||||
|
+ results, cookie1 = self.paged_search(set_1_expr, cookie=cookie1,
|
||||||
|
+ page_size=ps)
|
||||||
|
+ self.assertEqual(results, set_1[ps:ps*2])
|
||||||
|
+ results, cookie2 = self.paged_search(set_2_expr, cookie=cookie2,
|
||||||
|
+ page_size=ps)
|
||||||
|
+ self.assertEqual(results, set_2[ps:ps*2])
|
||||||
|
+
|
||||||
|
+ results, _ = self.paged_search(set_1_expr, cookie=cookie1,
|
||||||
|
+ page_size=len(self.users))
|
||||||
|
+ self.assertEqual(results, set_1[ps*2:])
|
||||||
|
+ results, _ = self.paged_search(set_2_expr, cookie=cookie2,
|
||||||
|
+ page_size=len(self.users))
|
||||||
|
+ self.assertEqual(results, set_2[ps*2:])
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class PagedResultsTestsGC(PagedResultsTestsRO):
|
||||||
|
+
|
||||||
|
+ def setUp(self):
|
||||||
|
+ super(PagedResultsTestsRO, self).setUp()
|
||||||
|
+ self.ldb_ro = SamDB(host + ":3268", credentials=creds,
|
||||||
|
+ session_info=system_session(lp), lp=lp)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class PagedResultsTestsRW(PagedResultsTests):
|
||||||
|
+
|
||||||
|
def test_paged_delete_during_search(self):
|
||||||
|
expr = "(objectClass=*)"
|
||||||
|
|
||||||
|
@@ -1611,39 +1685,6 @@ class PagedResultsTests(TestsWithUserOU):
|
||||||
|
cookie, attrs=changed_attrs,
|
||||||
|
extra_ctrls=[])
|
||||||
|
|
||||||
|
- def test_paged_search_lockstep(self):
|
||||||
|
- expr = "(objectClass=*)"
|
||||||
|
- ps = 3
|
||||||
|
-
|
||||||
|
- all_results, _ = self.paged_search(expr, page_size=len(self.users)+1)
|
||||||
|
-
|
||||||
|
- # Run two different but overlapping paged searches simultaneously.
|
||||||
|
- set_1_index = int((len(all_results))//3)
|
||||||
|
- set_2_index = int((2*len(all_results))//3)
|
||||||
|
- set_1 = all_results[set_1_index:]
|
||||||
|
- set_2 = all_results[:set_2_index+1]
|
||||||
|
- set_1_expr = "(cn>=%s)" % (all_results[set_1_index])
|
||||||
|
- set_2_expr = "(cn<=%s)" % (all_results[set_2_index])
|
||||||
|
-
|
||||||
|
- results, cookie1 = self.paged_search(set_1_expr, page_size=ps)
|
||||||
|
- self.assertEqual(results, set_1[:ps])
|
||||||
|
- results, cookie2 = self.paged_search(set_2_expr, page_size=ps)
|
||||||
|
- self.assertEqual(results, set_2[:ps])
|
||||||
|
-
|
||||||
|
- results, cookie1 = self.paged_search(set_1_expr, cookie=cookie1,
|
||||||
|
- page_size=ps)
|
||||||
|
- self.assertEqual(results, set_1[ps:ps*2])
|
||||||
|
- results, cookie2 = self.paged_search(set_2_expr, cookie=cookie2,
|
||||||
|
- page_size=ps)
|
||||||
|
- self.assertEqual(results, set_2[ps:ps*2])
|
||||||
|
-
|
||||||
|
- results, _ = self.paged_search(set_1_expr, cookie=cookie1,
|
||||||
|
- page_size=len(self.users))
|
||||||
|
- self.assertEqual(results, set_1[ps*2:])
|
||||||
|
- results, _ = self.paged_search(set_2_expr, cookie=cookie2,
|
||||||
|
- page_size=len(self.users))
|
||||||
|
- self.assertEqual(results, set_2[ps*2:])
|
||||||
|
-
|
||||||
|
def test_vlv_paged(self):
|
||||||
|
"""Testing behaviour with VLV and paged_results set.
|
||||||
|
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
65
CVE-2020-14303-1.patch
Normal file
65
CVE-2020-14303-1.patch
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
From 11034ea33fca9b8a1c2e14480e70069b55fca6a2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
Date: Thu, 25 Jun 2020 11:59:54 +1200
|
||||||
|
Subject: [PATCH 19/22] CVE-2020-14303 Ensure an empty packet will not DoS the
|
||||||
|
NBT server
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
|
||||||
|
---
|
||||||
|
python/samba/tests/dns_packet.py | 19 +++++++++++++++++++
|
||||||
|
selftest/knownfail.d/empty-nbt | 1 +
|
||||||
|
2 files changed, 20 insertions(+)
|
||||||
|
create mode 100644 selftest/knownfail.d/empty-nbt
|
||||||
|
|
||||||
|
diff --git a/python/samba/tests/dns_packet.py b/python/samba/tests/dns_packet.py
|
||||||
|
index c4f843eb613..ae7bcb3ad8c 100644
|
||||||
|
--- a/python/samba/tests/dns_packet.py
|
||||||
|
+++ b/python/samba/tests/dns_packet.py
|
||||||
|
@@ -156,6 +156,19 @@ class TestDnsPacketBase(TestCase):
|
||||||
|
rcode = self.decode_reply(data)['rcode']
|
||||||
|
return expected_rcode == rcode
|
||||||
|
|
||||||
|
+ def _test_empty_packet(self):
|
||||||
|
+
|
||||||
|
+ packet = b""
|
||||||
|
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
+ s.sendto(packet, self.server)
|
||||||
|
+ s.close()
|
||||||
|
+
|
||||||
|
+ # It is reasonable not to reply to an empty packet
|
||||||
|
+ # but it is not reasonable to render the server
|
||||||
|
+ # unresponsive.
|
||||||
|
+ ok = self._known_good_query()
|
||||||
|
+ self.assertTrue(ok, f"the server is unresponsive")
|
||||||
|
+
|
||||||
|
|
||||||
|
class TestDnsPackets(TestDnsPacketBase):
|
||||||
|
server = (SERVER, 53)
|
||||||
|
@@ -174,6 +187,9 @@ class TestDnsPackets(TestDnsPacketBase):
|
||||||
|
label = b'x.' * 31 + b'x'
|
||||||
|
self._test_many_repeated_components(label, 127)
|
||||||
|
|
||||||
|
+ def test_empty_packet(self):
|
||||||
|
+ self._test_empty_packet()
|
||||||
|
+
|
||||||
|
|
||||||
|
class TestNbtPackets(TestDnsPacketBase):
|
||||||
|
server = (SERVER, 137)
|
||||||
|
@@ -209,3 +225,6 @@ class TestNbtPackets(TestDnsPacketBase):
|
||||||
|
def test_127_half_dotty_components(self):
|
||||||
|
label = b'x.' * 31 + b'x'
|
||||||
|
self._test_many_repeated_components(label, 127)
|
||||||
|
+
|
||||||
|
+ def test_empty_packet(self):
|
||||||
|
+ self._test_empty_packet()
|
||||||
|
diff --git a/selftest/knownfail.d/empty-nbt b/selftest/knownfail.d/empty-nbt
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..e4bcccab4e5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/selftest/knownfail.d/empty-nbt
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+^samba.tests.dns_packet.samba.tests.dns_packet.TestNbtPackets.test_empty_packet
|
||||||
|
\ No newline at end of file
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
58
CVE-2020-14303-2.patch
Normal file
58
CVE-2020-14303-2.patch
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
From 153c8db09b26455aa9802ff95943dd8a75f31893 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
Date: Wed, 24 Jun 2020 14:27:08 +1200
|
||||||
|
Subject: [PATCH 20/22] CVE-2020-14303: s4 nbt: fix busy loop on empty UDP
|
||||||
|
packet
|
||||||
|
|
||||||
|
An empty UDP packet put the nbt server into a busy loop that consumes
|
||||||
|
100% of a cpu.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14417
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
|
||||||
|
---
|
||||||
|
libcli/nbt/nbtsocket.c | 17 ++++++++++++++++-
|
||||||
|
selftest/knownfail.d/empty-nbt | 1 -
|
||||||
|
2 files changed, 16 insertions(+), 2 deletions(-)
|
||||||
|
delete mode 100644 selftest/knownfail.d/empty-nbt
|
||||||
|
|
||||||
|
diff --git a/libcli/nbt/nbtsocket.c b/libcli/nbt/nbtsocket.c
|
||||||
|
index 33d53fba993..8aecaf73247 100644
|
||||||
|
--- a/libcli/nbt/nbtsocket.c
|
||||||
|
+++ b/libcli/nbt/nbtsocket.c
|
||||||
|
@@ -167,8 +167,23 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Given a zero length, data_blob_talloc() returns the
|
||||||
|
+ * NULL blob {NULL, 0}.
|
||||||
|
+ *
|
||||||
|
+ * We only want to error return here on a real out of memory condition
|
||||||
|
+ * (i.e. dsize != 0, so the UDP packet has data, but the return of the
|
||||||
|
+ * allocation failed, so blob.data==NULL).
|
||||||
|
+ *
|
||||||
|
+ * Given an actual zero length UDP packet having blob.data == NULL
|
||||||
|
+ * isn't an out of memory error condition, that's the defined semantics
|
||||||
|
+ * of data_blob_talloc() when asked for zero bytes.
|
||||||
|
+ *
|
||||||
|
+ * We still need to continue to do the zero-length socket_recvfrom()
|
||||||
|
+ * read in order to clear the "read pending" condition on the socket.
|
||||||
|
+ */
|
||||||
|
blob = data_blob_talloc(tmp_ctx, NULL, dsize);
|
||||||
|
- if (blob.data == NULL) {
|
||||||
|
+ if (blob.data == NULL && dsize != 0) {
|
||||||
|
talloc_free(tmp_ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
diff --git a/selftest/knownfail.d/empty-nbt b/selftest/knownfail.d/empty-nbt
|
||||||
|
deleted file mode 100644
|
||||||
|
index e4bcccab4e5..00000000000
|
||||||
|
--- a/selftest/knownfail.d/empty-nbt
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1 +0,0 @@
|
||||||
|
-^samba.tests.dns_packet.samba.tests.dns_packet.TestNbtPackets.test_empty_packet
|
||||||
|
\ No newline at end of file
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
62
samba.spec
62
samba.spec
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
Name: samba
|
Name: samba
|
||||||
Version: 4.11.6
|
Version: 4.11.6
|
||||||
Release: 7
|
Release: 8
|
||||||
|
|
||||||
Summary: A suite for Linux to interoperate with Windows
|
Summary: A suite for Linux to interoperate with Windows
|
||||||
License: GPLv3+ and LGPLv3+
|
License: GPLv3+ and LGPLv3+
|
||||||
@ -66,17 +66,38 @@ Source7: samba.pamd
|
|||||||
|
|
||||||
Source201: README.downgrade
|
Source201: README.downgrade
|
||||||
|
|
||||||
Patch100: 0000-use-gnutls-for-des-cbc.patch
|
Patch0: 0000-use-gnutls-for-des-cbc.patch
|
||||||
Patch101: 0001-handle-removal-des-enctypes-from-krb5.patch
|
Patch1: 0001-handle-removal-des-enctypes-from-krb5.patch
|
||||||
Patch102: 0002-samba-tool-create-working-private-krb5.conf.patch
|
Patch2: 0002-samba-tool-create-working-private-krb5.conf.patch
|
||||||
Patch103: CVE-2020-10700-1.patch
|
Patch3: CVE-2020-10700-1.patch
|
||||||
Patch104: CVE-2020-10700-3.patch
|
Patch4: CVE-2020-10700-3.patch
|
||||||
Patch105: CVE-2020-10704-1.patch
|
Patch5: CVE-2020-10704-1.patch
|
||||||
Patch106: CVE-2020-10704-3.patch
|
Patch6: CVE-2020-10704-3.patch
|
||||||
Patch107: CVE-2020-10704-5.patch
|
Patch7: CVE-2020-10704-5.patch
|
||||||
Patch108: CVE-2020-10704-6.patch
|
Patch8: CVE-2020-10704-6.patch
|
||||||
Patch109: CVE-2020-10704-7.patch
|
Patch9: CVE-2020-10704-7.patch
|
||||||
Patch110: CVE-2020-10704-8.patch
|
Patch10: CVE-2020-10704-8.patch
|
||||||
|
Patch11: CVE-2020-10730-1.patch
|
||||||
|
Patch12: CVE-2020-10730-2.patch
|
||||||
|
Patch13: CVE-2020-10730-3.patch
|
||||||
|
Patch14: CVE-2020-10730-4.patch
|
||||||
|
Patch15: CVE-2020-10730-5.patch
|
||||||
|
Patch16: CVE-2020-10730-6.patch
|
||||||
|
Patch17: CVE-2020-10730-7.patch
|
||||||
|
Patch18: CVE-2020-10730-8.patch
|
||||||
|
Patch19: CVE-2020-10730-9.patch
|
||||||
|
Patch20: CVE-2020-10730-10.patch
|
||||||
|
Patch21: CVE-2020-10745-1.patch
|
||||||
|
Patch22: CVE-2020-10745-2.patch
|
||||||
|
Patch23: CVE-2020-10745-3.patch
|
||||||
|
Patch24: CVE-2020-10745-4.patch
|
||||||
|
Patch25: CVE-2020-10745-5.patch
|
||||||
|
Patch26: CVE-2020-10745-6.patch
|
||||||
|
Patch27: CVE-2020-10745-7.patch
|
||||||
|
Patch28: CVE-2020-14303-1.patch
|
||||||
|
Patch29: CVE-2020-14303-2.patch
|
||||||
|
Patch30: CVE-2020-10760-1.patch
|
||||||
|
Patch31: CVE-2020-10760-2.patch
|
||||||
|
|
||||||
BuildRequires: avahi-devel cups-devel dbus-devel docbook-style-xsl e2fsprogs-devel gawk gnupg2 gnutls-devel >= 3.4.7 gpgme-devel
|
BuildRequires: avahi-devel cups-devel dbus-devel docbook-style-xsl e2fsprogs-devel gawk gnupg2 gnutls-devel >= 3.4.7 gpgme-devel
|
||||||
BuildRequires: jansson-devel krb5-devel >= %{required_mit_krb5} libacl-devel libaio-devel libarchive-devel libattr-devel
|
BuildRequires: jansson-devel krb5-devel >= %{required_mit_krb5} libacl-devel libaio-devel libarchive-devel libattr-devel
|
||||||
@ -1001,15 +1022,6 @@ fi
|
|||||||
%config %{_sysconfdir}/openldap/schema/samba.schema
|
%config %{_sysconfdir}/openldap/schema/samba.schema
|
||||||
%config(noreplace) %{_sysconfdir}/pam.d/samba
|
%config(noreplace) %{_sysconfdir}/pam.d/samba
|
||||||
|
|
||||||
%if ! %{with_vfs_glusterfs}
|
|
||||||
%exclude %{_mandir}/man8/vfs_glusterfs.8*
|
|
||||||
%endif
|
|
||||||
|
|
||||||
%if ! %{with_vfs_cephfs}
|
|
||||||
%exclude %{_mandir}/man8/vfs_ceph.8*
|
|
||||||
%exclude %{_mandir}/man8/vfs_ceph_snapshots.8*
|
|
||||||
%endif
|
|
||||||
|
|
||||||
%attr(775,root,printadmin) %dir /var/lib/samba/drivers
|
%attr(775,root,printadmin) %dir /var/lib/samba/drivers
|
||||||
|
|
||||||
%files libs
|
%files libs
|
||||||
@ -1902,6 +1914,8 @@ fi
|
|||||||
%{python3_sitearch}/samba/tests/__pycache__/upgradeprovisionneeddc.*.pyc
|
%{python3_sitearch}/samba/tests/__pycache__/upgradeprovisionneeddc.*.pyc
|
||||||
%{python3_sitearch}/samba/tests/__pycache__/usage.*.pyc
|
%{python3_sitearch}/samba/tests/__pycache__/usage.*.pyc
|
||||||
%{python3_sitearch}/samba/tests/__pycache__/xattr.*.pyc
|
%{python3_sitearch}/samba/tests/__pycache__/xattr.*.pyc
|
||||||
|
%{python3_sitearch}/samba/tests/__pycache__/dns_packet.*.pyc
|
||||||
|
%{python3_sitearch}/samba/tests/dns_packet.py
|
||||||
%{python3_sitearch}/samba/tests/audit_log_base.py
|
%{python3_sitearch}/samba/tests/audit_log_base.py
|
||||||
%{python3_sitearch}/samba/tests/audit_log_dsdb.py
|
%{python3_sitearch}/samba/tests/audit_log_dsdb.py
|
||||||
%{python3_sitearch}/samba/tests/audit_log_pass_change.py
|
%{python3_sitearch}/samba/tests/audit_log_pass_change.py
|
||||||
@ -3062,6 +3076,12 @@ fi
|
|||||||
%{_mandir}/man*
|
%{_mandir}/man*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Aug 05 2020 yuboyun <yuboyun@huawei.com> - 4.11.6-8
|
||||||
|
- Type:cves
|
||||||
|
- ID:CVE-2020-10730 CVE-2020-10745 CVE-2020-14303 CVE-2020-10760
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:fix CVE-2020-10730CVE-2020-10745CVE-2020-14303CVE-2020-10760
|
||||||
|
|
||||||
* Fri May 29 2020 songzifeng <songzifeng1@huawei.com> - 4.11.6-7
|
* Fri May 29 2020 songzifeng <songzifeng1@huawei.com> - 4.11.6-7
|
||||||
- fix the conflict of man and help
|
- fix the conflict of man and help
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user