From eabe7d732e6d9b64004bbb477384a1eae999815f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 8 May 2014 15:33:11 +1200 Subject: [PATCH] s3-winbind: Transparently forward IRPC messages to the winbind_dual child Change-Id: I8b336e2365e10ef9ea04d0957eb0829d3766b11e Signed-off-by: Andrew Bartlett Reviewed-by: Andreas Schneider --- source3/winbindd/winbindd_irpc.c | 117 ++++++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 37 deletions(-) diff --git a/source3/winbindd/winbindd_irpc.c b/source3/winbindd/winbindd_irpc.c index e5aa53ffad4..3c33076d615 100644 --- a/source3/winbindd/winbindd_irpc.c +++ b/source3/winbindd/winbindd_irpc.c @@ -4,6 +4,7 @@ Copyright (C) Volker Lendecke 2009 Copyright (C) Guenther Deschner 2009 Copyright (C) Andrew Bartlett 2014 + Copyright (C) Andrew Tridgell 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,64 +26,106 @@ #include "source4/lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_winbind.h" -struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state { +struct wb_irpc_forward_state { struct irpc_message *msg; struct winbind_DsrUpdateReadOnlyServerDnsRecords *req; -}; -static void wb_irpc_DsrUpdateReadOnlyServerDnsRecords_callback(struct tevent_req *subreq); + const char *opname; + struct dcesrv_call_state *dce_call; +}; -NTSTATUS wb_irpc_DsrUpdateReadOnlyServerDnsRecords(struct irpc_message *msg, - struct winbind_DsrUpdateReadOnlyServerDnsRecords *req) +/* + called when the forwarded rpc request is finished + */ +static void wb_irpc_forward_callback(struct tevent_req *subreq) { - struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state *s; - struct tevent_req *subreq; - struct winbindd_domain *domain; + struct wb_irpc_forward_state *st = + tevent_req_callback_data(subreq, + struct wb_irpc_forward_state); + const char *opname = st->opname; + NTSTATUS status; - DEBUG(5, ("wb_irpc_DsrUpdateReadOnlyServerDnsRecords called\n")); + status = dcerpc_binding_handle_call_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("RPC callback failed for %s - %s\n", + opname, nt_errstr(status))); + irpc_send_reply(st->msg, status); + } - s = talloc(msg, struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state); - NT_STATUS_HAVE_NO_MEMORY(s); + irpc_send_reply(st->msg, status); +} - s->msg = msg; - s->req = req; - domain = find_our_domain(); - if (domain == NULL) { - return NT_STATUS_NO_SUCH_DOMAIN; - } - subreq = dcerpc_winbind_DsrUpdateReadOnlyServerDnsRecords_send(s, winbind_event_context(), - dom_child_handle(domain), - req->in.site_name, - req->in.dns_ttl, - req->in.dns_names); - if (!subreq) { +/** + * Forward a RPC call using IRPC to another task + */ + +static NTSTATUS wb_irpc_forward_rpc_call(struct irpc_message *msg, TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + void *r, uint32_t callid, + const char *opname, + struct winbindd_domain *domain, + uint32_t timeout) +{ + struct wb_irpc_forward_state *st; + struct dcerpc_binding_handle *binding_handle; + struct tevent_req *subreq; + + st = talloc(mem_ctx, struct wb_irpc_forward_state); + if (st == NULL) { return NT_STATUS_NO_MEMORY; } - tevent_req_set_callback(subreq, - wb_irpc_DsrUpdateReadOnlyServerDnsRecords_callback, - s); + st->msg = msg; + st->opname = opname; + + binding_handle = dom_child_handle(domain); + if (binding_handle == NULL) { + DEBUG(0,("%s: Failed to forward request to winbind handler for %s\n", + opname, domain->name)); + return NT_STATUS_UNSUCCESSFUL; + } + /* reset timeout for the handle */ + dcerpc_binding_handle_set_timeout(binding_handle, timeout); + + /* forward the call */ + subreq = dcerpc_binding_handle_call_send(st, ev, + binding_handle, + NULL, &ndr_table_winbind, + callid, + msg, r); + if (subreq == NULL) { + DEBUG(0,("%s: Failed to forward request to winbind handler for %s\n", + opname, domain->name)); + return NT_STATUS_UNSUCCESSFUL; + } + + /* mark the request as replied async */ msg->defer_reply = true; + + /* setup the callback */ + tevent_req_set_callback(subreq, wb_irpc_forward_callback, st); return NT_STATUS_OK; } -static void wb_irpc_DsrUpdateReadOnlyServerDnsRecords_callback(struct tevent_req *subreq) +static NTSTATUS wb_irpc_DsrUpdateReadOnlyServerDnsRecords(struct irpc_message *msg, + struct winbind_DsrUpdateReadOnlyServerDnsRecords *req) { - struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state *s = - tevent_req_callback_data(subreq, - struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state); - NTSTATUS status, result; - - DEBUG(5, ("wb_irpc_DsrUpdateReadOnlyServerDnsRecords_callback called\n")); + struct winbindd_domain *domain = find_our_domain(); + if (domain == NULL) { + return NT_STATUS_NO_SUCH_DOMAIN; + } - status = dcerpc_winbind_DsrUpdateReadOnlyServerDnsRecords_recv(subreq, s, &result); - any_nt_status_not_ok(status, result, &status); - TALLOC_FREE(subreq); + DEBUG(5, ("wb_irpc_DsrUpdateReadOnlyServerDnsRecords called\n")); - irpc_send_reply(s->msg, status); + return wb_irpc_forward_rpc_call(msg, msg, + winbind_event_context(), + req, NDR_WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS, + "winbind_DsrUpdateReadOnlyServerDnsRecords", + domain, IRPC_CALL_TIMEOUT); } NTSTATUS wb_irpc_register(void) -- 2.11.4.GIT