From: Ralph Boehme Date: Fri, 24 Jun 2016 13:16:42 +0000 (+0200) Subject: winbindd: in wb_lookupsids return domain name if we have it X-Git-Tag: tdb-1.3.10~654 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9be918116e356c358ef77cc2933e471090088293;p=thirdparty%2Fsamba.git winbindd: in wb_lookupsids return domain name if we have it When doing a SID to xid mapping for an unknown SID, the idmap child gets passed a lsa_RefDomainList with an empty domain name (ie ""). This is coming from LsaLookupSids() and causes the mapping request to end up in the default idmap domain. Example request with domain name "": wbint_Sids2UnixIDs: struct wbint_Sids2UnixIDs in: struct wbint_Sids2UnixIDs domains : * domains: struct lsa_RefDomainList count : 0x00000001 (1) domains : * domains: ARRAY(1) domains: struct lsa_DomainInfo name: struct lsa_StringLarge length : 0x0000 (0) size : 0x0002 (2) string : * string : '' sid : * sid : S-1-5-21-3152989960-574718769-2188965058 max_size : 0x00000020 (32) ids : * ids: struct wbint_TransIDArray num_ids : 0x00000001 (1) ids: ARRAY(1) ids: struct wbint_TransID type : ID_TYPE_NOT_SPECIFIED (0) domain_index : 0x00000000 (0) rid : 0x000029aa (66666) xid: struct unixid id : 0xffffffff (4294967295) type : ID_TYPE_NOT_SPECIFIED (0) In _wbint_Sids2UnixIDs() we call idmap_find_domain_with_sid() with the domain name "" and this triggers use of the default idmap domain which in case of idmap_autorid will allocate an id from a idmap_autorid range. If we know the domain, ensure we return it for SIDs were the SID was not found but the domain of the SID was found. Callers like sids2xids depend on the domain name and returning an empty string "" for valid domain can trigger unwanted idmap range allocations. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11961 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- diff --git a/source3/winbindd/wb_lookupsids.c b/source3/winbindd/wb_lookupsids.c index 8c5f9dbbb48..248054750ff 100644 --- a/source3/winbindd/wb_lookupsids.c +++ b/source3/winbindd/wb_lookupsids.c @@ -72,6 +72,8 @@ struct wb_lookupsids_state { * wbint_LookupSid. Preallocated with num_sids. */ uint32_t *single_sids; + /* Pointer into the "domains" array above*/ + struct wb_lookupsids_domain **single_domains; uint32_t num_single_sids; uint32_t single_sids_done; @@ -127,6 +129,12 @@ struct tevent_req *wb_lookupsids_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(state->single_sids, req)) { return tevent_req_post(req, ev); } + state->single_domains = talloc_zero_array(state, + struct wb_lookupsids_domain *, + num_sids); + if (tevent_req_nomem(state->single_domains, req)) { + return tevent_req_post(req, ev); + } state->res_domains = talloc_zero(state, struct lsa_RefDomainList); if (tevent_req_nomem(state->res_domains, req)) { @@ -455,6 +463,7 @@ static void wb_lookupsids_done(struct tevent_req *subreq) state->single_sids[state->num_single_sids] = res_sid_index; + state->single_domains[state->num_single_sids] = d; state->num_single_sids += 1; } state->domains_done += 1; @@ -514,9 +523,28 @@ static void wb_lookupsids_single_done(struct tevent_req *subreq) &domain_name, &name); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { + struct wb_lookupsids_domain *wb_domain; + const char *tmpname; + type = SID_NAME_UNKNOWN; - domain_name = talloc_strdup(talloc_tos(), ""); + wb_domain = state->single_domains[state->single_sids_done]; + if (wb_domain != NULL) { + /* + * If the lookupsid failed because the rid not + * found in a domain and we have a reference + * to the lookup domain, use the name from + * there. + * + * Callers like sid2xid will use the domain + * name in the idmap backend to figure out + * which domain to use in processing. + */ + tmpname = wb_domain->domain->name; + } else { + tmpname = ""; + } + domain_name = talloc_strdup(talloc_tos(), tmpname); if (tevent_req_nomem(domain_name, req)) { return; }