From 12b03ad89ecc98600a6d3ac91a3f3bf08c068858 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 24 Jun 2011 20:13:26 +0200 Subject: [PATCH] s3:winbindd_lookuprids: use wbint_LookupSids instead of wbint_LookupRids for most domains (bug #7841) Using wbint_LookupRids() looses the domain sid to which the rids belong. We can only use wbint_LookupRids for the domain of our local sam, for the unix user/group and builtin domains and trusts we need to use wbint_LookupSids in order to pass the domain sids to the target. metze --- source3/winbindd/winbindd_lookuprids.c | 100 +++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 6 deletions(-) diff --git a/source3/winbindd/winbindd_lookuprids.c b/source3/winbindd/winbindd_lookuprids.c index 738adbaefc3b..0379be65f14c 100644 --- a/source3/winbindd/winbindd_lookuprids.c +++ b/source3/winbindd/winbindd_lookuprids.c @@ -21,18 +21,24 @@ #include "winbindd.h" #include "librpc/gen_ndr/ndr_wbint_c.h" #include "../libcli/security/security.h" +#include "passdb/machine_sid.h" struct winbindd_lookuprids_state { struct tevent_context *ev; const char *domain_name; struct wbint_RidArray rids; struct wbint_Principals names; + + struct lsa_SidArray tmp_sids; + struct lsa_RefDomainList tmp_domains; + struct lsa_TransNameArray tmp_names; }; static bool parse_ridlist(TALLOC_CTX *mem_ctx, char *ridstr, uint32_t **prids, uint32_t *pnum_rids); -static void winbindd_lookuprids_done(struct tevent_req *subreq); +static void winbindd_lookuprids_rids_done(struct tevent_req *subreq); +static void winbindd_lookuprids_sids_done(struct tevent_req *subreq); struct tevent_req *winbindd_lookuprids_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -43,6 +49,7 @@ struct tevent_req *winbindd_lookuprids_send(TALLOC_CTX *mem_ctx, struct winbindd_lookuprids_state *state; struct winbindd_domain *domain; struct dom_sid sid; + uint32_t i; req = tevent_req_create(mem_ctx, &state, struct winbindd_lookuprids_state); @@ -83,17 +90,52 @@ struct tevent_req *winbindd_lookuprids_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - subreq = dcerpc_wbint_LookupRids_send( - state, ev, dom_child_handle(domain), &state->rids, - &state->domain_name, &state->names); + if (sid_check_is_domain(&sid)) { + subreq = dcerpc_wbint_LookupRids_send( + state, ev, dom_child_handle(domain), &state->rids, + &state->domain_name, &state->names); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, winbindd_lookuprids_rids_done, req); + return req; + } + + state->tmp_sids.num_sids = state->rids.num_rids; + state->tmp_sids.sids = talloc_array(state, struct lsa_SidPtr, + state->tmp_sids.num_sids); + if (tevent_req_nomem(state->tmp_sids.sids, req)) { + return tevent_req_post(req, ev); + } + + for (i=0; irids.num_rids; i++) { + struct lsa_SidPtr *cur = &state->tmp_sids.sids[i]; + cur->sid = dom_sid_add_rid(state->tmp_sids.sids, + &sid, state->rids.rids[i]); + if (tevent_req_nomem(cur->sid, req)) { + return tevent_req_post(req, ev); + } + } + + state->names.num_principals = state->rids.num_rids; + state->names.principals = talloc_array(state, + struct wbint_Principal, + state->names.num_principals); + if (tevent_req_nomem(state->names.principals, req)) { + return tevent_req_post(req, ev); + } + + subreq = dcerpc_wbint_LookupSids_send( + state, state->ev, dom_child_handle(domain), + &state->tmp_sids, &state->tmp_domains, &state->tmp_names); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, winbindd_lookuprids_done, req); + tevent_req_set_callback(subreq, winbindd_lookuprids_sids_done, req); return req; } -static void winbindd_lookuprids_done(struct tevent_req *subreq) +static void winbindd_lookuprids_rids_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); @@ -110,6 +152,52 @@ static void winbindd_lookuprids_done(struct tevent_req *subreq) tevent_req_done(req); } +static void winbindd_lookuprids_sids_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct winbindd_lookuprids_state *state = tevent_req_data( + req, struct winbindd_lookuprids_state); + NTSTATUS status, result; + uint32_t i; + + status = dcerpc_wbint_LookupSids_recv(subreq, state, &result); + TALLOC_FREE(subreq); + if (any_nt_status_not_ok(status, result, &status)) { + tevent_req_nterror(req, status); + return; + } + + if (state->tmp_names.count != state->names.num_principals) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + if (state->tmp_domains.count != 1) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + state->domain_name = talloc_move(state, + &state->tmp_domains.domains[0].name.string); + + for (i=0; i < state->tmp_names.count; i++) { + struct lsa_TranslatedName *n = &state->tmp_names.names[i]; + struct wbint_Principal *p = &state->names.principals[i]; + + if (n->sid_index != 0) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + p->name = talloc_move(state->names.principals, &n->name.string); + p->sid = *state->tmp_sids.sids[i].sid; + p->type = n->sid_type; + } + + tevent_req_done(req); +} + NTSTATUS winbindd_lookuprids_recv(struct tevent_req *req, struct winbindd_response *response) { -- 2.34.1