The Samba-Bugzilla – Attachment 10525 Details for
Bug 9404
Adding a zone via the dnsserver RPC interface should trigger a zone reload in the internal DNS server
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to notify DNS server when zones are created or deleted through RPC (for 4.1)
0001-s4-dns-Reload-zones-from-dsdb-when-zones-are-added-o.patch.for41 (text/plain), 9.47 KB, created by
Samuel Cabrero
on 2014-12-11 12:10:13 UTC
(
hide
)
Description:
Patch to notify DNS server when zones are created or deleted through RPC (for 4.1)
Filename:
MIME Type:
Creator:
Samuel Cabrero
Created:
2014-12-11 12:10:13 UTC
Size:
9.47 KB
patch
obsolete
>From 4c2381898351468dc33eb97ec32dea436f31200b Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <samuelcabrero@kernevil.me> >Date: Thu, 11 Dec 2014 12:19:08 +0100 >Subject: [PATCH] s4-dns: Reload zones from dsdb when zones are added or > deleted through RPC > >Setup a RPC management call on the internal DNS server triggered by the >RPC server when zones are added or deleted by ZoneCreate or DeleteZoneFromDs >calls. > >Signed-off-by: Samuel Cabrero <samuelcabrero@kernevil.me> >--- > source4/dns_server/dns_server.c | 133 +++++++++++++++++------- > source4/librpc/idl/irpc.idl | 11 ++ > source4/rpc_server/dnsserver/dcerpc_dnsserver.c | 57 ++++++++++ > 3 files changed, 163 insertions(+), 38 deletions(-) > >diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c >index f1a4c4c..f46efd3 100644 >--- a/source4/dns_server/dns_server.c >+++ b/source4/dns_server/dns_server.c >@@ -45,6 +45,8 @@ > #include "lib/util/tevent_werror.h" > #include "auth/auth.h" > #include "auth/credentials/credentials.h" >+#include "librpc/gen_ndr/ndr_irpc.h" >+#include "lib/messaging/irpc.h" > > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_DNS >@@ -761,16 +763,89 @@ static struct dns_server_tkey_store *tkey_store_init(TALLOC_CTX *mem_ctx, > return buffer; > } > >+static NTSTATUS dns_server_reload_zones(struct dns_server *dns) >+{ >+ int ret; >+ static const char * const attrs[] = { "name", NULL}; >+ struct ldb_result *res; >+ int i; >+ struct dns_server_zone *new_list = NULL; >+ struct dns_server_zone *old_list = NULL; >+ struct dns_server_zone *z; >+ >+ // TODO: this search does not work against windows >+ ret = dsdb_search(dns->samdb, dns, &res, NULL, LDB_SCOPE_SUBTREE, >+ attrs, DSDB_SEARCH_SEARCH_ALL_PARTITIONS, "(objectClass=dnsZone)"); >+ if (ret != LDB_SUCCESS) { >+ return NT_STATUS_INTERNAL_DB_CORRUPTION; >+ } >+ >+ TYPESAFE_QSORT(res->msgs, res->count, dns_server_sort_zones); >+ >+ for (i=0; i < res->count; i++) { >+ struct dns_server_zone *z; >+ >+ z = talloc_zero(dns, struct dns_server_zone); >+ if (z == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ >+ z->name = ldb_msg_find_attr_as_string(res->msgs[i], "name", NULL); >+ z->dn = talloc_move(z, &res->msgs[i]->dn); >+ /* >+ * Ignore the RootDNSServers zone and zones that we don't support yet >+ * RootDNSServers should never be returned (Windows DNS server don't) >+ * ..TrustAnchors should never be returned as is, (Windows returns >+ * TrustAnchors) and for the moment we don't support DNSSEC so we'd better >+ * not return this zone. >+ */ >+ if ((strcmp(z->name, "RootDNSServers") == 0) || >+ (strcmp(z->name, "..TrustAnchors") == 0)) >+ { >+ DEBUG(10, ("Ignoring zone %s\n", z->name)); >+ talloc_free(z); >+ continue; >+ } >+ DLIST_ADD_END(new_list, z, NULL); >+ } >+ >+ old_list = dns->zones; >+ dns->zones = new_list; >+ while ((z = DLIST_TAIL(old_list)) != NULL) { >+ DLIST_REMOVE(old_list, z); >+ talloc_free(z); >+ } >+ >+ return NT_STATUS_OK; >+} >+ >+/** >+ * Called when the internal DNS server should reload the zones from DB, for >+ * example, when zones are added or deleted through RPC. >+ */ >+static NTSTATUS dns_reload_zones(struct irpc_message *msg, >+ struct dns_server_reload_zones *r) >+{ >+ struct dns_server *dns; >+ >+ dns = talloc_get_type(msg->private_data, struct dns_server); >+ if (dns == NULL) { >+ r->out.result = NT_STATUS_INTERNAL_ERROR; >+ return NT_STATUS_INTERNAL_ERROR; >+ } >+ >+ r->out.result = dns_server_reload_zones(dns); >+ >+ return NT_STATUS_OK; >+} >+ > static void dns_task_init(struct task_server *task) > { > struct dns_server *dns; > NTSTATUS status; > struct interface *ifaces = NULL; > int ret; >- struct ldb_result *res; >- static const char * const attrs[] = { "name", NULL}; > static const char * const attrs_none[] = { NULL}; >- unsigned int i; > struct ldb_message *dns_acc; > char *hostname_lower; > char *dns_spn; >@@ -866,48 +941,30 @@ static void dns_task_init(struct task_server *task) > return; > } > >- // TODO: this search does not work against windows >- ret = dsdb_search(dns->samdb, dns, &res, NULL, LDB_SCOPE_SUBTREE, >- attrs, DSDB_SEARCH_SEARCH_ALL_PARTITIONS, "(objectClass=dnsZone)"); >- if (ret != LDB_SUCCESS) { >- task_server_terminate(task, >- "dns: failed to look up root DNS zones", >- true); >+ status = dns_server_reload_zones(dns); >+ if (!NT_STATUS_IS_OK(status)) { >+ task_server_terminate(task, "dns: failed to load DNS zones", true); > return; > } > >- TYPESAFE_QSORT(res->msgs, res->count, dns_server_sort_zones); >- >- for (i=0; i < res->count; i++) { >- struct dns_server_zone *z; >- >- z = talloc_zero(dns, struct dns_server_zone); >- if (z == NULL) { >- task_server_terminate(task, "dns failed to allocate memory", true); >- } >+ status = dns_startup_interfaces(dns, ifaces); >+ if (!NT_STATUS_IS_OK(status)) { >+ task_server_terminate(task, "dns failed to setup interfaces", true); >+ return; >+ } > >- z->name = ldb_msg_find_attr_as_string(res->msgs[i], "name", NULL); >- z->dn = talloc_move(z, &res->msgs[i]->dn); >- /* >- * Ignore the RootDNSServers zone and zones that we don't support yet >- * RootDNSServers should never be returned (Windows DNS server don't) >- * ..TrustAnchors should never be returned as is, (Windows returns >- * TrustAnchors) and for the moment we don't support DNSSEC so we'd better >- * not return this zone. >- */ >- if ((strcmp(z->name, "RootDNSServers") == 0) || >- (strcmp(z->name, "..TrustAnchors") == 0)) >- { >- DEBUG(10, ("Ignoring zone %s\n", z->name)); >- talloc_free(z); >- continue; >- } >- DLIST_ADD_END(dns->zones, z, NULL); >+ /* Setup the IRPC interface and register handlers */ >+ status = irpc_add_name(task->msg_ctx, "dns"); >+ if (!NT_STATUS_IS_OK(status)) { >+ task_server_terminate(task, "dns: failed to register IRPC name", true); >+ return; > } > >- status = dns_startup_interfaces(dns, ifaces); >+ status = IRPC_REGISTER(task->msg_ctx, irpc, DNS_SERVER_RELOAD_ZONES, >+ dns_reload_zones, dns); > if (!NT_STATUS_IS_OK(status)) { >- task_server_terminate(task, "dns failed to setup interfaces", true); >+ task_server_terminate(task, "dns: failed to setup reload " >+ "handler", true); > return; > } > } >diff --git a/source4/librpc/idl/irpc.idl b/source4/librpc/idl/irpc.idl >index 6a55eef..ce4ae25 100644 >--- a/source4/librpc/idl/irpc.idl >+++ b/source4/librpc/idl/irpc.idl >@@ -207,4 +207,15 @@ import "misc.idl", "security.idl", "nbt.idl", "netlogon.idl", "server_id.idl"; > [in] uint32 dns_ttl, > [in,out,ref] NL_DNS_NAME_INFO_ARRAY *dns_names > ); >+ >+ /****************************************************** >+ * Management calls for the dns server >+ ******************************************************/ >+ /** >+ * Force internal DNS server to reload the zones. >+ * >+ * Called when zones are added or deleted through RPC >+ * server. >+ */ >+ NTSTATUS dns_server_reload_zones(); > } >diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c >index be31500..0ce62b1 100644 >--- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c >+++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c >@@ -27,6 +27,9 @@ > #include "librpc/gen_ndr/ndr_dnsserver.h" > #include "dnsserver.h" > #include "lib/ldb/include/ldb_private.h" >+#include "librpc/gen_ndr/ndr_irpc.h" >+#include "lib/messaging/irpc.h" >+#include "librpc/gen_ndr/ndr_irpc_c.h" > > struct dnsserver_state { > struct loadparm_context *lp_ctx; >@@ -35,10 +38,59 @@ struct dnsserver_state { > struct dnsserver_zone *zones; > int zones_count; > struct dnsserver_serverinfo *serverinfo; >+ struct imessaging_context *msg_ctx; >+ struct tevent_context *event_ctx; > }; > > > /* Utility functions */ >+struct dnsserver_notify_dns_server_state { >+ struct dns_server_reload_zones r; >+}; >+ >+static void dnsserver_notify_dns_server_done(struct tevent_req *subreq); >+ >+/** >+ * Sends a notification to the dns server to reload zones from database >+ */ >+static void dnsserver_notify_dns_server(struct dnsserver_state *dsstate) >+{ >+ struct dnsserver_notify_dns_server_state *state; >+ struct dcerpc_binding_handle *irpc_handle; >+ struct tevent_req *subreq; >+ >+ state = talloc_zero(dsstate, struct dnsserver_notify_dns_server_state); >+ if (state == NULL) { >+ return; >+ } >+ >+ irpc_handle = irpc_binding_handle_by_name(state, dsstate->msg_ctx, >+ "dns", &ndr_table_irpc); >+ if (irpc_handle == NULL) { >+ /* DNS server not running */ >+ talloc_free(state); >+ return; >+ } >+ >+ subreq = dcerpc_dns_server_reload_zones_r_send(state, dsstate->event_ctx, >+ irpc_handle, &state->r); >+ if (subreq == NULL) { >+ talloc_free(state); >+ return; >+ } >+ tevent_req_set_callback(subreq, dnsserver_notify_dns_server_done, state); >+} >+ >+static void dnsserver_notify_dns_server_done(struct tevent_req *subreq) >+{ >+ struct dnsserver_notify_dns_server_state *state; >+ >+ state = tevent_req_callback_data(subreq, struct dnsserver_notify_dns_server_state); >+ >+ dcerpc_dns_server_reload_zones_r_recv(subreq, state); >+ talloc_free(subreq); >+ talloc_free(state); >+} > > static void dnsserver_reload_zones(struct dnsserver_state *dsstate) > { >@@ -90,6 +142,9 @@ static void dnsserver_reload_zones(struct dnsserver_state *dsstate) > } > > dsstate->zones = new_list; >+ >+ /* Send a notification to the dns server to reload zones */ >+ dnsserver_notify_dns_server(dsstate); > } > > >@@ -110,6 +165,8 @@ static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_c > } > > dsstate->lp_ctx = dce_call->conn->dce_ctx->lp_ctx; >+ dsstate->msg_ctx = dce_call->conn->msg_ctx; >+ dsstate->event_ctx = dce_call->conn->event_ctx; > > /* FIXME: create correct auth_session_info for connecting user */ > dsstate->samdb = samdb_connect(dsstate, dce_call->event_ctx, dsstate->lp_ctx, >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 9404
:
10524
| 10525 |
10821
|
10822