samba/backport-0005-CVE-2020-25717-wb_sids2xids-build-state-idmap_doms-b.patch
haochenstar 8378df4821 fix CVE-2020-25717,CVE-2020-25718,CVE-2020-25719,CVE-2020-25721,CVE-2020-25722,CVE-2016-2124,CVE-2021-3738
(cherry picked from commit aee849c6c0708056f62f6445e3b5274d1cec6408)
2022-01-19 11:41:35 +08:00

170 lines
4.6 KiB
Diff

From ed1542b9f37734bc77906c4ba49ea6ea3be09af8 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Thu, 10 Sep 2020 17:13:14 +0200
Subject: [PATCH 026/266] CVE-2020-25717 wb_sids2xids: build state->idmap_doms
based on wb_parent_idmap_config
In future we'll try to avoid wb_lookupsids_send() and only call
it if needed.
The domain name passed should be only relevant to find the correct
idmap backend, and these should all be available in
wb_parent_idmap_config as it was created before the idmap child was forked.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
(cherry picked from commit c55f4f37589130a0d8952489da175bbcf53f6748)
---
source3/winbindd/wb_sids2xids.c | 101 +++++++++++++++++++-------------
1 file changed, 61 insertions(+), 40 deletions(-)
Conflict:lookup_sids --> non_cached
lookup_count --> num_non_cached
li --> i
delete 'uint32_t ai = state->tmp_idx[i]'
state->all_ids.ids[i] --> &state->ids.ids[i]
add 't->xid.id = UINT32_MAX;
t->xid.type = t->type;'
type_hint --> type
Reference:https://git.samba.org/samba.git/?p=samba.git;a=patch;h=ed1542b9f37734bc77906c4ba49ea6ea3be09af8
diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c
index 21bf5f901f3..3a3d47abbe5 100644
--- a/source3/winbindd/wb_sids2xids.c
+++ b/source3/winbindd/wb_sids2xids.c
@@ -193,6 +193,7 @@ static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq)
struct wb_sids2xids_state *state = tevent_req_data(
req, struct wb_sids2xids_state);
NTSTATUS status;
+ uint32_t i;
status = wb_parent_idmap_setup_recv(subreq, &state->cfg);
TALLOC_FREE(subreq);
@@ -201,6 +202,66 @@ static void wb_sids2xids_idmap_setup_done(struct tevent_req *subreq)
}
SMB_ASSERT(state->cfg->num_doms > 0);
+ /*
+ * Now we build a list with all domain
+ * with non cached entries
+ */
+ for (i=0; i<state->num_sids; i++) {
+ struct wbint_TransID *t = &state->ids.ids[i];
+ struct dom_sid domain_sid;
+ const char *domain_name = NULL;
+ int domain_index;
+ uint32_t rid = 0;
+ uint32_t di;
+
+ if (t->domain_index == UINT32_MAX) {
+ /* ignore already filled entries */
+ continue;
+ }
+
+ sid_copy(&domain_sid, &state->sids[i]);
+ sid_split_rid(&domain_sid, &rid);
+
+ for (di = 0; di < state->cfg->num_doms; di++) {
+ struct wb_parent_idmap_config_dom *dom =
+ &state->cfg->doms[di];
+ bool match;
+
+ match = dom_sid_equal(&domain_sid,
+ &dom->sid);
+ if (!match) {
+ continue;
+ }
+
+ domain_name = dom->name;
+ break;
+ }
+ if (domain_name == NULL) {
+ struct winbindd_domain *wb_domain = NULL;
+
+ /*
+ * Try to fill the name if we already know it
+ */
+ wb_domain = find_domain_from_sid_noinit(&state->sids[i]);
+ if (wb_domain != NULL) {
+ domain_name = wb_domain->name;
+ }
+ }
+ if (domain_name == NULL) {
+ domain_name = "";
+ }
+
+ domain_index = init_lsa_ref_domain_list(state,
+ &state->idmap_doms,
+ domain_name,
+ &domain_sid);
+ if (domain_index == -1) {
+ tevent_req_oom(req);
+ return;
+ }
+ t->domain_index = domain_index;
+ }
+
subreq = wb_lookupsids_send(state,
state->ev,
state->non_cached,
@@ -251,51 +312,11 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq)
}
for (i=0; i<state->num_non_cached; i++) {
- const struct dom_sid *sid = &state->non_cached[i];
- struct dom_sid dom_sid;
struct lsa_TranslatedName *n = &names->names[i];
struct wbint_TransID *t = &state->ids.ids[i];
- int domain_index;
- const char *domain_name = NULL;
-
- if (n->sid_index != UINT32_MAX) {
- const struct lsa_DomainInfo *info;
- bool match;
-
- info = &domains->domains[n->sid_index];
- match = dom_sid_in_domain(info->sid, sid);
- if (match) {
- domain_name = info->name.string;
- }
- }
- if (domain_name == NULL) {
- struct winbindd_domain *wb_domain = NULL;
-
- /*
- * This is needed to handle Samba DCs
- * which always return sid_index == UINT32_MAX for
- * unknown sids.
- */
- wb_domain = find_domain_from_sid_noinit(sid);
- if (wb_domain != NULL) {
- domain_name = wb_domain->name;
- }
- }
- if (domain_name == NULL) {
- domain_name = "";
- }
- sid_copy(&dom_sid, sid);
- sid_split_rid(&dom_sid, &t->rid);
t->type = lsa_SidType_to_id_type(n->sid_type);
- domain_index = init_lsa_ref_domain_list(
- state, &state->idmap_doms, domain_name, &dom_sid);
- if (domain_index == -1) {
- tevent_req_oom(req);
- return;
- }
- t->domain_index = domain_index;
t->xid.id = UINT32_MAX;
t->xid.type = t->type;
}
--
2.23.0