From 065e2a922d1494acd0b88e532c2ac1c0673c1ff5 Mon Sep 17 00:00:00 2001 From: Sam Liddicott Date: Wed, 5 Jun 2013 16:56:23 +0100 Subject: [PATCH] Winbind cope with disconnected LSA transport, bugzilla #9806 winbind could not detect or recover when lsa auth pipe went away Fix is to detect this when pulling a domain entry from the sid2domain cache, and to retry on a NT_STATUS_CONNECTION_RESET error Signed-off-by: Sam Liddicott --- source4/winbind/wb_irpc.c | 20 ++++++++++++++++++++ source4/winbind/wb_sid2domain.c | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/source4/winbind/wb_irpc.c b/source4/winbind/wb_irpc.c index 628114e..95b621e 100644 --- a/source4/winbind/wb_irpc.c +++ b/source4/winbind/wb_irpc.c @@ -28,6 +28,7 @@ struct wb_irpc_SamLogon_state { struct irpc_message *msg; struct winbind_SamLogon *req; + int retries; }; static void wb_irpc_SamLogon_callback(struct tevent_req *subreq); @@ -47,6 +48,7 @@ static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg, s->msg = msg; s->req = req; + s->retries = 1; subreq = wb_sam_logon_send(s, service->task->event_ctx, @@ -64,11 +66,29 @@ static void wb_irpc_SamLogon_callback(struct tevent_req *subreq) struct wb_irpc_SamLogon_state *s = tevent_req_callback_data(subreq, struct wb_irpc_SamLogon_state); + struct wbsrv_service *service = talloc_get_type(s->msg->private_data, + struct wbsrv_service); NTSTATUS status; DEBUG(5, ("wb_irpc_SamLogon_callback called\n")); status = wb_sam_logon_recv(subreq, s, s->req); + + if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET) && (s->retries--)) { + DEBUG(1,("%s Connection reset, try again\n", __FUNCTION__)); + TALLOC_FREE(subreq); + subreq = wb_sam_logon_send(s, + service->task->event_ctx, + service, s->req); + if (! subreq) { + irpc_send_reply(s->msg, NT_STATUS_NO_MEMORY); + return; + } + + tevent_req_set_callback(subreq, wb_irpc_SamLogon_callback, s); + return; + } + TALLOC_FREE(subreq); irpc_send_reply(s->msg, status); diff --git a/source4/winbind/wb_sid2domain.c b/source4/winbind/wb_sid2domain.c index 637fe1d..dc6cf4e 100644 --- a/source4/winbind/wb_sid2domain.c +++ b/source4/winbind/wb_sid2domain.c @@ -35,6 +35,11 @@ static struct wbsrv_domain *find_domain_from_sid(struct wbsrv_service *service, struct wbsrv_domain *domain; for (domain = service->domains; domain!=NULL; domain = domain->next) { + if (! (dcerpc_binding_handle_is_connected(domain->netlogon_pipe->binding_handle))) { + DLIST_REMOVE(service->domains, domain); + talloc_free(domain); + return find_domain_from_sid(service, sid); + } if (dom_sid_equal(domain->info->sid, sid)) { break; } @@ -79,6 +84,10 @@ static struct tevent_req *_wb_sid2domain_send(TALLOC_CTX *mem_ctx, state->domain = find_domain_from_sid(service, sid); if (state->domain != NULL) { + /* We don't want it to be reaped while we use it + just because someone else found the connection + had died and free'd it from find_domain_from_sid */ + talloc_reference(mem_ctx, state->domain); tevent_req_done(req); return tevent_req_post(req, ev); } -- 1.7.10.4