From 467a39049d2738d3b54874a72cba7394140a3103 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 10 Jun 2016 15:07:43 +0200 Subject: [PATCH] winbindd: idmap backend allocates id for unknown SID 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 LsaLookupNames() 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. To fix this, filter out SID mapping requests for unknown SIDs (unknown as per not found via LsaLookupNames()) and don't send them down the stack to the idmap child. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11961 Signed-off-by: Ralph Boehme --- librpc/idl/winbind.idl | 1 + source3/winbindd/wb_sids2xids.c | 9 +++++++++ source3/winbindd/winbindd_dual_srv.c | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/librpc/idl/winbind.idl b/librpc/idl/winbind.idl index 60c875b..332de58 100644 --- a/librpc/idl/winbind.idl +++ b/librpc/idl/winbind.idl @@ -41,6 +41,7 @@ interface winbind typedef struct { id_type type; + lsa_SidType sid_type; uint32 domain_index; uint32 rid; unixid xid; diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c index e16917f..5302b6a 100644 --- a/source3/winbindd/wb_sids2xids.c +++ b/source3/winbindd/wb_sids2xids.c @@ -196,6 +196,7 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) info = &domains->domains[n->sid_index]; t->type = lsa_SidType_to_id_type(n->sid_type); + t->sid_type = n->sid_type; domain_index = init_lsa_ref_domain_list( state, &state->idmap_doms, info->name.string, &dom_sid); @@ -310,6 +311,10 @@ static void wb_sids2xids_done(struct tevent_req *subreq) } for (i=0; inum_ids; i++) { + if (dst->ids[i].sid_type == SID_NAME_UNKNOWN) { + /* Skip unkown SIDS */ + continue; + } if (dst->ids[i].domain_index == state->dom_index) { dst->ids[i].type = src->ids[src_idx].type; dst->ids[i].xid = src->ids[src_idx].xid; @@ -450,6 +455,10 @@ static struct wbint_TransIDArray *wb_sids2xids_extract_for_domain_index( } for (i=0; inum_ids; i++) { + if (src->ids[i].sid_type == SID_NAME_UNKNOWN) { + /* Skip unknown SIDs */ + continue; + } if (src->ids[i].domain_index == domain_index) { ret->ids[ret->num_ids] = src->ids[i]; ret->ids[ret->num_ids].domain_index = 0; diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index fb65e9d..88fb40a 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -139,6 +139,14 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p, ids = r->in.ids->ids; num_ids = r->in.ids->num_ids; + if (num_ids == 0) { + /* + * This can happen when there's one SID for a domain + * and LsaLookupName returned SID_NAME_UNKNOWN. + */ + return NT_STATUS_OK; + } + dom = idmap_find_domain_with_sid(d->name.string, d->sid); if (dom == NULL) { DEBUG(10, ("idmap domain %s:%s not found\n", -- 1.9.1