From 223fbdaf3872fe71a75fec62813b91612af73a2b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 May 2014 17:00:09 +1200 Subject: s3-winbindd: Listen on IRPC and do forwarded DNS updates on an RODC Change-Id: Ib87933c318f510d95f7008e122216d73803ede68 Signed-off-by: Andrew Bartlett Reviewed-by: Andreas Schneider --- source3/librpc/idl/wbint.idl | 6 ++ source3/winbindd/winbindd.c | 8 +++ source3/winbindd/winbindd_dual_srv.c | 39 +++++++++++++ source3/winbindd/winbindd_proto.h | 5 ++ source3/winbindd/winbindd_update_rodc_dns.c | 85 +++++++++++++++++++++++++++++ source3/wscript_build | 1 + 6 files changed, 144 insertions(+) create mode 100644 source3/winbindd/winbindd_update_rodc_dns.c (limited to 'source3') diff --git a/source3/librpc/idl/wbint.idl b/source3/librpc/idl/wbint.idl index f05107a0a8b..e91ef072fcc 100644 --- a/source3/librpc/idl/wbint.idl +++ b/source3/librpc/idl/wbint.idl @@ -167,4 +167,10 @@ interface wbint NTSTATUS wbint_PingDc( [out,string,charset(UTF8)] char **dcname ); + + NTSTATUS wbint_DsrUpdateReadOnlyServerDnsRecords( + [in,unique] [string,charset(UTF16)] uint16 *site_name, + [in] uint32 dns_ttl, + [in,out,ref] NL_DNS_NAME_INFO_ARRAY *dns_names + ); } diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 8a2c09e5158..153a400f2e8 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -42,6 +42,7 @@ #include "source4/lib/messaging/irpc.h" #include "source4/lib/messaging/messaging.h" #include "lib/param/param.h" +#include "source4/librpc/gen_ndr/ndr_winbind.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -1147,6 +1148,7 @@ bool winbindd_use_cache(void) static void winbindd_register_handlers(struct messaging_context *msg_ctx, bool foreground) { + NTSTATUS status; /* Setup signal handlers */ if (!winbindd_setup_sig_term_handler(true)) @@ -1246,6 +1248,12 @@ static void winbindd_register_handlers(struct messaging_context *msg_ctx, } } + status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS, + wb_irpc_DsrUpdateReadOnlyServerDnsRecords, NULL); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Could not register IRPC handler for wb_irpc_DsrUpdateReadOnlyServerDnsRecords\n")); + exit(1); + } } struct winbindd_addrchanged_state { diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index f064467bf23..721d293c4d0 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -29,6 +29,7 @@ #include "../librpc/gen_ndr/ndr_netlogon_c.h" #include "idmap.h" #include "../libcli/security/security.h" +#include "../libcli/auth/netlogon_creds_cli.h" void _wbint_Ping(struct pipes_struct *p, struct wbint_Ping *r) { @@ -717,3 +718,41 @@ NTSTATUS _wbint_PingDc(struct pipes_struct *p, struct wbint_PingDc *r) DEBUG(5, ("winbindd_dual_ping_dc succeeded\n")); return NT_STATUS_OK; } + +NTSTATUS _wbint_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p, + struct wbint_DsrUpdateReadOnlyServerDnsRecords *r) +{ + struct winbindd_domain *domain; + NTSTATUS status; + struct rpc_pipe_client *netlogon_pipe; + + domain = wb_child_domain(); + if (domain == NULL) { + return NT_STATUS_REQUEST_NOT_ACCEPTED; + } + + status = cm_connect_netlogon(domain, &netlogon_pipe); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("could not open handle to NETLOGON pipe\n")); + goto done; + } + + status = netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords(domain->conn.netlogon_creds, + netlogon_pipe->binding_handle, + r->in.site_name, + r->in.dns_ttl, + r->in.dns_names); + + /* Pass back result code - zero for success, other values for + specific failures. */ + + DEBUG(3,("DNS records for domain %s %s\n", domain->name, + NT_STATUS_IS_OK(status) ? "changed" : "unchanged")); + + done: + DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2, + ("Update of DNS records via RW DC %s returned %s\n", + domain->name, nt_errstr(status))); + + return status; +} diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 642aadd440d..7f3eb92e0cb 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -908,4 +908,9 @@ NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx, /* The following definitions come from winbindd/winbindd_ads.c */ ADS_STATUS ads_idmap_cached_connection(ADS_STRUCT **adsp, const char *dom_name); +/* The following definitions come from winbindd/winbindd_update_rodc_dns.c */ +struct irpc_message; +struct winbind_DsrUpdateReadOnlyServerDnsRecords; +NTSTATUS wb_irpc_DsrUpdateReadOnlyServerDnsRecords(struct irpc_message *msg, + struct winbind_DsrUpdateReadOnlyServerDnsRecords *req); #endif /* _WINBINDD_PROTO_H_ */ diff --git a/source3/winbindd/winbindd_update_rodc_dns.c b/source3/winbindd/winbindd_update_rodc_dns.c new file mode 100644 index 00000000000..f809dc615fc --- /dev/null +++ b/source3/winbindd/winbindd_update_rodc_dns.c @@ -0,0 +1,85 @@ +/* + Unix SMB/CIFS implementation. + async implementation of WINBINDD_CHANGE_MACHINE_ACCT + Copyright (C) Volker Lendecke 2009 + Copyright (C) Guenther Deschner 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "winbindd.h" +#include "librpc/gen_ndr/ndr_wbint_c.h" +#include "librpc/gen_ndr/ndr_winbind_c.h" +#include "source4/lib/messaging/irpc.h" + +struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state { + struct irpc_message *msg; + struct winbind_DsrUpdateReadOnlyServerDnsRecords *req; +}; + +static void wb_irpc_DsrUpdateReadOnlyServerDnsRecords_callback(struct tevent_req *subreq); + +NTSTATUS wb_irpc_DsrUpdateReadOnlyServerDnsRecords(struct irpc_message *msg, + struct winbind_DsrUpdateReadOnlyServerDnsRecords *req) +{ + struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state *s; + struct tevent_req *subreq; + struct winbindd_domain *domain; + + DEBUG(5, ("wb_irpc_DsrUpdateReadOnlyServerDnsRecords called\n")); + + s = talloc(msg, struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state); + NT_STATUS_HAVE_NO_MEMORY(s); + + s->msg = msg; + s->req = req; + + domain = find_our_domain(); + if (domain == NULL) { + return NT_STATUS_NO_SUCH_DOMAIN; + } + + subreq = dcerpc_wbint_DsrUpdateReadOnlyServerDnsRecords_send(s, winbind_event_context(), + dom_child_handle(domain), + req->in.site_name, + req->in.dns_ttl, + req->in.dns_names); + if (!subreq) { + return NT_STATUS_NO_MEMORY; + } + + tevent_req_set_callback(subreq, + wb_irpc_DsrUpdateReadOnlyServerDnsRecords_callback, + s); + + msg->defer_reply = true; + return NT_STATUS_OK; +} + +static void wb_irpc_DsrUpdateReadOnlyServerDnsRecords_callback(struct tevent_req *subreq) +{ + 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")); + + status = dcerpc_wbint_DsrUpdateReadOnlyServerDnsRecords_recv(subreq, s, &result); + any_nt_status_not_ok(status, result, &status); + TALLOC_FREE(subreq); + + irpc_send_reply(s->msg, status); +} diff --git a/source3/wscript_build b/source3/wscript_build index 806a49712c2..a0080b32fcb 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -943,6 +943,7 @@ bld.SAMBA3_BINARY('winbindd/winbindd', winbindd/winbindd_list_groups.c winbindd/winbindd_check_machine_acct.c winbindd/winbindd_change_machine_acct.c + winbindd/winbindd_update_rodc_dns.c winbindd/winbindd_ping_dc.c winbindd/winbindd_pam_auth.c winbindd/winbindd_pam_logoff.c -- cgit