summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2014-05-08 15:33:11 +1200
committerAndrew Bartlett <abartlet@samba.org>2014-06-11 10:18:26 +0200
commiteabe7d732e6d9b64004bbb477384a1eae999815f (patch)
tree440f7408bde1ea0ecee79c16b9ef3fdeec1ca3d2
parentfaa4452df7f2add0b4b583a25365b43da8ec1305 (diff)
downloadsamba-eabe7d732e6d9b64004bbb477384a1eae999815f.tar.gz
samba-eabe7d732e6d9b64004bbb477384a1eae999815f.tar.xz
samba-eabe7d732e6d9b64004bbb477384a1eae999815f.zip
s3-winbind: Transparently forward IRPC messages to the winbind_dual child
Change-Id: I8b336e2365e10ef9ea04d0957eb0829d3766b11e Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
-rw-r--r--source3/winbindd/winbindd_irpc.c117
1 files 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)