diff --git a/CVE-2020-10700-1.patch b/CVE-2020-10700-1.patch deleted file mode 100644 index 6c87ec7483f36dc7502aef4abacb2e5850ea80c0..0000000000000000000000000000000000000000 --- a/CVE-2020-10700-1.patch +++ /dev/null @@ -1,222 +0,0 @@ -From 0e77fa7747d789bd8c9256373498a352251f6877 Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -Date: Mon, 30 Mar 2020 09:44:20 +0000 -Subject: [PATCH 1/4] CVE-2020-10700: dsdb: Add test for ASQ and ASQ in - combination with paged_results - -Thanks to Andrei Popa for finding, -reporting and working with us to diagnose this issue! - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14331 - -Signed-off-by: Andrew Bartlett -Reviewed-by: Gary Lockyer ---- - selftest/knownfail.d/asq | 1 + - source4/dsdb/tests/python/asq.py | 171 +++++++++++++++++++++++++++++++ - source4/selftest/tests.py | 1 + - 3 files changed, 173 insertions(+) - create mode 100644 selftest/knownfail.d/asq - create mode 100644 source4/dsdb/tests/python/asq.py - -diff --git a/selftest/knownfail.d/asq b/selftest/knownfail.d/asq -new file mode 100644 -index 00000000000..eb0e3e0aba1 ---- /dev/null -+++ b/selftest/knownfail.d/asq -@@ -0,0 +1 @@ -+samba4.asq.python\(ad_dc_default\).__main__.ASQLDAPTest.test_asq_paged -\ No newline at end of file -diff --git a/source4/dsdb/tests/python/asq.py b/source4/dsdb/tests/python/asq.py -new file mode 100644 -index 00000000000..a32c9f40cd3 ---- /dev/null -+++ b/source4/dsdb/tests/python/asq.py -@@ -0,0 +1,171 @@ -+#!/usr/bin/env python3 -+# -+# Test ASQ LDAP control behaviour in Samba -+# Copyright (C) Andrew Bartlett 2019-2020 -+# -+# Based on Unit tests for the notification control -+# Copyright (C) Stefan Metzmacher 2016 -+# -+# 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 . -+ -+import optparse -+import sys -+import os -+import random -+ -+sys.path.insert(0, "bin/python") -+import samba -+from samba.tests.subunitrun import SubunitOptions, TestProgram -+ -+import samba.getopt as options -+ -+from samba.auth import system_session -+from samba import ldb -+from samba.samdb import SamDB -+from samba.ndr import ndr_unpack -+from samba import gensec -+from samba.credentials import Credentials -+import samba.tests -+ -+from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError -+from ldb import ERR_TIME_LIMIT_EXCEEDED, ERR_ADMIN_LIMIT_EXCEEDED, ERR_UNWILLING_TO_PERFORM -+from ldb import Message -+ -+parser = optparse.OptionParser("large_ldap.py [options] ") -+sambaopts = options.SambaOptions(parser) -+parser.add_option_group(sambaopts) -+parser.add_option_group(options.VersionOptions(parser)) -+# use command line creds if available -+credopts = options.CredentialsOptions(parser) -+parser.add_option_group(credopts) -+subunitopts = SubunitOptions(parser) -+parser.add_option_group(subunitopts) -+opts, args = parser.parse_args() -+ -+if len(args) < 1: -+ parser.print_usage() -+ sys.exit(1) -+ -+url = args[0] -+ -+lp = sambaopts.get_loadparm() -+creds = credopts.get_credentials(lp) -+ -+ -+class ASQLDAPTest(samba.tests.TestCase): -+ -+ def setUp(self): -+ super(ASQLDAPTest, self).setUp() -+ self.ldb = samba.Ldb(url, credentials=creds, session_info=system_session(lp), lp=lp) -+ self.base_dn = self.ldb.get_default_basedn() -+ self.NAME_ASQ="asq_" + format(random.randint(0, 99999), "05") -+ self.OU_NAME_ASQ= self.NAME_ASQ + "_ou" -+ self.ou_dn = ldb.Dn(self.ldb, "ou=" + self.OU_NAME_ASQ + "," + str(self.base_dn)) -+ -+ samba.tests.delete_force(self.ldb, self.ou_dn, -+ controls=['tree_delete:1']) -+ -+ self.ldb.add({ -+ "dn": self.ou_dn, -+ "objectclass": "organizationalUnit", -+ "ou": self.OU_NAME_ASQ}) -+ -+ self.members = [] -+ self.members2 = [] -+ -+ for x in range(20): -+ name = self.NAME_ASQ + "_" + str(x) -+ dn = ldb.Dn(self.ldb, -+ "cn=" + name + "," + str(self.ou_dn)) -+ self.members.append(dn) -+ self.ldb.add({ -+ "dn": dn, -+ "objectclass": "group"}) -+ -+ for x in range(20): -+ name = self.NAME_ASQ + "_" + str(x + 20) -+ dn = ldb.Dn(self.ldb, -+ "cn=" + name + "," + str(self.ou_dn)) -+ self.members2.append(dn) -+ self.ldb.add({ -+ "dn": dn, -+ "objectclass": "group", -+ "member": [str(x) for x in self.members]}) -+ -+ name = self.NAME_ASQ + "_" + str(x + 40) -+ self.top_dn = ldb.Dn(self.ldb, -+ "cn=" + name + "," + str(self.ou_dn)) -+ self.ldb.add({ -+ "dn": self.top_dn, -+ "objectclass": "group", -+ "member": [str(x) for x in self.members2]}) -+ -+ def tearDown(self): -+ samba.tests.delete_force(self.ldb, self.ou_dn, -+ controls=['tree_delete:1']) -+ -+ def test_asq(self): -+ """Testing ASQ behaviour. -+ -+ 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! -+ -+ """ -+ -+ msgs = self.ldb.search(base=self.top_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=["objectGUID", "cn", "member"], -+ controls=["asq:1:member"]) -+ -+ 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) -+ -+ def test_asq_paged(self): -+ """Testing ASQ behaviour with 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! -+ -+ """ -+ -+ msgs = self.ldb.search(base=self.top_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=["objectGUID", "cn", "member"], -+ controls=["asq:1:member", -+ "paged_results:1:1024"]) -+ -+ 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 -+ else: -+ url = "ldap://%s" % url -+ -+TestProgram(module=__name__, opts=subunitopts) -diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py -index ae2b10ae659..52db18a872b 100755 ---- a/source4/selftest/tests.py -+++ b/source4/selftest/tests.py -@@ -885,6 +885,7 @@ plantestsuite_loadlist("samba4.tokengroups.krb5.python(ad_dc_default)", "ad_dc_d - plantestsuite_loadlist("samba4.tokengroups.ntlm.python(ad_dc_default)", "ad_dc_default:local", [python, os.path.join(DSDB_PYTEST_DIR, "token_group.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '-k', 'no', '$LOADLIST', '$LISTOPT']) - plantestsuite("samba4.sam.python(fl2008r2dc)", "fl2008r2dc", [python, os.path.join(DSDB_PYTEST_DIR, "sam.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) - plantestsuite("samba4.sam.python(ad_dc_default)", "ad_dc_default", [python, os.path.join(DSDB_PYTEST_DIR, "sam.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) -+plantestsuite("samba4.asq.python(ad_dc_default)", "ad_dc_default", [python, os.path.join(DSDB_PYTEST_DIR, "asq.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) - plantestsuite("samba4.user_account_control.python(ad_dc_default)", "ad_dc_default", [python, os.path.join(DSDB_PYTEST_DIR, "user_account_control.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) - - for env in ['ad_dc_default:local', 'schema_dc:local']: --- -2.17.1 - - diff --git a/CVE-2020-10700-3.patch b/CVE-2020-10700-3.patch deleted file mode 100644 index 5782dc70236c714d98056b020cf46a846d6cfde1..0000000000000000000000000000000000000000 --- a/CVE-2020-10700-3.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 34f9e6e969913629f9241522020c5895dc9636dc Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -Date: Wed, 11 Mar 2020 16:43:31 +1300 -Subject: [PATCH 3/4] CVE-2020-10700: dsdb: Do not permit the ASQ control for - the GUID search in paged_results - -ASQ is a very strange control and a BASE search can return multiple results -that are NOT the requested DN, but the DNs pointed to by it! - -Thanks to Andrei Popa for finding, -reporting and working with us to diagnose this issue! - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14331 - -Signed-off-by: Andrew Bartlett -Reviewed-by: Gary Lockyer ---- - selftest/knownfail.d/asq | 1 - - source4/dsdb/samdb/ldb_modules/paged_results.c | 18 +++++++++++++----- - 2 files changed, 13 insertions(+), 6 deletions(-) - delete mode 100644 selftest/knownfail.d/asq - -diff --git a/selftest/knownfail.d/asq b/selftest/knownfail.d/asq -deleted file mode 100644 -index eb0e3e0aba1..00000000000 ---- a/selftest/knownfail.d/asq -+++ /dev/null -@@ -1 +0,0 @@ --samba4.asq.python\(ad_dc_default\).__main__.ASQLDAPTest.test_asq_paged -\ No newline at end of file -diff --git a/source4/dsdb/samdb/ldb_modules/paged_results.c b/source4/dsdb/samdb/ldb_modules/paged_results.c -index 940d2254fb0..dc211dd18ce 100644 ---- a/source4/dsdb/samdb/ldb_modules/paged_results.c -+++ b/source4/dsdb/samdb/ldb_modules/paged_results.c -@@ -483,8 +483,14 @@ paged_results_copy_down_controls(TALLOC_CTX *mem_ctx, - if (control->oid == NULL) { - continue; - } -- if (strncmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID, -- sizeof(LDB_CONTROL_PAGED_RESULTS_OID)) == 0) { -+ if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) { -+ continue; -+ } -+ /* -+ * ASQ changes everything, do not copy it down for the -+ * per-GUID search -+ */ -+ if (strcmp(control->oid, LDB_CONTROL_ASQ_OID) == 0) { - continue; - } - new_controls[j] = talloc_steal(new_controls, control); -@@ -534,21 +540,23 @@ static bool paged_controls_same(struct ldb_request *req, - - num_non_null_req_controls = 0; - for (i=0; req->controls[i] != NULL; i++) { -- if (req->controls[i]->oid != NULL) { -+ if (req->controls[i]->oid != NULL && -+ strcmp(req->controls[i]->oid, -+ LDB_CONTROL_ASQ_OID) != 0) { - num_non_null_req_controls++; - } - } - - /* At this point we have the number of non-null entries for both - * control lists and we know that: -- * 1. down_controls does not contain the paged control -+ * 1. down_controls does not contain the paged control or ASQ - * (because paged_results_copy_down_controls excludes it) - * 2. req->controls does contain the paged control - * (because this function is only called if this is true) - * 3. down_controls is a subset of non-null controls in req->controls - * (checked above) - * So to confirm that the two lists are identical except for the paged -- * control, all we need to check is: */ -+ * control and possibly ASQ, all we need to check is: */ - if (num_non_null_req_controls == num_down_controls + 1) { - return true; - } --- -2.17.1 - - diff --git a/CVE-2020-10704-1.patch b/CVE-2020-10704-1.patch deleted file mode 100644 index a19ca621697abb001a6447c921220d0d39a37d86..0000000000000000000000000000000000000000 --- a/CVE-2020-10704-1.patch +++ /dev/null @@ -1,547 +0,0 @@ -From b01952c6fb15b92fff3ad1bf8f1cf579875e5483 Mon Sep 17 00:00:00 2001 -From: Gary Lockyer -Date: Fri, 3 Apr 2020 12:18:03 +1300 -Subject: [PATCH 1/8] CVE-2020-10704: lib util asn1: Add ASN.1 max tree depth - -Add maximum parse tree depth to the call to asn1_init, which will be -used to limit the depth of the ASN.1 parse tree. - -Credit to OSS-Fuzz - -REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334 - -Signed-off-by: Gary Lockyer -Reviewed-by: Andrew Bartlett ---- - auth/gensec/gensec_util.c | 2 +- - lib/util/asn1.c | 17 +++++++++- - lib/util/asn1.h | 9 +++++- - lib/util/tests/asn1_tests.c | 2 +- - libcli/auth/spnego_parse.c | 6 ++-- - libcli/cldap/cldap.c | 2 +- - libcli/ldap/ldap_message.c | 2 +- - source3/lib/tldap.c | 4 +-- - source3/lib/tldap_util.c | 4 +-- - source3/libsmb/clispnego.c | 4 +-- - source3/torture/torture.c | 2 +- - source4/auth/gensec/gensec_krb5.c | 4 +-- - source4/ldap_server/ldap_server.c | 2 +- - source4/libcli/ldap/ldap_client.c | 2 +- - source4/libcli/ldap/ldap_controls.c | 48 ++++++++++++++--------------- - 15 files changed, 66 insertions(+), 44 deletions(-) - -diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c -index 20c9c2a1fbb..e185acc0c20 100644 ---- a/auth/gensec/gensec_util.c -+++ b/auth/gensec/gensec_util.c -@@ -76,7 +76,7 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx, - static bool gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid) - { - bool ret = false; -- struct asn1_data *data = asn1_init(NULL); -+ struct asn1_data *data = asn1_init(NULL, ASN1_MAX_TREE_DEPTH); - - if (!data) return false; - -diff --git a/lib/util/asn1.c b/lib/util/asn1.c -index 51da5424956..ec6e674ce20 100644 ---- a/lib/util/asn1.c -+++ b/lib/util/asn1.c -@@ -36,15 +36,19 @@ struct asn1_data { - off_t ofs; - struct nesting *nesting; - bool has_error; -+ unsigned depth; -+ unsigned max_depth; - }; - - /* allocate an asn1 structure */ --struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx) -+struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx, unsigned max_depth) - { - struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data); - if (ret == NULL) { - DEBUG(0,("asn1_init failed! out of memory\n")); -+ return ret; - } -+ ret->max_depth = max_depth; - return ret; - } - -@@ -480,6 +484,11 @@ bool asn1_check_BOOLEAN(struct asn1_data *data, bool v) - /* load a struct asn1_data structure with a lump of data, ready to be parsed */ - bool asn1_load(struct asn1_data *data, DATA_BLOB blob) - { -+ /* -+ * Save the maximum depth -+ */ -+ unsigned max_depth = data->max_depth; -+ - ZERO_STRUCTP(data); - data->data = (uint8_t *)talloc_memdup(data, blob.data, blob.length); - if (!data->data) { -@@ -487,6 +496,7 @@ bool asn1_load(struct asn1_data *data, DATA_BLOB blob) - return false; - } - data->length = blob.length; -+ data->max_depth = max_depth; - return true; - } - -@@ -1103,9 +1113,14 @@ bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, - */ - void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len) - { -+ /* -+ * Save max_depth -+ */ -+ unsigned max_depth = data->max_depth; - ZERO_STRUCTP(data); - data->data = buf; - data->length = len; -+ data->max_depth = max_depth; - } - - int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) -diff --git a/lib/util/asn1.h b/lib/util/asn1.h -index ddd69863574..fc365724e93 100644 ---- a/lib/util/asn1.h -+++ b/lib/util/asn1.h -@@ -45,7 +45,14 @@ typedef struct asn1_data ASN1_DATA; - - #define ASN1_MAX_OIDS 20 - --struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx); -+/* -+ * The maximum permitted depth for an ASN.1 parse tree, the limit is chosen -+ * to align with the value for windows. Note that this value will trigger -+ * ASAN stack overflow errors. -+ */ -+#define ASN1_MAX_TREE_DEPTH 512 -+ -+struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx, unsigned max_depth); - void asn1_free(struct asn1_data *data); - bool asn1_has_error(const struct asn1_data *data); - void asn1_set_error(struct asn1_data *data); -diff --git a/lib/util/tests/asn1_tests.c b/lib/util/tests/asn1_tests.c -index e4b386ad785..ab5262c4ffb 100644 ---- a/lib/util/tests/asn1_tests.c -+++ b/lib/util/tests/asn1_tests.c -@@ -330,7 +330,7 @@ static bool test_asn1_Integer(struct torture_context *tctx) - DATA_BLOB blob; - int val; - -- data = asn1_init(mem_ctx); -+ data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - if (!data) { - goto err; - } -diff --git a/libcli/auth/spnego_parse.c b/libcli/auth/spnego_parse.c -index f538b44552c..f7f19b10778 100644 ---- a/libcli/auth/spnego_parse.c -+++ b/libcli/auth/spnego_parse.c -@@ -296,7 +296,7 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data - return ret; - } - -- asn1 = asn1_init(mem_ctx); -+ asn1 = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - if (asn1 == NULL) { - return -1; - } -@@ -339,7 +339,7 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data - - ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_data *spnego) - { -- struct asn1_data *asn1 = asn1_init(mem_ctx); -+ struct asn1_data *asn1 = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - ssize_t ret = -1; - - if (asn1 == NULL) { -@@ -411,7 +411,7 @@ bool spnego_write_mech_types(TALLOC_CTX *mem_ctx, - DATA_BLOB *blob) - { - bool ret = false; -- struct asn1_data *asn1 = asn1_init(mem_ctx); -+ struct asn1_data *asn1 = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - - if (asn1 == NULL) { - return false; -diff --git a/libcli/cldap/cldap.c b/libcli/cldap/cldap.c -index daba37a21d7..8fa9ce0b273 100644 ---- a/libcli/cldap/cldap.c -+++ b/libcli/cldap/cldap.c -@@ -229,7 +229,7 @@ static bool cldap_socket_recv_dgram(struct cldap_socket *c, - goto error; - } - -- asn1 = asn1_init(in); -+ asn1 = asn1_init(in, ASN1_MAX_TREE_DEPTH); - if (!asn1) { - goto nomem; - } -diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c -index f21598374a1..ba82bddeab1 100644 ---- a/libcli/ldap/ldap_message.c -+++ b/libcli/ldap/ldap_message.c -@@ -390,7 +390,7 @@ _PUBLIC_ bool ldap_encode(struct ldap_message *msg, - const struct ldap_control_handler *control_handlers, - DATA_BLOB *result, TALLOC_CTX *mem_ctx) - { -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - int i, j; - - if (!data) return false; -diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c -index d6c6e8859a6..bf5fc05d785 100644 ---- a/source3/lib/tldap.c -+++ b/source3/lib/tldap.c -@@ -632,7 +632,7 @@ static void tldap_msg_received(struct tevent_req *subreq) - goto fail; - } - -- data = asn1_init(talloc_tos()); -+ data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH); - if (data == NULL) { - status = TLDAP_NO_MEMORY; - goto fail; -@@ -763,7 +763,7 @@ static struct tevent_req *tldap_req_create(TALLOC_CTX *mem_ctx, - if (req == NULL) { - return NULL; - } -- state->out = asn1_init(state); -+ state->out = asn1_init(state, ASN1_MAX_TREE_DEPTH); - if (state->out == NULL) { - goto err; - } -diff --git a/source3/lib/tldap_util.c b/source3/lib/tldap_util.c -index 1b86962a32e..168932a8a96 100644 ---- a/source3/lib/tldap_util.c -+++ b/source3/lib/tldap_util.c -@@ -644,7 +644,7 @@ static struct tevent_req *tldap_ship_paged_search( - struct tldap_control *pgctrl; - struct asn1_data *asn1 = NULL; - -- asn1 = asn1_init(state); -+ asn1 = asn1_init(state, ASN1_MAX_TREE_DEPTH); - if (asn1 == NULL) { - return NULL; - } -@@ -783,7 +783,7 @@ static void tldap_search_paged_done(struct tevent_req *subreq) - - TALLOC_FREE(state->cookie.data); - -- asn1 = asn1_init(talloc_tos()); -+ asn1 = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH); - if (tevent_req_nomem(asn1, req)) { - return; - } -diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c -index 4a0fbcd73af..1608f6a9960 100644 ---- a/source3/libsmb/clispnego.c -+++ b/source3/libsmb/clispnego.c -@@ -50,7 +50,7 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx, - *secblob = data_blob_null; - } - -- data = asn1_init(talloc_tos()); -+ data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH); - if (data == NULL) { - return false; - } -@@ -171,7 +171,7 @@ DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const ui - ASN1_DATA *data; - DATA_BLOB ret = data_blob_null; - -- data = asn1_init(talloc_tos()); -+ data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH); - if (data == NULL) { - return data_blob_null; - } -diff --git a/source3/torture/torture.c b/source3/torture/torture.c -index a795e61125f..c4b0a7bc4f9 100644 ---- a/source3/torture/torture.c -+++ b/source3/torture/torture.c -@@ -11370,7 +11370,7 @@ tldap_build_extended_control(enum tldap_extended_val val) - ZERO_STRUCT(empty_control); - - if (val != EXTENDED_NONE) { -- data = asn1_init(talloc_tos()); -+ data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH); - - if (!data) { - return NULL; -diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c -index 0323da87d29..b735063656a 100644 ---- a/source4/auth/gensec/gensec_krb5.c -+++ b/source4/auth/gensec/gensec_krb5.c -@@ -444,7 +444,7 @@ static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLO - struct asn1_data *data; - DATA_BLOB ret = data_blob_null; - -- data = asn1_init(mem_ctx); -+ data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - if (!data || !ticket->data) { - return ret; - } -@@ -478,7 +478,7 @@ static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLO - static bool gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8_t tok_id[2]) - { - bool ret = false; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - int data_remaining; - - if (!data) { -diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c -index 709b7bcacfa..6d329329909 100644 ---- a/source4/ldap_server/ldap_server.c -+++ b/source4/ldap_server/ldap_server.c -@@ -560,7 +560,7 @@ static void ldapsrv_call_read_done(struct tevent_req *subreq) - return; - } - -- asn1 = asn1_init(call); -+ asn1 = asn1_init(call, ASN1_MAX_TREE_DEPTH); - if (asn1 == NULL) { - ldapsrv_terminate_connection(conn, "no memory"); - return; -diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c -index da84adc7769..2d75af6af6e 100644 ---- a/source4/libcli/ldap/ldap_client.c -+++ b/source4/libcli/ldap/ldap_client.c -@@ -284,7 +284,7 @@ static void ldap_connection_recv_done(struct tevent_req *subreq) - return; - } - -- asn1 = asn1_init(conn); -+ asn1 = asn1_init(conn, ASN1_MAX_TREE_DEPTH); - if (asn1 == NULL) { - TALLOC_FREE(msg); - ldap_error_handler(conn, NT_STATUS_NO_MEMORY); -diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c -index 716ca148308..df012a158e0 100644 ---- a/source4/libcli/ldap/ldap_controls.c -+++ b/source4/libcli/ldap/ldap_controls.c -@@ -32,7 +32,7 @@ static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out) - { - void **out = (void **)_out; - DATA_BLOB attr; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - struct ldb_sort_resp_control *lsrc; - - if (!data) return false; -@@ -79,7 +79,7 @@ static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void *_out) - void **out = (void **)_out; - DATA_BLOB attr; - DATA_BLOB rule; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - struct ldb_server_sort_control **lssc; - int num; - -@@ -166,7 +166,7 @@ static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out) - return true; - } - -- data = asn1_init(mem_ctx); -+ data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - if (!data) return false; - - if (!asn1_load(data, in)) { -@@ -198,7 +198,7 @@ static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out) - static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out) - { - void **out = (void **)_out; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - struct ldb_sd_flags_control *lsdfc; - - if (!data) return false; -@@ -232,7 +232,7 @@ static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out) - static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void *_out) - { - void **out = (void **)_out; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - struct ldb_search_options_control *lsoc; - - if (!data) return false; -@@ -267,7 +267,7 @@ static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void *_out - { - void **out = (void **)_out; - DATA_BLOB cookie; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - struct ldb_paged_control *lprc; - - if (!data) return false; -@@ -316,7 +316,7 @@ static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void *_out) - { - void **out = (void **)_out; - DATA_BLOB cookie; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - struct ldb_dirsync_control *ldc; - - if (!data) return false; -@@ -372,7 +372,7 @@ static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out) - { - void **out = (void **)_out; - DATA_BLOB source_attribute; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - struct ldb_asq_control *lac; - - if (!data) return false; -@@ -433,7 +433,7 @@ static bool decode_verify_name_request(void *mem_ctx, DATA_BLOB in, void *_out) - { - void **out = (void **)_out; - DATA_BLOB name; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - struct ldb_verify_name_control *lvnc; - int len; - -@@ -485,7 +485,7 @@ static bool decode_verify_name_request(void *mem_ctx, DATA_BLOB in, void *_out) - static bool encode_verify_name_request(void *mem_ctx, void *in, DATA_BLOB *out) - { - struct ldb_verify_name_control *lvnc = talloc_get_type(in, struct ldb_verify_name_control); -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - DATA_BLOB gc_utf16; - - if (!data) return false; -@@ -528,7 +528,7 @@ static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out) - { - void **out = (void **)_out; - DATA_BLOB assertion_value, context_id; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - struct ldb_vlv_req_control *lvrc; - - if (!data) return false; -@@ -626,7 +626,7 @@ static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out) - { - void **out = (void **)_out; - DATA_BLOB context_id; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - struct ldb_vlv_resp_control *lvrc; - - if (!data) return false; -@@ -682,7 +682,7 @@ static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out) - static bool encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) - { - struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control); -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - - if (!data) return false; - -@@ -716,7 +716,7 @@ static bool encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) - static bool encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) - { - struct ldb_server_sort_control **lssc = talloc_get_type(in, struct ldb_server_sort_control *); -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - int num; - - if (!data) return false; -@@ -782,7 +782,7 @@ static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) - return true; - } - -- data = asn1_init(mem_ctx); -+ data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - - if (!data) return false; - -@@ -810,7 +810,7 @@ static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) - static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) - { - struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control); -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - - if (!data) return false; - -@@ -838,7 +838,7 @@ static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) - static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out) - { - struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control); -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - - if (!data) return false; - -@@ -866,7 +866,7 @@ static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *ou - static bool encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out) - { - struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control); -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - - if (!data) return false; - -@@ -901,7 +901,7 @@ static bool encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out - static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) - { - struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control); -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - - if (!data) return false; - -@@ -936,7 +936,7 @@ static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) - static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) - { - struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control); -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - - if (!data) return false; - -@@ -972,7 +972,7 @@ static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) - static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) - { - struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control); -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - - if (!data) return false; - -@@ -1040,7 +1040,7 @@ static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) - static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) - { - struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control); -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - - if (!data) return false; - -@@ -1083,7 +1083,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out) - { - struct dsdb_openldap_dereference_control *control = talloc_get_type(in, struct dsdb_openldap_dereference_control); - int i,j; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - - if (!data) return false; - -@@ -1132,7 +1132,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out) - static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out) - { - void **out = (void **)_out; -- struct asn1_data *data = asn1_init(mem_ctx); -+ struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH); - struct dsdb_openldap_dereference_result_control *control; - struct dsdb_openldap_dereference_result **r = NULL; - int i = 0; --- -2.17.1 - - diff --git a/CVE-2020-10704-3.patch b/CVE-2020-10704-3.patch deleted file mode 100644 index a0b866daa307e364462dd0ca1cdc3e2d60dfb3aa..0000000000000000000000000000000000000000 --- a/CVE-2020-10704-3.patch +++ /dev/null @@ -1,52 +0,0 @@ -Backport of: - -From d3be674c3ffa3541e2ba757e2c6dfb32508db440 Mon Sep 17 00:00:00 2001 -From: Gary Lockyer -Date: Wed, 8 Apr 2020 15:30:52 +1200 -Subject: [PATCH 3/8] CVE-2020-10704: lib util asn1: Check parse tree depth - -Check the current depth of the parse tree and reject the input if the -depth exceeds that passed to asn1_init - -Credit to OSS-Fuzz - -REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334 - -Signed-off-by: Gary Lockyer -Reviewed-by: Andrew Bartlett ---- - lib/util/asn1.c | 13 +++++++++++++ - selftest/knownfail.d/ldap_message | 2 -- - 2 files changed, 13 insertions(+), 2 deletions(-) - delete mode 100644 selftest/knownfail.d/ldap_message - ---- a/lib/util/asn1.c -+++ b/lib/util/asn1.c -@@ -647,6 +647,16 @@ bool asn1_start_tag(struct asn1_data *da - uint8_t b; - struct nesting *nesting; - -+ /* -+ * Check the depth of the parse tree and prevent it from growing -+ * too large. -+ */ -+ data->depth++; -+ if (data->depth > data->max_depth) { -+ data->has_error = true; -+ return false; -+ } -+ - if (!asn1_read_uint8(data, &b)) - return false; - -@@ -703,6 +713,9 @@ bool asn1_end_tag(struct asn1_data *data - { - struct nesting *nesting; - -+ if (data->depth > 0) { -+ data->depth--; -+ } - /* make sure we read it all */ - if (asn1_tag_remaining(data) != 0) { - data->has_error = true; diff --git a/CVE-2020-10704-5.patch b/CVE-2020-10704-5.patch deleted file mode 100644 index fd98adacb072c805002f042c3928b08d4a4b3208..0000000000000000000000000000000000000000 --- a/CVE-2020-10704-5.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 9944df6ef1e421331ea1ca773f7e5652262d5d1b Mon Sep 17 00:00:00 2001 -From: Gary Lockyer -Date: Tue, 7 Apr 2020 09:09:01 +1200 -Subject: [PATCH 5/8] CVE-2020-10704: smb.conf: Add max ldap request sizes - -Add two new smb.conf parameters to control the maximum permitted ldap -request size. - -Adds: - ldap max anonymous request size default 250Kb - ldap max authenticated request size default 16Mb - -Credit to OSS-Fuzz - -REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334 - -Signed-off-by: Gary Lockyer -Reviewed-by: Andrew Bartlett ---- - .../smbdotconf/ldap/ldapmaxanonrequest.xml | 18 ++++++++++++++++++ - .../smbdotconf/ldap/ldapmaxauthrequest.xml | 18 ++++++++++++++++++ - lib/param/loadparm.c | 5 +++++ - source3/param/loadparm.c | 3 +++ - 4 files changed, 44 insertions(+) - create mode 100644 docs-xml/smbdotconf/ldap/ldapmaxanonrequest.xml - create mode 100644 docs-xml/smbdotconf/ldap/ldapmaxauthrequest.xml - ---- /dev/null -+++ b/docs-xml/smbdotconf/ldap/ldapmaxanonrequest.xml -@@ -0,0 +1,18 @@ -+ -+ -+ -+ This parameter specifies the maximum permitted size (in bytes) -+ for an LDAP request received on an anonymous connection. -+ -+ -+ -+ If the request size exceeds this limit the request will be -+ rejected. -+ -+ -+256000 -+500000 -+ ---- /dev/null -+++ b/docs-xml/smbdotconf/ldap/ldapmaxauthrequest.xml -@@ -0,0 +1,18 @@ -+ -+ -+ -+ This parameter specifies the maximum permitted size (in bytes) -+ for an LDAP request received on an authenticated connection. -+ -+ -+ -+ If the request size exceeds this limit the request will be -+ rejected. -+ -+ -+16777216 -+4194304 -+ ---- a/lib/param/loadparm.c -+++ b/lib/param/loadparm.c -@@ -3027,6 +3027,11 @@ struct loadparm_context *loadparm_init(T - - lpcfg_do_global_parameter(lp_ctx, "debug encryption", "no"); - -+ lpcfg_do_global_parameter( -+ lp_ctx, "ldap max anonymous request size", "256000"); -+ lpcfg_do_global_parameter( -+ lp_ctx, "ldap max authenticated request size", "16777216"); -+ - for (i = 0; parm_table[i].label; i++) { - if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) { - lp_ctx->flags[i] |= FLAG_DEFAULT; ---- a/source3/param/loadparm.c -+++ b/source3/param/loadparm.c -@@ -956,6 +956,9 @@ static void init_globals(struct loadparm - Globals.prefork_backoff_increment = 10; - Globals.prefork_maximum_backoff = 120; - -+ Globals.ldap_max_anonymous_request_size = 256000; -+ Globals.ldap_max_authenticated_request_size = 16777216; -+ - /* Now put back the settings that were set with lp_set_cmdline() */ - apply_lp_set_cmdline(); - } diff --git a/CVE-2020-10704-6.patch b/CVE-2020-10704-6.patch deleted file mode 100644 index 350a78ea7d0ecfff64651473ed09c122910a4bf4..0000000000000000000000000000000000000000 --- a/CVE-2020-10704-6.patch +++ /dev/null @@ -1,163 +0,0 @@ -Backport of: - -From 85619363d3280346b2253fe44bf67d4881a53ebd Mon Sep 17 00:00:00 2001 -From: Gary Lockyer -Date: Wed, 8 Apr 2020 15:32:22 +1200 -Subject: [PATCH 6/8] CVE-2020-10704: S4 ldap server: Limit request sizes - -Check the size of authenticated and anonymous ldap requests and reject -them if they exceed the limits in smb.conf - -Credit to OSS-Fuzz - -REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334 - -Signed-off-by: Gary Lockyer -Reviewed-by: Andrew Bartlett ---- - selftest/knownfail.d/ldap_raw | 1 - - source4/ldap_server/ldap_server.c | 96 ++++++++++++++++++++++++++++++- - 2 files changed, 95 insertions(+), 2 deletions(-) - delete mode 100644 selftest/knownfail.d/ldap_raw - ---- a/source4/ldap_server/ldap_server.c -+++ b/source4/ldap_server/ldap_server.c -@@ -441,6 +441,10 @@ static void ldapsrv_accept_tls_done(stru - } - - static void ldapsrv_call_read_done(struct tevent_req *subreq); -+static NTSTATUS ldapsrv_packet_check( -+ void *private_data, -+ DATA_BLOB blob, -+ size_t *packet_size); - - static bool ldapsrv_call_read_next(struct ldapsrv_connection *conn) - { -@@ -494,7 +498,7 @@ static bool ldapsrv_call_read_next(struc - conn->connection->event.ctx, - conn->sockets.active, - 7, /* initial_read_size */ -- ldap_full_packet, -+ ldapsrv_packet_check, - conn); - if (subreq == NULL) { - ldapsrv_terminate_connection(conn, "ldapsrv_call_read_next: " -@@ -520,6 +524,9 @@ static bool ldapsrv_call_read_next(struc - } - - static void ldapsrv_call_process_done(struct tevent_req *subreq); -+static int ldapsrv_check_packet_size( -+ struct ldapsrv_connection *conn, -+ size_t size); - - static void ldapsrv_call_read_done(struct tevent_req *subreq) - { -@@ -530,6 +537,7 @@ static void ldapsrv_call_read_done(struc - struct ldapsrv_call *call; - struct asn1_data *asn1; - DATA_BLOB blob; -+ int ret = LDAP_SUCCESS; - - conn->sockets.read_req = NULL; - -@@ -560,6 +568,14 @@ static void ldapsrv_call_read_done(struc - return; - } - -+ ret = ldapsrv_check_packet_size(conn, blob.length); -+ if (ret != LDAP_SUCCESS) { -+ ldapsrv_terminate_connection( -+ conn, -+ "Request packet too large"); -+ return; -+ } -+ - asn1 = asn1_init(call, ASN1_MAX_TREE_DEPTH); - if (asn1 == NULL) { - ldapsrv_terminate_connection(conn, "no memory"); -@@ -1362,6 +1378,84 @@ static void ldapsrv_post_fork(struct tas - } - } - -+/* -+ * Check the size of an ldap request packet. -+ * -+ * For authenticated connections the maximum packet size is controlled by -+ * the smb.conf parameter "ldap max authenticated request size" -+ * -+ * For anonymous connections the maximum packet size is controlled by -+ * the smb.conf parameter "ldap max anonymous request size" -+ */ -+static int ldapsrv_check_packet_size( -+ struct ldapsrv_connection *conn, -+ size_t size) -+{ -+ bool is_anonymous = false; -+ size_t max_size = 0; -+ -+ max_size = lpcfg_ldap_max_anonymous_request_size(conn->lp_ctx); -+ if (size <= max_size) { -+ return LDAP_SUCCESS; -+ } -+ -+ /* -+ * Request is larger than the maximum unauthenticated request size. -+ * As this code is called frequently we avoid calling -+ * security_token_is_anonymous if possible -+ */ -+ if (conn->session_info != NULL && -+ conn->session_info->security_token != NULL) { -+ is_anonymous = security_token_is_anonymous( -+ conn->session_info->security_token); -+ } -+ -+ if (is_anonymous) { -+ DBG_WARNING( -+ "LDAP request size (%zu) exceeds (%zu)\n", -+ size, -+ max_size); -+ return LDAP_UNWILLING_TO_PERFORM; -+ } -+ -+ max_size = lpcfg_ldap_max_authenticated_request_size(conn->lp_ctx); -+ if (size > max_size) { -+ DBG_WARNING( -+ "LDAP request size (%zu) exceeds (%zu)\n", -+ size, -+ max_size); -+ return LDAP_UNWILLING_TO_PERFORM; -+ } -+ return LDAP_SUCCESS; -+ -+} -+ -+/* -+ * Check that the blob contains enough data to be a valid packet -+ * If there is a packet header check the size to ensure that it does not -+ * exceed the maximum sizes. -+ * -+ */ -+static NTSTATUS ldapsrv_packet_check( -+ void *private_data, -+ DATA_BLOB blob, -+ size_t *packet_size) -+{ -+ NTSTATUS ret; -+ struct ldapsrv_connection *conn = private_data; -+ int result = LDB_SUCCESS; -+ -+ ret = ldap_full_packet(private_data, blob, packet_size); -+ if (!NT_STATUS_IS_OK(ret)) { -+ return ret; -+ } -+ result = ldapsrv_check_packet_size(conn, *packet_size); -+ if (result != LDAP_SUCCESS) { -+ return NT_STATUS_LDAP(result); -+ } -+ return NT_STATUS_OK; -+} -+ - NTSTATUS server_service_ldap_init(TALLOC_CTX *ctx) - { - static const struct service_details details = { diff --git a/CVE-2020-10704-7.patch b/CVE-2020-10704-7.patch deleted file mode 100644 index a2c72e619f561d2e14ff12da4512f372fd0d4468..0000000000000000000000000000000000000000 --- a/CVE-2020-10704-7.patch +++ /dev/null @@ -1,211 +0,0 @@ -Backport of: - -From 9be121c7055fde841be15f8d570ff49801b68bff Mon Sep 17 00:00:00 2001 -From: Gary Lockyer -Date: Wed, 8 Apr 2020 08:49:23 +1200 -Subject: [PATCH 7/8] CVE-2020-10704: libcli ldap_message: Add search size - limits to ldap_decode - -Add search request size limits to ldap_decode calls. - -The ldap server uses the smb.conf variable -"ldap max search request size" which defaults to 250Kb. -For cldap the limit is hard coded as 4096. - -Credit to OSS-Fuzz - -REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334 - -Signed-off-by: Gary Lockyer -Reviewed-by: Andrew Bartlett ---- - .../smbdotconf/ldap/ldapmaxsearchrequest.xml | 18 ++++++++++++++ - lib/param/loadparm.c | 2 ++ - libcli/cldap/cldap.c | 18 +++++++++++--- - libcli/ldap/ldap_message.c | 1 + - libcli/ldap/ldap_message.h | 5 ++++ - libcli/ldap/tests/ldap_message_test.c | 24 +++++++++++++++---- - source3/param/loadparm.c | 1 + - source4/ldap_server/ldap_server.c | 10 ++++++-- - source4/libcli/ldap/ldap_client.c | 3 ++- - 9 files changed, 72 insertions(+), 10 deletions(-) - create mode 100644 docs-xml/smbdotconf/ldap/ldapmaxsearchrequest.xml - ---- /dev/null -+++ b/docs-xml/smbdotconf/ldap/ldapmaxsearchrequest.xml -@@ -0,0 +1,18 @@ -+ -+ -+ -+ This parameter specifies the maximum permitted size (in bytes) -+ for an LDAP search request. -+ -+ -+ -+ If the request size exceeds this limit the request will be -+ rejected. -+ -+ -+256000 -+4194304 -+ ---- a/lib/param/loadparm.c -+++ b/lib/param/loadparm.c -@@ -3031,6 +3031,8 @@ struct loadparm_context *loadparm_init(T - lp_ctx, "ldap max anonymous request size", "256000"); - lpcfg_do_global_parameter( - lp_ctx, "ldap max authenticated request size", "16777216"); -+ lpcfg_do_global_parameter( -+ lp_ctx, "ldap max search request size", "256000"); - - for (i = 0; parm_table[i].label; i++) { - if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) { ---- a/libcli/cldap/cldap.c -+++ b/libcli/cldap/cldap.c -@@ -111,6 +111,11 @@ struct cldap_search_state { - struct tevent_req *req; - }; - -+/* -+ * For CLDAP we limit the maximum search request size to 4kb -+ */ -+#define MAX_SEARCH_REQUEST 4096 -+ - static int cldap_socket_destructor(struct cldap_socket *c) - { - while (c->searches.list) { -@@ -224,6 +229,9 @@ static bool cldap_socket_recv_dgram(stru - void *p; - struct cldap_search_state *search; - NTSTATUS status; -+ struct ldap_request_limits limits = { -+ .max_search_size = MAX_SEARCH_REQUEST -+ }; - - if (in->recv_errno != 0) { - goto error; -@@ -242,7 +250,7 @@ static bool cldap_socket_recv_dgram(stru - } - - /* this initial decode is used to find the message id */ -- status = ldap_decode(asn1, NULL, in->ldap_msg); -+ status = ldap_decode(asn1, &limits, NULL, in->ldap_msg); - if (!NT_STATUS_IS_OK(status)) { - goto nterror; - } -@@ -770,6 +778,9 @@ NTSTATUS cldap_search_recv(struct tevent - struct cldap_search_state); - struct ldap_message *ldap_msg; - NTSTATUS status; -+ struct ldap_request_limits limits = { -+ .max_search_size = MAX_SEARCH_REQUEST -+ }; - - if (tevent_req_is_nterror(req, &status)) { - goto failed; -@@ -780,7 +791,7 @@ NTSTATUS cldap_search_recv(struct tevent - goto nomem; - } - -- status = ldap_decode(state->response.asn1, NULL, ldap_msg); -+ status = ldap_decode(state->response.asn1, &limits, NULL, ldap_msg); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } -@@ -796,7 +807,8 @@ NTSTATUS cldap_search_recv(struct tevent - *io->out.response = ldap_msg->r.SearchResultEntry; - - /* decode the 2nd part */ -- status = ldap_decode(state->response.asn1, NULL, ldap_msg); -+ status = ldap_decode( -+ state->response.asn1, &limits, NULL, ldap_msg); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } ---- a/libcli/ldap/ldap_message.c -+++ b/libcli/ldap/ldap_message.c -@@ -1162,6 +1162,7 @@ static bool ldap_decode_attribs(TALLOC_C - /* This routine returns LDAP status codes */ - - _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, -+ const struct ldap_request_limits *limits, - const struct ldap_control_handler *control_handlers, - struct ldap_message *msg) - { ---- a/libcli/ldap/ldap_message.h -+++ b/libcli/ldap/ldap_message.h -@@ -213,10 +213,15 @@ struct ldap_control_handler { - bool (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); - }; - -+struct ldap_request_limits { -+ unsigned max_search_size; -+}; -+ - struct asn1_data; - - struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); - NTSTATUS ldap_decode(struct asn1_data *data, -+ const struct ldap_request_limits *limits, - const struct ldap_control_handler *control_handlers, - struct ldap_message *msg); - bool ldap_encode(struct ldap_message *msg, ---- a/source3/param/loadparm.c -+++ b/source3/param/loadparm.c -@@ -958,6 +958,7 @@ static void init_globals(struct loadparm - - Globals.ldap_max_anonymous_request_size = 256000; - Globals.ldap_max_authenticated_request_size = 16777216; -+ Globals.ldap_max_search_request_size = 256000; - - /* Now put back the settings that were set with lp_set_cmdline() */ - apply_lp_set_cmdline(); ---- a/source4/ldap_server/ldap_server.c -+++ b/source4/ldap_server/ldap_server.c -@@ -538,6 +538,7 @@ static void ldapsrv_call_read_done(struc - struct asn1_data *asn1; - DATA_BLOB blob; - int ret = LDAP_SUCCESS; -+ struct ldap_request_limits limits = {0}; - - conn->sockets.read_req = NULL; - -@@ -593,8 +594,13 @@ static void ldapsrv_call_read_done(struc - return; - } - -- status = ldap_decode(asn1, samba_ldap_control_handlers(), -- call->request); -+ limits.max_search_size = -+ lpcfg_ldap_max_search_request_size(conn->lp_ctx); -+ status = ldap_decode( -+ asn1, -+ &limits, -+ samba_ldap_control_handlers(), -+ call->request); - if (!NT_STATUS_IS_OK(status)) { - ldapsrv_terminate_connection(conn, nt_errstr(status)); - return; ---- a/source4/libcli/ldap/ldap_client.c -+++ b/source4/libcli/ldap/ldap_client.c -@@ -277,6 +277,7 @@ static void ldap_connection_recv_done(st - struct ldap_message *msg; - struct asn1_data *asn1; - DATA_BLOB blob; -+ struct ldap_request_limits limits = {0}; - - msg = talloc_zero(conn, struct ldap_message); - if (msg == NULL) { -@@ -306,7 +307,7 @@ static void ldap_connection_recv_done(st - - asn1_load_nocopy(asn1, blob.data, blob.length); - -- status = ldap_decode(asn1, samba_ldap_control_handlers(), msg); -+ status = ldap_decode(asn1, &limits, samba_ldap_control_handlers(), msg); - asn1_free(asn1); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(msg); diff --git a/CVE-2020-10704-8.patch b/CVE-2020-10704-8.patch deleted file mode 100644 index bc336428bca7a126717ab14de14299f25cf0771c..0000000000000000000000000000000000000000 --- a/CVE-2020-10704-8.patch +++ /dev/null @@ -1,66 +0,0 @@ -From ee3156c76b86c11829f6f3fe1e3c940b45899c56 Mon Sep 17 00:00:00 2001 -From: Gary Lockyer -Date: Wed, 8 Apr 2020 10:46:44 +1200 -Subject: [PATCH 8/8] CVE-2020-10704 libcli ldap: Check search request lengths. - -Check the search request lengths against the limits passed to -ldap_decode. - -Credit to OSS-Fuzz - -REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334 - -Signed-off-by: Gary Lockyer -Reviewed-by: Andrew Bartlett ---- - lib/util/asn1.c | 7 +++++++ - lib/util/asn1.h | 1 + - libcli/ldap/ldap_message.c | 4 ++++ - 3 files changed, 12 insertions(+) - -diff --git a/lib/util/asn1.c b/lib/util/asn1.c -index ee3cff9cb65..32d7981d28f 100644 ---- a/lib/util/asn1.c -+++ b/lib/util/asn1.c -@@ -1159,3 +1159,10 @@ int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) - *packet_size = size; - return 0; - } -+ -+/* -+ * Get the length of the ASN.1 data -+ */ -+size_t asn1_get_length(const struct asn1_data *asn1) { -+ return asn1->length; -+} -diff --git a/lib/util/asn1.h b/lib/util/asn1.h -index fc365724e93..de92a767f14 100644 ---- a/lib/util/asn1.h -+++ b/lib/util/asn1.h -@@ -106,5 +106,6 @@ bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, - DATA_BLOB *pblob); - void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len); - int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size); -+size_t asn1_get_length(const struct asn1_data *asn1); - - #endif /* _ASN_1_H */ -diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c -index d38fa0b3b61..69a48279532 100644 ---- a/libcli/ldap/ldap_message.c -+++ b/libcli/ldap/ldap_message.c -@@ -1259,7 +1259,11 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - int sizelimit, timelimit; - const char **attrs = NULL; -+ size_t request_size = asn1_get_length(data); - msg->type = LDAP_TAG_SearchRequest; -+ if (request_size > limits->max_search_size) { -+ goto prot_err; -+ } - if (!asn1_start_tag(data, tag)) goto prot_err; - if (!asn1_read_OctetString_talloc(msg, data, &r->basedn)) goto prot_err; - if (!asn1_read_enumerated(data, (int *)(void *)&(r->scope))) goto prot_err; --- -2.17.1 - diff --git a/CVE-2020-10730-1.patch b/CVE-2020-10730-1.patch deleted file mode 100644 index cab223adf72fda27127867723d23f9edb6401c1d..0000000000000000000000000000000000000000 --- a/CVE-2020-10730-1.patch +++ /dev/null @@ -1,35 +0,0 @@ -From b8628cb44766ac4c4817b1a50f09ca316425bd8b Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -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 -Reviewed-by: Gary Lockyer ---- - 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 - diff --git a/CVE-2020-10730-10.patch b/CVE-2020-10730-10.patch deleted file mode 100644 index e619cd8b94119ca06295440837a78bbedaac262f..0000000000000000000000000000000000000000 --- a/CVE-2020-10730-10.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 303947c58abf9311a666fe63ebd4ce26655ff36e Mon Sep 17 00:00:00 2001 -From: Gary Lockyer -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 -Reviewed-by: Andrew Bartlett ---- - 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 - diff --git a/CVE-2020-10730-2.patch b/CVE-2020-10730-2.patch deleted file mode 100644 index ced373ce43eb5c893f8bf26c9df77ddd6c7c888b..0000000000000000000000000000000000000000 --- a/CVE-2020-10730-2.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 2041c05d9b41fb0255c3492d118628c14a0c4b3d Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -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 -Reviewed-by: Gary Lockyer ---- - 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 - diff --git a/CVE-2020-10730-3.patch b/CVE-2020-10730-3.patch deleted file mode 100644 index 6c330d1afa8587e722670c85eca3199d6c73616a..0000000000000000000000000000000000000000 --- a/CVE-2020-10730-3.patch +++ /dev/null @@ -1,57 +0,0 @@ -From cf10f9b9a9a2f94afc526995a4034c1c6f05f5b4 Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -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 -Reviewed-by: Gary Lockyer ---- - 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 - diff --git a/CVE-2020-10730-4.patch b/CVE-2020-10730-4.patch deleted file mode 100644 index 92f5a94205757459cbb35d9744442a1c628ad94f..0000000000000000000000000000000000000000 --- a/CVE-2020-10730-4.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 3fd7ce69761fd2e21a85101772196aafc5ae57df Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -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 -Reviewed-by: Gary Lockyer ---- - .../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 - diff --git a/CVE-2020-10730-5.patch b/CVE-2020-10730-5.patch deleted file mode 100644 index e4d6f392662fcbc5b7e1749ede7c24c50dfe36b8..0000000000000000000000000000000000000000 --- a/CVE-2020-10730-5.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 01cce3d1fc69f04cdc237425b2f2ad1f2ac973d4 Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -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 -Reviewed-by: Gary Lockyer ---- - 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 - diff --git a/CVE-2020-10730-6.patch b/CVE-2020-10730-6.patch deleted file mode 100644 index 121fb0afa9896814cf4bf5fbe7ba9c3f98e9f533..0000000000000000000000000000000000000000 --- a/CVE-2020-10730-6.patch +++ /dev/null @@ -1,35 +0,0 @@ -From c7608e43c933d9a33d94e32371080e64cc1d4fcb Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -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 -Reviewed-by: Gary Lockyer ---- - 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 - diff --git a/CVE-2020-10730-7.patch b/CVE-2020-10730-7.patch deleted file mode 100644 index c94f549cf7ca61e984bf65232d6c2861724a1753..0000000000000000000000000000000000000000 --- a/CVE-2020-10730-7.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0c8cd0a9fbd9d17c1d7219f977ca35f88f0a2ea3 Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -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 -Reviewed-by: Gary Lockyer ---- - 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 - diff --git a/CVE-2020-10730-8.patch b/CVE-2020-10730-8.patch deleted file mode 100644 index 3bc694b239cc6564d1bd6531f74732d4c75ec999..0000000000000000000000000000000000000000 --- a/CVE-2020-10730-8.patch +++ /dev/null @@ -1,138 +0,0 @@ -From dcf713038ff10e35a74ee255f1634be81103e360 Mon Sep 17 00:00:00 2001 -From: Gary Lockyer -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 -Reviewed-by: Andrew Bartlett ---- - .../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 - diff --git a/CVE-2020-10730-9.patch b/CVE-2020-10730-9.patch deleted file mode 100644 index dc5ac3cb4b469508013e846453a6916203405fff..0000000000000000000000000000000000000000 --- a/CVE-2020-10730-9.patch +++ /dev/null @@ -1,171 +0,0 @@ -From ae6e9445ac8bf8f6870a8caa24406153cd2ee2bf Mon Sep 17 00:00:00 2001 -From: Gary Lockyer -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 -Reviewed-by: Andrew Bartlett ---- - .../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 - diff --git a/CVE-2020-10745-1.patch b/CVE-2020-10745-1.patch deleted file mode 100644 index a77fe4eb5df9e28b7b2c1b87bdaaaaf1ec28b15c..0000000000000000000000000000000000000000 --- a/CVE-2020-10745-1.patch +++ /dev/null @@ -1,272 +0,0 @@ -From ddd3ed7ce2e2776839c463010bd975f01dd0977d Mon Sep 17 00:00:00 2001 -From: Douglas Bagnall -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 ---- - 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 -+# -+# 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 . -+ -+"""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 - diff --git a/CVE-2020-10745-2.patch b/CVE-2020-10745-2.patch deleted file mode 100644 index cab8b58c6d2d3fbc7ca74b80817e76258403194a..0000000000000000000000000000000000000000 --- a/CVE-2020-10745-2.patch +++ /dev/null @@ -1,316 +0,0 @@ -From ddeabf87957ce73e12030977948418c93436a05c Mon Sep 17 00:00:00 2001 -From: Douglas Bagnall -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 ---- - 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 . -+ * -+ */ -+ -+#include "replace.h" -+#include -+#include -+ -+#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 - diff --git a/CVE-2020-10745-3.patch b/CVE-2020-10745-3.patch deleted file mode 100644 index 1e72aced66e5fcf7520276a8223e8d81340edcd4..0000000000000000000000000000000000000000 --- a/CVE-2020-10745-3.patch +++ /dev/null @@ -1,241 +0,0 @@ -From 37cacb8f41b9b2ea19a9c1bbfade4ea250dced46 Mon Sep 17 00:00:00 2001 -From: Douglas Bagnall -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 ---- - 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 - diff --git a/CVE-2020-10745-4.patch b/CVE-2020-10745-4.patch deleted file mode 100644 index b4da8a91714c251f1e9637fb91e57b32709e1b10..0000000000000000000000000000000000000000 --- a/CVE-2020-10745-4.patch +++ /dev/null @@ -1,28 +0,0 @@ -From b687813ac362ff71085d192a4b7821235345feea Mon Sep 17 00:00:00 2001 -From: Douglas Bagnall -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 ---- - 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 - diff --git a/CVE-2020-10745-5.patch b/CVE-2020-10745-5.patch deleted file mode 100644 index 9f053dfac22f3be26d12c644a4a59f3e0584b20f..0000000000000000000000000000000000000000 --- a/CVE-2020-10745-5.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 507503f80e8913450364dcd8ab080f3211b6f855 Mon Sep 17 00:00:00 2001 -From: Douglas Bagnall -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 ---- - 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 - diff --git a/CVE-2020-10745-6.patch b/CVE-2020-10745-6.patch deleted file mode 100644 index b4aa790838338814f4c0b4677986afef22b30f48..0000000000000000000000000000000000000000 --- a/CVE-2020-10745-6.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 83b00656ea0e8cfdce8a9c1cef71e41477e8e6f0 Mon Sep 17 00:00:00 2001 -From: Douglas Bagnall -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 ---- - 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 - diff --git a/CVE-2020-10745-7.patch b/CVE-2020-10745-7.patch deleted file mode 100644 index 76d0cbe00884fbf414c542f017ed3c4755347c1a..0000000000000000000000000000000000000000 --- a/CVE-2020-10745-7.patch +++ /dev/null @@ -1,267 +0,0 @@ -From 23e9eb71052e02aecf726609db0256c0d93e0b57 Mon Sep 17 00:00:00 2001 -From: Douglas Bagnall -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 ---- - 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 - diff --git a/CVE-2020-10760-1.patch b/CVE-2020-10760-1.patch deleted file mode 100644 index 94fedce64bcaeed0e4394f69d5ea91b1b37c2c16..0000000000000000000000000000000000000000 --- a/CVE-2020-10760-1.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 4def2dc554754033174c60f5860f51b46d8502c1 Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -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 ---- - 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 - diff --git a/CVE-2020-10760-2.patch b/CVE-2020-10760-2.patch deleted file mode 100644 index 2d00f1c67aec42aceff7019b3d970824babac340..0000000000000000000000000000000000000000 --- a/CVE-2020-10760-2.patch +++ /dev/null @@ -1,247 +0,0 @@ -From df599b6b79010759279eb7f52486f1d0a59d06d3 Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -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 ---- - 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 - diff --git a/CVE-2020-14303-1.patch b/CVE-2020-14303-1.patch deleted file mode 100644 index 04cfb85ef4d36d8f420986e1f01f5ace0b39e1aa..0000000000000000000000000000000000000000 --- a/CVE-2020-14303-1.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 11034ea33fca9b8a1c2e14480e70069b55fca6a2 Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -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 ---- - 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 - diff --git a/CVE-2020-14303-2.patch b/CVE-2020-14303-2.patch deleted file mode 100644 index 8e4c544b106468eb6b0847aa700e8113f517d3b6..0000000000000000000000000000000000000000 --- a/CVE-2020-14303-2.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 153c8db09b26455aa9802ff95943dd8a75f31893 Mon Sep 17 00:00:00 2001 -From: Gary Lockyer -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 ---- - 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 - diff --git a/samba-4.11.12.tar.asc b/samba-4.11.12.tar.asc new file mode 100644 index 0000000000000000000000000000000000000000..9c14d513ca28678b7b2f3601336563652aac53ba --- /dev/null +++ b/samba-4.11.12.tar.asc @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- + +iHMEABECADMWIQRS+8C4bZVLCEMyTNxvM5FbZWi36gUCX0TCrBUcc2FtYmEtYnVn +c0BzYW1iYS5vcmcACgkQbzORW2Vot+pkIgCePoB8Vb0cE4j0tafdJDK411aAP9YA +n0xcJD8v1hc1/qlhXLjA6bG3i7Rx +=GXx8 +-----END PGP SIGNATURE----- diff --git a/samba-4.11.6.tar.gz b/samba-4.11.12.tar.gz similarity index 66% rename from samba-4.11.6.tar.gz rename to samba-4.11.12.tar.gz index 770ccb2d702675ce8bcfc4993e4b72f3a373d96c..0ad4d01f4a90bcd542ef5b1d523b157b62ead389 100644 Binary files a/samba-4.11.6.tar.gz and b/samba-4.11.12.tar.gz differ diff --git a/samba-4.11.13-lib_util_wscript.patch b/samba-4.11.13-lib_util_wscript.patch new file mode 100644 index 0000000000000000000000000000000000000000..3921f3f8a9930d009531d419ad1eb15dbc7e9b83 --- /dev/null +++ b/samba-4.11.13-lib_util_wscript.patch @@ -0,0 +1,28 @@ +From 7f2c62dcdebb387b086df37c8dd38a6027d8b631 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?G=C3=BCnther=20Deschner?= +Date: Tue, 25 Aug 2020 10:37:18 +0200 +Subject: [PATCH] lib/util: do not install /usr/bin/test_util + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14166 + +Guenther + +Signed-off-by: Guenther Deschner +--- + lib/util/wscript_build | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lib/util/wscript_build b/lib/util/wscript_build +index 4ac0a9cc064..e04752cb130 100644 +--- a/lib/util/wscript_build ++++ b/lib/util/wscript_build +@@ -291,4 +291,5 @@ else: + bld.SAMBA_BINARY('test_util', + source='tests/test_util.c', + deps='cmocka replace talloc samba-util', +- local_include=False) ++ local_include=False, ++ install=False) +-- +2.26.2 + diff --git a/samba-4.11.6.tar.asc b/samba-4.11.6.tar.asc deleted file mode 100644 index 292cb0c8253e97ccbe0509b795af9f40c2fabbd1..0000000000000000000000000000000000000000 --- a/samba-4.11.6.tar.asc +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iHMEABECADMWIQRS+8C4bZVLCEMyTNxvM5FbZWi36gUCXjALthUcc2FtYmEtYnVn -c0BzYW1iYS5vcmcACgkQbzORW2Vot+od+ACgpzREKkVcyLse9EwufX0vS/JMUYIA -n2xGjOlyTFJJUD9heWInjmYzy4W0 -=472O ------END PGP SIGNATURE----- diff --git a/samba.spec b/samba.spec index e63bf78a520d35542c71f0316ec93b6f99b300bb..c2da2dd28b1ff192545e49572b683029e3114b0e 100644 --- a/samba.spec +++ b/samba.spec @@ -4,7 +4,7 @@ %define talloc_version 2.2.0 %define tdb_version 1.4.2 %define tevent_version 0.10.0 -%define ldb_version 2.0.8 +%define ldb_version 2.0.12 %undefine _strict_symbol_defs_build @@ -48,8 +48,8 @@ %define samba_depver %{version}-%{release} Name: samba -Version: 4.11.6 -Release: 8 +Version: 4.11.12 +Release: 1 Summary: A suite for Linux to interoperate with Windows License: GPLv3+ and LGPLv3+ @@ -69,35 +69,7 @@ Source201: README.downgrade Patch0: 0000-use-gnutls-for-des-cbc.patch Patch1: 0001-handle-removal-des-enctypes-from-krb5.patch Patch2: 0002-samba-tool-create-working-private-krb5.conf.patch -Patch3: CVE-2020-10700-1.patch -Patch4: CVE-2020-10700-3.patch -Patch5: CVE-2020-10704-1.patch -Patch6: CVE-2020-10704-3.patch -Patch7: CVE-2020-10704-5.patch -Patch8: CVE-2020-10704-6.patch -Patch9: CVE-2020-10704-7.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 +Patch3: samba-4.11.13-lib_util_wscript.patch 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 @@ -1856,6 +1828,7 @@ fi %{python3_sitearch}/samba/tests/__pycache__/hostconfig.*.pyc %{python3_sitearch}/samba/tests/__pycache__/join.*.pyc %{python3_sitearch}/samba/tests/__pycache__/krb5_credentials.*.pyc +%{python3_sitearch}/samba/tests/__pycache__/ldap_raw.*.pyc %{python3_sitearch}/samba/tests/__pycache__/ldap_referrals.*.pyc %{python3_sitearch}/samba/tests/__pycache__/loadparm.*.pyc %{python3_sitearch}/samba/tests/__pycache__/libsmb.*.pyc @@ -2039,6 +2012,7 @@ fi %{python3_sitearch}/samba/tests/kcc/kcc_utils.py %{python3_sitearch}/samba/tests/kcc/ldif_import_export.py %{python3_sitearch}/samba/tests/krb5_credentials.py +%{python3_sitearch}/samba/tests/ldap_raw.py %{python3_sitearch}/samba/tests/ldap_referrals.py %{python3_sitearch}/samba/tests/libsmb.py %{python3_sitearch}/samba/tests/loadparm.py @@ -2113,6 +2087,9 @@ fi %{python3_sitearch}/samba/tests/samba_tool/__pycache__/user.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/user_check_password_script.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/user_virtualCryptSHA.*.pyc +%{python3_sitearch}/samba/tests/samba_tool/__pycache__/user_virtualCryptSHA_base.*.pyc +%{python3_sitearch}/samba/tests/samba_tool/__pycache__/user_virtualCryptSHA_gpg.*.pyc +%{python3_sitearch}/samba/tests/samba_tool/__pycache__/user_virtualCryptSHA_userPassword.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/user_wdigest.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/visualize.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/visualize_drs.*.pyc @@ -2144,6 +2121,9 @@ fi %{python3_sitearch}/samba/tests/samba_tool/user.py %{python3_sitearch}/samba/tests/samba_tool/user_check_password_script.py %{python3_sitearch}/samba/tests/samba_tool/user_virtualCryptSHA.py +%{python3_sitearch}/samba/tests/samba_tool/user_virtualCryptSHA_base.py +%{python3_sitearch}/samba/tests/samba_tool/user_virtualCryptSHA_gpg.py +%{python3_sitearch}/samba/tests/samba_tool/user_virtualCryptSHA_userPassword.py %{python3_sitearch}/samba/tests/samba_tool/user_wdigest.py %{python3_sitearch}/samba/tests/samba_tool/visualize.py %{python3_sitearch}/samba/tests/samba_tool/visualize_drs.py @@ -3076,6 +3056,12 @@ fi %{_mandir}/man* %changelog +* Mon Aug 31 2020 yuboyun - 4.11.12-1 +- Type:NA +- ID:NA +- SUG:NA +- DESC:update to 4.11.12 + * Wed Aug 05 2020 yuboyun - 4.11.6-8 - Type:cves - ID:CVE-2020-10730 CVE-2020-10745 CVE-2020-14303 CVE-2020-10760