From e4b57ecab1dd622940e75e9d602bf0bc71270d9f Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 4 Apr 2017 14:51:09 +0200 Subject: [PATCH 1/2] winbindd: handling of SIDs without domain reference in wb_sids2xids_lookupsids_done() This lets wb_sids2xids_lookupsids_done() deal with wp_lookupsids returning UINT32_MAX as domain index for SIDs from unknown domains. Call find_domain_from_sid_noinit() to search our list of known domains. If a matching domain is found, use it's name, otherwise use the empty string "". This needed to handle Samba DCs which always returns sid_index UINT32_MAX for unknown SIDs, even from known domains. Currently the wb_lookupsids adds these fake domains with an empty string as domain name, but that's not the correct place to do it. We need the domain name as it gets passed to the idmap child where the choise of idmap backend is based on the domain name. This will possibly be changed in the future to be based on domain SIDs, not the name. Prerequisite for bug: https://bugzilla.samba.org/show_bug.cgi?id=12702 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 1efaeb072e55735421191fbae9cc586db6d07bb1) --- source3/winbindd/wb_sids2xids.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c index 9bb8fa8..dc90bdf 100644 --- a/source3/winbindd/wb_sids2xids.c +++ b/source3/winbindd/wb_sids2xids.c @@ -185,20 +185,41 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) } for (i=0; inum_non_cached; i++) { + const struct dom_sid *sid = &state->non_cached[i]; struct dom_sid dom_sid; - struct lsa_DomainInfo *info; struct lsa_TranslatedName *n = &names->names[i]; struct wbint_TransID *t = &state->ids.ids[i]; int domain_index; + const char *domain_name = NULL; - sid_copy(&dom_sid, &state->non_cached[i]); - sid_split_rid(&dom_sid, &t->rid); + if (n->sid_index != UINT32_MAX) { + const struct lsa_DomainInfo *info; - info = &domains->domains[n->sid_index]; - t->type = lsa_SidType_to_id_type(n->sid_type); + info = &domains->domains[n->sid_index]; + 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, info->name.string, &dom_sid); + state, &state->idmap_doms, domain_name, &dom_sid); if (domain_index == -1) { tevent_req_oom(req); return; -- 2.9.3 From 5763b27d4853a29686b1d3df600a5f20097e63fe Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 10 Apr 2017 14:28:18 +0200 Subject: [PATCH 2/2] winbindd: only use the domain name from lookup sids if the domain matches With the use of sIDHistory it happens that two sids map to the same name: S-1-5-21-1387724271-3540671778-1971508351-1115 DOMAIN2\d1u1 (1) S-1-5-21-3293503978-489118715-2763867031-1106 DOMAIN2\d1u1 (1) On the net it looks like this: lsa_LookupSids: struct lsa_LookupSids in: struct lsa_LookupSids handle : * handle: struct policy_handle handle_type : 0x00000000 (0) uuid : 344f3586-7de4-4e1d-96a9-8c6c23e4b2f0 sids : * sids: struct lsa_SidArray num_sids : 0x00000002 (2) sids : * sids: ARRAY(2) sids: struct lsa_SidPtr sid : * sid : S-1-5-21-1387724271-3540671778-1971508351-1115 sids: struct lsa_SidPtr sid : * sid : S-1-5-21-3293503978-489118715-2763867031-1106 names : * names: struct lsa_TransNameArray count : 0x00000000 (0) names : NULL level : LSA_LOOKUP_NAMES_ALL (1) count : * count : 0x00000000 (0) lsa_LookupSids: struct lsa_LookupSids out: struct lsa_LookupSids domains : * domains : * domains: struct lsa_RefDomainList count : 0x00000001 (1) domains : * domains: ARRAY(1) domains: struct lsa_DomainInfo name: struct lsa_StringLarge length : 0x000e (14) size : 0x0010 (16) string : * string : 'DOMAIN2' sid : * sid : S-1-5-21-1387724271-3540671778-1971508351 max_size : 0x00000020 (32) names : * names: struct lsa_TransNameArray count : 0x00000002 (2) names : * names: ARRAY(7) names: struct lsa_TranslatedName sid_type : SID_NAME_USER (1) name: struct lsa_String length : 0x0008 (8) size : 0x0008 (8) string : * string : 'd1u1' sid_index : 0x00000000 (0) names: struct lsa_TranslatedName sid_type : SID_NAME_USER (1) name: struct lsa_String length : 0x0008 (8) size : 0x0008 (8) string : * string : 'd1u1' sid_index : 0x00000000 (0) count : * count : 0x00000002 (2) result : NT_STATUS_OK So the name for S-1-5-21-3293503978-489118715-2763867031-1106 has S-1-5-21-1387724271-3540671778-1971508351 in referenced lsa_DomainInfo structure. In that case we should not use the domain name from lsa_DomainInfo, because we would use the wrong idmap backend. For the case where the domain part of the sIDHistory sid is a still existing domain, which can be found our internal list of trusted domains, we now use the correct idmap backend: the idmap domain from the historic SID. If the historic domain does no longer exist, we will fallback to the default idmap domain. The next step would be doing a lookup sid call for the domain sid, which may help with one-way trusts. The long term goal needs to be that idmap backends are based on sids only and only the smb.conf allows names to be used which will be converted to sids on startup. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12702 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Ralph Boehme Reviewed-by: Uri Simchoni Autobuild-User(master): Uri Simchoni Autobuild-Date(master): Wed Apr 12 16:43:30 CEST 2017 on sn-devel-144 (cherry picked from commit 9d419c3fe3654f038fbc978ecb7fa87cf8a5cc3b) --- source3/winbindd/wb_sids2xids.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c index dc90bdf..b8ad300 100644 --- a/source3/winbindd/wb_sids2xids.c +++ b/source3/winbindd/wb_sids2xids.c @@ -194,9 +194,13 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) if (n->sid_index != UINT32_MAX) { const struct lsa_DomainInfo *info; + bool match; info = &domains->domains[n->sid_index]; - domain_name = info->name.string; + 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; -- 2.9.3