170 lines
4.6 KiB
Diff
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
|
|
|