!82 backport to fix CVE-2021-3670

From: @eaglegai 
Reviewed-by: @seuzw 
Signed-off-by: @seuzw
This commit is contained in:
openeuler-ci-bot 2022-06-22 08:27:30 +00:00 committed by Gitee
commit 812503e64d
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
8 changed files with 709 additions and 1 deletions

View File

@ -0,0 +1,110 @@
From dc71ae17782ef4c6cac51e51b0b8b7ad77b556a0 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
Date: Thu, 26 Aug 2021 21:18:26 +1200
Subject: [PATCH] CVE-2021-3670 tests/krb5/test_ldap.py: Add test for LDAP
timeouts
We allow a timeout of 2x over to avoid this being a flapping test.
Samba is not very accurate on the timeout, which is not otherwise an
issue but makes this test fail sometimes.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14694
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit dcfcafdbf756e12d9077ad7920eea25478c29f81)
---
selftest/knownfail.d/ldap-timeout | 1 +
source4/dsdb/tests/python/large_ldap.py | 63 +++++++++++++++++++++++++
2 files changed, 64 insertions(+)
create mode 100644 selftest/knownfail.d/ldap-timeout
diff --git a/selftest/knownfail.d/ldap-timeout b/selftest/knownfail.d/ldap-timeout
new file mode 100644
index 000000000000..378ca1f48217
--- /dev/null
+++ b/selftest/knownfail.d/ldap-timeout
@@ -0,0 +1 @@
+samba4.ldap.large_ldap\..*\.python\(.*\).__main__.LargeLDAPTest.test_timeout\(.*\)
\ No newline at end of file
diff --git a/source4/dsdb/tests/python/large_ldap.py b/source4/dsdb/tests/python/large_ldap.py
index cce9d41862fd..620309ccae97 100644
--- a/source4/dsdb/tests/python/large_ldap.py
+++ b/source4/dsdb/tests/python/large_ldap.py
@@ -24,6 +24,7 @@
import sys
import os
import random
+import time
sys.path.insert(0, "bin/python")
import samba
@@ -245,6 +246,68 @@ def test_iterator_search(self):
# Assert we don't get all the entries but still the error
self.assertGreater(count, count_jpeg)
+ def test_timeout(self):
+ policy_dn = ldb.Dn(self.ldb,
+ 'CN=Default Query Policy,CN=Query-Policies,'
+ 'CN=Directory Service,CN=Windows NT,CN=Services,'
+ f'{self.ldb.get_config_basedn().get_linearized()}')
+
+ # Get the current value of lDAPAdminLimits.
+ res = self.ldb.search(base=policy_dn,
+ scope=ldb.SCOPE_BASE,
+ attrs=['lDAPAdminLimits'])
+ msg = res[0]
+ admin_limits = msg['lDAPAdminLimits']
+
+ # Ensure we restore the previous value of the attribute.
+ admin_limits.set_flags(ldb.FLAG_MOD_REPLACE)
+ self.addCleanup(self.ldb.modify, msg)
+
+ # Temporarily lower the value of MaxQueryDuration so we can test
+ # timeout behaviour.
+ timeout = 5
+ query_duration = f'MaxQueryDuration={timeout}'.encode()
+
+ admin_limits = [limit for limit in admin_limits
+ if not limit.lower().startswith(b'maxqueryduration=')]
+ admin_limits.append(query_duration)
+
+ # Set the new attribute value.
+ msg = ldb.Message(policy_dn)
+ msg['lDAPAdminLimits'] = ldb.MessageElement(admin_limits,
+ ldb.FLAG_MOD_REPLACE,
+ 'lDAPAdminLimits')
+ self.ldb.modify(msg)
+
+ # Use a new connection so that the limits are reloaded.
+ samdb = SamDB(url, credentials=creds,
+ session_info=system_session(lp),
+ lp=lp)
+
+ # Create a large search expression that will take a long time to
+ # evaluate.
+ expression = '(anr=l)' * 10000
+ expression = f'(|{expression})'
+
+ # Perform the LDAP search.
+ prev = time.time()
+ with self.assertRaises(ldb.LdbError) as err:
+ samdb.search(base=self.ou_dn,
+ scope=ldb.SCOPE_SUBTREE,
+ expression=expression,
+ attrs=['objectGUID'])
+ now = time.time()
+ duration = now - prev
+
+ # Ensure that we timed out.
+ enum, _ = err.exception.args
+ self.assertEqual(ldb.ERR_TIME_LIMIT_EXCEEDED, enum)
+
+ # Ensure that the time spent searching is within the limit we
+ # set. We allow a margin of 100% over as the Samba timeout
+ # handling is not very accurate (and does not need to be)
+ self.assertLess(timeout - 1, duration)
+ self.assertLess(duration, timeout * 2)
if "://" not in url:

View File

@ -0,0 +1,38 @@
From f72090064bd674ea3a6d6b2e7556a9a85bb01df6 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
Date: Thu, 26 Aug 2021 13:53:23 +1200
Subject: [PATCH] CVE-2021-3670 ldap_server: Set timeout on requests based on
MaxQueryDuration
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14694
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 86fe9d48883f87c928bf31ccbd275db420386803)
---
source4/ldap_server/ldap_backend.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index e19f82cf5dfa..c7405f666437 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -869,7 +869,17 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
}
}
- ldb_set_timeout(samdb, lreq, req->timelimit);
+ {
+ time_t timeout = call->conn->limits.search_timeout;
+
+ if (timeout == 0
+ || (req->timelimit != 0
+ && req->timelimit < timeout))
+ {
+ timeout = req->timelimit;
+ }
+ ldb_set_timeout(samdb, lreq, timeout);
+ }
if (!call->conn->is_privileged) {
ldb_req_mark_untrusted(lreq);

View File

@ -0,0 +1,30 @@
From f9b2267c6eb8138fc94df7a138ad5d87526f1d79 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
Date: Tue, 28 Sep 2021 17:20:43 +1300
Subject: [PATCH] CVE-2021-3670 ldap_server: Ensure value of MaxQueryDuration
is greater than zero
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14694
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit e1ab0c43629686d1d2c0b0b2bcdc90057a792049)
---
source4/ldap_server/ldap_server.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index 20442ecd9e57..bde2ecfa47f0 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -255,7 +255,9 @@ static int ldapsrv_load_limits(struct ldapsrv_connection *conn)
continue;
}
if (strcasecmp("MaxQueryDuration", policy_name) == 0) {
- conn->limits.search_timeout = policy_value;
+ if (policy_value > 0) {
+ conn->limits.search_timeout = policy_value;
+ }
continue;
}
}

View File

@ -0,0 +1,172 @@
From 08c9016cb9f25105c39488770113a1b00f8a4223 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Mon, 27 Sep 2021 16:47:46 +1300
Subject: [PATCH] CVE-2021-3670 ldb: Confirm the request has not yet timed out
in ldb filter processing
The LDB filter processing is where the time is spent in the LDB stack
but the timeout event will not get run while this is ongoing, so we
must confirm we have not yet timed out manually.
RN: Ensure that the LDB request has not timed out during filter processing
as the LDAP server MaxQueryDuration is otherwise not honoured.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14694
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 1d5b155619bc532c46932965b215bd73a920e56f)
---
lib/ldb/ldb_key_value/ldb_kv.c | 2 ++
lib/ldb/ldb_key_value/ldb_kv.h | 10 +++++++
lib/ldb/ldb_key_value/ldb_kv_index.c | 41 +++++++++++++++++++++++++++
lib/ldb/ldb_key_value/ldb_kv_search.c | 33 ++++++++++++++++++++-
selftest/knownfail.d/ldap-timeout | 1 -
5 files changed, 85 insertions(+), 2 deletions(-)
delete mode 100644 selftest/knownfail.d/ldap-timeout
diff --git a/lib/ldb/ldb_key_value/ldb_kv.c b/lib/ldb/ldb_key_value/ldb_kv.c
index ed0f760b5a26..aea6f0c1be0d 100644
--- a/lib/ldb/ldb_key_value/ldb_kv.c
+++ b/lib/ldb/ldb_key_value/ldb_kv.c
@@ -2078,6 +2078,8 @@ static int ldb_kv_handle_request(struct ldb_module *module,
}
}
+ ac->timeout_timeval = tv;
+
/* set a spy so that we do not try to use the request context
* if it is freed before ltdb_callback fires */
ac->spy = talloc(req, struct ldb_kv_req_spy);
diff --git a/lib/ldb/ldb_key_value/ldb_kv.h b/lib/ldb/ldb_key_value/ldb_kv.h
index f9dffae2dcf0..ac474b04b4cd 100644
--- a/lib/ldb/ldb_key_value/ldb_kv.h
+++ b/lib/ldb/ldb_key_value/ldb_kv.h
@@ -152,6 +152,16 @@ struct ldb_kv_context {
struct ldb_module *module;
struct ldb_request *req;
+ /*
+ * Required as we might not get to the event loop before the
+ * timeout, so we need some old-style cooperative multitasking
+ * here.
+ */
+ struct timeval timeout_timeval;
+
+ /* Used to throttle calls to gettimeofday() */
+ size_t timeout_counter;
+
bool request_terminated;
struct ldb_kv_req_spy *spy;
diff --git a/lib/ldb/ldb_key_value/ldb_kv_index.c b/lib/ldb/ldb_key_value/ldb_kv_index.c
index 1cc042aa84fb..d70e5f619efc 100644
--- a/lib/ldb/ldb_key_value/ldb_kv_index.c
+++ b/lib/ldb/ldb_key_value/ldb_kv_index.c
@@ -2352,6 +2352,47 @@ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv,
for (i = 0; i < num_keys; i++) {
int ret;
bool matched;
+
+ /*
+ * Check the time every 64 records, to reduce calls to
+ * gettimeofday(). This is a compromise, not all
+ * calls to ldb_match_message() will take the same
+ * time, most will run quickly but by luck it might be
+ * possible to have 64 records that are slow, doing a
+ * recursive search via LDAP_MATCHING_RULE_IN_CHAIN.
+ *
+ * Thankfully this is after index processing so only
+ * on the subset that matches some index (but still
+ * possibly a big one like objectclass=user)
+ */
+ if (i % 64 == 0) {
+ struct timeval now = tevent_timeval_current();
+ int timeval_cmp = tevent_timeval_compare(&ac->timeout_timeval,
+ &now);
+
+ /*
+ * The search has taken too long. This is the
+ * most likely place for our time to expire,
+ * as we are checking the records after the
+ * index set intersection. This is now the
+ * slow process of checking if the records
+ * actually match.
+ *
+ * The tevent based timeout is not likely to
+ * be hit, sadly, as we don't run an event
+ * loop.
+ *
+ * While we are indexed and most of the work
+ * should have been done already, the
+ * ldb_match_* calls can be quite expensive if
+ * the caller uses LDAP_MATCHING_RULE_IN_CHAIN
+ */
+ if (timeval_cmp <= 0) {
+ talloc_free(keys);
+ return LDB_ERR_TIME_LIMIT_EXCEEDED;
+ }
+ }
+
msg = ldb_msg_new(ac);
if (!msg) {
talloc_free(keys);
diff --git a/lib/ldb/ldb_key_value/ldb_kv_search.c b/lib/ldb/ldb_key_value/ldb_kv_search.c
index a0e1762bc902..46031b99c16c 100644
--- a/lib/ldb/ldb_key_value/ldb_kv_search.c
+++ b/lib/ldb/ldb_key_value/ldb_kv_search.c
@@ -314,7 +314,8 @@ static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv,
struct ldb_context *ldb;
struct ldb_kv_context *ac;
struct ldb_message *msg, *filtered_msg;
- int ret;
+ struct timeval now;
+ int ret, timeval_cmp;
bool matched;
ac = talloc_get_type(state, struct ldb_kv_context);
@@ -341,6 +342,36 @@ static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv,
return 0;
}
+ /*
+ * Check the time every 64 records, to reduce calls to
+ * gettimeofday(). This is a compromise, not all calls to
+ * ldb_match_message() will take the same time, most will fail
+ * quickly but by luck it might be possible to have 64 records
+ * that are slow, doing a recursive search via
+ * LDAP_MATCHING_RULE_IN_CHAIN.
+ */
+ if (ac->timeout_counter++ % 64 == 0) {
+ now = tevent_timeval_current();
+ timeval_cmp = tevent_timeval_compare(&ac->timeout_timeval,
+ &now);
+
+ /*
+ * The search has taken too long. This is the most
+ * likely place for our time to expire, as we are in
+ * an un-indexed search and we return the data from
+ * within this loop. The tevent based timeout is not
+ * likely to be hit, sadly.
+ *
+ * ldb_match_msg_error() can be quite expensive if a
+ * LDAP_MATCHING_RULE_IN_CHAIN extended match was
+ * specified.
+ */
+ if (timeval_cmp <= 0) {
+ ac->error = LDB_ERR_TIME_LIMIT_EXCEEDED;
+ return -1;
+ }
+ }
+
msg = ldb_msg_new(ac);
if (!msg) {
ac->error = LDB_ERR_OPERATIONS_ERROR;
diff --git a/selftest/knownfail.d/ldap-timeout b/selftest/knownfail.d/ldap-timeout
deleted file mode 100644
index 378ca1f48217..000000000000
--- a/selftest/knownfail.d/ldap-timeout
+++ /dev/null
@@ -1 +0,0 @@
-samba4.ldap.large_ldap\..*\.python\(.*\).__main__.LargeLDAPTest.test_timeout\(.*\)
\ No newline at end of file

View File

@ -0,0 +1,29 @@
From d92dfb0dabf9cfccb86f2b1146d6c353af2e1435 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Thu, 18 Nov 2021 15:27:08 +1300
Subject: [PATCH] CVE-2021-3670 ldap_server: Remove duplicate print of LDAP
search details
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14694
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 2b3af3b560c9617a233c131376c870fce146c002)
---
source4/ldap_server/ldap_backend.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index c7405f666437..78d0de951c54 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -729,9 +729,6 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
unsigned int i;
int extended_type = 1;
- DEBUG(10, ("SearchRequest"));
- DEBUGADD(10, (" basedn: %s", req->basedn));
- DEBUGADD(10, (" filter: %s\n", ldb_filter_from_tree(call, req->tree)));
local_ctx = talloc_new(call);
NT_STATUS_HAVE_NO_MEMORY(local_ctx);

View File

@ -0,0 +1,133 @@
From 3a4eb50cf74671de3442d179bd2d44afd5bc52c1 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Thu, 18 Nov 2021 15:57:34 +1300
Subject: [PATCH] CVE-2021-3670 dsdb/anr: Do a copy of the potentially anr
query before starting to modify it
RN: Do not modify the caller-supplied memory in the anr=* handling to
allow clear logging of the actual caller request after it has been processed.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14694
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 5f0590362c5c0c5ee20503a67467f9be2d50e73b)
---
source4/dsdb/samdb/ldb_modules/anr.c | 73 +++++++++++++++++++++++++---
1 file changed, 65 insertions(+), 8 deletions(-)
diff --git a/source4/dsdb/samdb/ldb_modules/anr.c b/source4/dsdb/samdb/ldb_modules/anr.c
index 660ba2714962..e083f5db17d8 100644
--- a/source4/dsdb/samdb/ldb_modules/anr.c
+++ b/source4/dsdb/samdb/ldb_modules/anr.c
@@ -148,8 +148,6 @@ static int anr_replace_value(struct anr_context *ac,
return LDB_ERR_OPERATIONS_ERROR;
}
- ac->found_anr = true;
-
if (match->length > 1 && match->data[0] == '=') {
struct ldb_val *match2 = talloc(mem_ctx, struct ldb_val);
if (match2 == NULL){
@@ -285,6 +283,49 @@ static int anr_replace_subtrees(struct anr_context *ac,
return LDB_SUCCESS;
}
+struct anr_present_ctx {
+ bool found_anr;
+ const char *attr;
+};
+
+/*
+ callback to determine if ANR is in use at all
+ */
+static int parse_tree_anr_present(struct ldb_parse_tree *tree, void *private_context)
+{
+ struct anr_present_ctx *ctx = private_context;
+ switch (tree->operation) {
+ case LDB_OP_EQUALITY:
+ case LDB_OP_GREATER:
+ case LDB_OP_LESS:
+ case LDB_OP_APPROX:
+ if (ldb_attr_cmp(tree->u.equality.attr, ctx->attr) == 0) {
+ ctx->found_anr = true;
+ }
+ break;
+ case LDB_OP_SUBSTRING:
+ if (ldb_attr_cmp(tree->u.substring.attr, ctx->attr) == 0) {
+ ctx->found_anr = true;
+ }
+ break;
+ case LDB_OP_PRESENT:
+ if (ldb_attr_cmp(tree->u.present.attr, ctx->attr) == 0) {
+ ctx->found_anr = true;
+ }
+ break;
+ case LDB_OP_EXTENDED:
+ if (tree->u.extended.attr &&
+ ldb_attr_cmp(tree->u.extended.attr, ctx->attr) == 0) {
+ ctx->found_anr = true;
+ }
+ break;
+ default:
+ break;
+ }
+ return LDB_SUCCESS;
+}
+
+
static int anr_search_callback(struct ldb_request *req, struct ldb_reply *ares)
{
struct anr_context *ac;
@@ -322,8 +363,21 @@ static int anr_search(struct ldb_module *module, struct ldb_request *req)
struct ldb_parse_tree *anr_tree;
struct ldb_request *down_req;
struct anr_context *ac;
+ struct anr_present_ctx ctx;
+ const char *attr = "anr";
int ret;
+ ctx.found_anr = false;
+ ctx.attr = attr;
+
+ ldb_parse_tree_walk(req->op.search.tree,
+ parse_tree_anr_present,
+ &ctx);
+
+ if (!ctx.found_anr) {
+ return ldb_next_request(module, req);
+ }
+
ldb = ldb_module_get_ctx(module);
ac = talloc(req, struct anr_context);
@@ -333,20 +387,23 @@ static int anr_search(struct ldb_module *module, struct ldb_request *req)
ac->module = module;
ac->req = req;
- ac->found_anr = false;
#if 0
printf("oldanr : %s\n", ldb_filter_from_tree (0, req->op.search.tree));
#endif
- ret = anr_replace_subtrees(ac, req->op.search.tree, "anr", &anr_tree);
- if (ret != LDB_SUCCESS) {
+ /* First make a copy, so we don't overwrite caller memory */
+
+ anr_tree = ldb_parse_tree_copy_shallow(ac, req->op.search.tree);
+
+ if (anr_tree == NULL) {
return ldb_operr(ldb);
}
- if (!ac->found_anr) {
- talloc_free(ac);
- return ldb_next_request(module, req);
+ /* Now expand 'anr' out */
+ ret = anr_replace_subtrees(ac, anr_tree, attr, &anr_tree);
+ if (ret != LDB_SUCCESS) {
+ return ldb_operr(ldb);
}
ret = ldb_build_search_req_ex(&down_req,

View File

@ -0,0 +1,183 @@
From 3e8d6e681f8dbe79e4595549f78c42649b3573a2 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Thu, 18 Nov 2021 16:09:47 +1300
Subject: [PATCH] CVE-2021-3670 ldap_server: Clearly log LDAP queries and
timeouts
This puts all the detail on one line so it can be searched
by IP address and connecting SID.
This relies on the anr handling as otherwise this log
becomes the expanded query, not the original one.
RN: Provide clear logs of the LDAP search and who made it, including
a warning (at log level 3) for queries that are 1/4 of the hard timeout.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14694
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Autobuild-User(master): Douglas Bagnall <dbagnall@samba.org>
Autobuild-Date(master): Thu Nov 25 02:30:42 UTC 2021 on sn-devel-184
(cherry picked from commit 3507e96b3dcf0c0b8eff7b2c08ffccaf0812a393)
---
source4/ldap_server/ldap_backend.c | 121 +++++++++++++++++++++++------
1 file changed, 99 insertions(+), 22 deletions(-)
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index 78d0de951c54..e37b87f62eed 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -33,6 +33,7 @@
#include "ldb_wrap.h"
#include "lib/tsocket/tsocket.h"
#include "libcli/ldap/ldap_proto.h"
+#include "source4/auth/auth.h"
static int map_ldb_error(TALLOC_CTX *mem_ctx, int ldb_err,
const char *add_err_string, const char **errstring)
@@ -729,6 +729,15 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
unsigned int i;
int extended_type = 1;
+ /*
+ * Warn for searches that are longer than 1/4 of the
+ * search_timeout, being 30sec by default
+ */
+ struct timeval start_time = timeval_current();
+ struct timeval warning_time
+ = timeval_add(&start_time,
+ call->conn->limits.search_timeout / 4,
+ 0);
local_ctx = talloc_new(call);
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
@@ -736,29 +745,27 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
basedn = ldb_dn_new(local_ctx, samdb, req->basedn);
NT_STATUS_HAVE_NO_MEMORY(basedn);
- DEBUG(10, ("SearchRequest: basedn: [%s]\n", req->basedn));
- DEBUG(10, ("SearchRequest: filter: [%s]\n", ldb_filter_from_tree(call, req->tree)));
-
switch (req->scope) {
- case LDAP_SEARCH_SCOPE_BASE:
- scope_str = "BASE";
- scope = LDB_SCOPE_BASE;
- break;
- case LDAP_SEARCH_SCOPE_SINGLE:
- scope_str = "ONE";
- scope = LDB_SCOPE_ONELEVEL;
- break;
- case LDAP_SEARCH_SCOPE_SUB:
- scope_str = "SUB";
- scope = LDB_SCOPE_SUBTREE;
- break;
- default:
- result = LDAP_PROTOCOL_ERROR;
- map_ldb_error(local_ctx, LDB_ERR_PROTOCOL_ERROR, NULL,
- &errstr);
- errstr = talloc_asprintf(local_ctx,
- "%s. Invalid scope", errstr);
- goto reply;
+ case LDAP_SEARCH_SCOPE_BASE:
+ scope_str = "BASE";
+ scope = LDB_SCOPE_BASE;
+ break;
+ case LDAP_SEARCH_SCOPE_SINGLE:
+ scope_str = "ONE";
+ scope = LDB_SCOPE_ONELEVEL;
+ break;
+ case LDAP_SEARCH_SCOPE_SUB:
+ scope_str = "SUB";
+ scope = LDB_SCOPE_SUBTREE;
+ break;
+ default:
+ result = LDAP_PROTOCOL_ERROR;
+ map_ldb_error(local_ctx, LDB_ERR_PROTOCOL_ERROR, NULL,
+ &errstr);
+ scope_str = "<Invalid scope>";
+ errstr = talloc_asprintf(local_ctx,
+ "%s. Invalid scope", errstr);
+ goto reply;
}
DEBUG(10,("SearchRequest: scope: [%s]\n", scope_str));
@@ -911,6 +918,76 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
}
reply:
+
+ /*
+ * This looks like duplicated code - because it is - but
+ * otherwise the work in the parameters will be done
+ * regardless, this way the functions only execuate when the
+ * log level is set.
+ *
+ * The basedn is re-obtained as a string to escape it
+ */
+ if ((req->timelimit == 0 || call->conn->limits.search_timeout < req->timelimit)
+ && ldb_ret == LDB_ERR_TIME_LIMIT_EXCEEDED) {
+ struct dom_sid_buf sid_buf;
+ DBG_WARNING("MaxQueryDuration(%d) timeout exceeded "
+ "in SearchRequest by %s from %s filter: [%s] "
+ "basedn: [%s] "
+ "scope: [%s]\n",
+ call->conn->limits.search_timeout,
+ dom_sid_str_buf(&call->conn->session_info->security_token->sids[0],
+ &sid_buf),
+ tsocket_address_string(call->conn->connection->remote_address,
+ call),
+ ldb_filter_from_tree(call, req->tree),
+ ldb_dn_get_extended_linearized(call, basedn, 1),
+ scope_str);
+ for (i=0; i < req->num_attributes; i++) {
+ DBG_WARNING("MaxQueryDuration timeout exceeded attrs: [%s]\n",
+ req->attributes[i]);
+ }
+
+ } else if (timeval_expired(&warning_time)) {
+ struct dom_sid_buf sid_buf;
+ DBG_NOTICE("Long LDAP Query: Duration was %.2fs, "
+ "MaxQueryDuration(%d)/4 == %d "
+ "in SearchRequest by %s from %s filter: [%s] "
+ "basedn: [%s] "
+ "scope: [%s] "
+ "result: %s\n",
+ timeval_elapsed(&start_time),
+ call->conn->limits.search_timeout,
+ call->conn->limits.search_timeout / 4,
+ dom_sid_str_buf(&call->conn->session_info->security_token->sids[0],
+ &sid_buf),
+ tsocket_address_string(call->conn->connection->remote_address,
+ call),
+ ldb_filter_from_tree(call, req->tree),
+ ldb_dn_get_extended_linearized(call, basedn, 1),
+ scope_str,
+ ldb_strerror(ldb_ret));
+ for (i=0; i < req->num_attributes; i++) {
+ DBG_NOTICE("Long LDAP Query attrs: [%s]\n",
+ req->attributes[i]);
+ }
+ } else {
+ struct dom_sid_buf sid_buf;
+ DBG_INFO("LDAP Query: Duration was %.2fs, "
+ "SearchRequest by %s from %s filter: [%s] "
+ "basedn: [%s] "
+ "scope: [%s] "
+ "result: %s\n",
+ timeval_elapsed(&start_time),
+ dom_sid_str_buf(&call->conn->session_info->security_token->sids[0],
+ &sid_buf),
+ tsocket_address_string(call->conn->connection->remote_address,
+ call),
+ ldb_filter_from_tree(call, req->tree),
+ ldb_dn_get_extended_linearized(call, basedn, 1),
+ scope_str,
+ ldb_strerror(ldb_ret));
+ }
+
DLIST_REMOVE(call->conn->pending_calls, call);
call->notification.busy = false;

View File

@ -49,7 +49,7 @@
Name: samba
Version: 4.11.12
Release: 10
Release: 11
Summary: A suite for Linux to interoperate with Windows
License: GPLv3+ and LGPLv3+
@ -183,6 +183,13 @@ Patch6254: backport-0003-CVE-2021-44142.patch
Patch6255: backport-0004-CVE-2021-44142.patch
Patch6256: backport-0005-CVE-2021-44142.patch
Patch6257: backport-CVE-2022-0336.patch
Patch6258: backport-001-CVE-2021-3670.patch
Patch6259: backport-002-CVE-2021-3670.patch
Patch6260: backport-003-CVE-2021-3670.patch
Patch6261: backport-004-CVE-2021-3670.patch
Patch6262: backport-005-CVE-2021-3670.patch
Patch6263: backport-006-CVE-2021-3670.patch
Patch6264: backport-007-CVE-2021-3670.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
@ -3170,6 +3177,12 @@ fi
%{_mandir}/man*
%changelog
* Tue Jun 21 2022 gaihuiying <eaglegai@163.com> - 4.11.12-11
- Type:CVE
- CVE:CVE-2021-3670
- SUG:NA
- DESC:backport to fix CVE-2021-3670
* Mon Feb 14 2022 gaihuiying <eaglegai@163.com> - 4.11.12-10
- Type:cves
- ID:CVE-2022-0366