Avoid including libds/common/roles.h in public loadparm.h header.
[amitay/samba.git] / source4 / dns_server / dns_server.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    DNS server startup
5
6    Copyright (C) 2010 Kai Blin  <kai@samba.org>
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "smbd/service_task.h"
24 #include "smbd/service.h"
25 #include "smbd/service_stream.h"
26 #include "smbd/process_model.h"
27 #include "lib/events/events.h"
28 #include "lib/socket/socket.h"
29 #include "lib/tsocket/tsocket.h"
30 #include "libcli/util/tstream.h"
31 #include "libcli/util/ntstatus.h"
32 #include "system/network.h"
33 #include "lib/stream/packet.h"
34 #include "lib/socket/netif.h"
35 #include "dns_server/dns_server.h"
36 #include "param/param.h"
37 #include "librpc/ndr/libndr.h"
38 #include "librpc/gen_ndr/ndr_dns.h"
39 #include "librpc/gen_ndr/ndr_dnsp.h"
40 #include <ldb.h>
41 #include "dsdb/samdb/samdb.h"
42 #include "dsdb/common/util.h"
43 #include "auth/session.h"
44 #include "lib/util/dlinklist.h"
45 #include "lib/util/tevent_werror.h"
46 #include "auth/auth.h"
47 #include "auth/credentials/credentials.h"
48 #include "librpc/gen_ndr/ndr_irpc.h"
49 #include "lib/messaging/irpc.h"
50 #include "libds/common/roles.h"
51
52 #undef DBGC_CLASS
53 #define DBGC_CLASS DBGC_DNS
54
55 NTSTATUS server_service_dns_init(void);
56
57 /* hold information about one dns socket */
58 struct dns_socket {
59         struct dns_server *dns;
60         struct tsocket_address *local_address;
61 };
62
63 struct dns_udp_socket {
64         struct dns_socket *dns_socket;
65         struct tdgram_context *dgram;
66         struct tevent_queue *send_queue;
67 };
68
69 /*
70   state of an open tcp connection
71 */
72 struct dns_tcp_connection {
73         /* stream connection we belong to */
74         struct stream_connection *conn;
75
76         /* the dns_server the connection belongs to */
77         struct dns_socket *dns_socket;
78
79         struct tstream_context *tstream;
80
81         struct tevent_queue *send_queue;
82 };
83
84 static void dns_tcp_terminate_connection(struct dns_tcp_connection *dnsconn, const char *reason)
85 {
86         stream_terminate_connection(dnsconn->conn, reason);
87 }
88
89 static void dns_tcp_recv(struct stream_connection *conn, uint16_t flags)
90 {
91         struct dns_tcp_connection *dnsconn = talloc_get_type(conn->private_data,
92                                                              struct dns_tcp_connection);
93         /* this should never be triggered! */
94         dns_tcp_terminate_connection(dnsconn, "dns_tcp_recv: called");
95 }
96
97 static void dns_tcp_send(struct stream_connection *conn, uint16_t flags)
98 {
99         struct dns_tcp_connection *dnsconn = talloc_get_type(conn->private_data,
100                                                              struct dns_tcp_connection);
101         /* this should never be triggered! */
102         dns_tcp_terminate_connection(dnsconn, "dns_tcp_send: called");
103 }
104
105 struct dns_process_state {
106         DATA_BLOB *in;
107         struct dns_server *dns;
108         struct dns_name_packet in_packet;
109         struct dns_request_state state;
110         uint16_t dns_err;
111         struct dns_name_packet out_packet;
112         DATA_BLOB out;
113 };
114
115 static void dns_process_done(struct tevent_req *subreq);
116
117 static struct tevent_req *dns_process_send(TALLOC_CTX *mem_ctx,
118                                            struct tevent_context *ev,
119                                            struct dns_server *dns,
120                                            DATA_BLOB *in)
121 {
122         struct tevent_req *req, *subreq;
123         struct dns_process_state *state;
124         enum ndr_err_code ndr_err;
125         WERROR ret;
126         const char *forwarder = lpcfg_dns_forwarder(dns->task->lp_ctx);
127         req = tevent_req_create(mem_ctx, &state, struct dns_process_state);
128         if (req == NULL) {
129                 return NULL;
130         }
131         state->state.mem_ctx = state;
132         state->in = in;
133
134         state->dns = dns;
135
136         if (in->length < 12) {
137                 tevent_req_werror(req, WERR_INVALID_PARAM);
138                 return tevent_req_post(req, ev);
139         }
140         dump_data_dbgc(DBGC_DNS, 8, in->data, in->length);
141
142         ndr_err = ndr_pull_struct_blob(
143                 in, state, &state->in_packet,
144                 (ndr_pull_flags_fn_t)ndr_pull_dns_name_packet);
145
146         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
147                 state->dns_err = DNS_RCODE_FORMERR;
148                 tevent_req_done(req);
149                 return tevent_req_post(req, ev);
150         }
151         if (DEBUGLVLC(DBGC_DNS, 8)) {
152                 NDR_PRINT_DEBUGC(DBGC_DNS, dns_name_packet, &state->in_packet);
153         }
154
155         ret = dns_verify_tsig(dns, state, &state->state, &state->in_packet, in);
156         if (!W_ERROR_IS_OK(ret)) {
157                 DEBUG(1, ("Failed to verify TSIG!\n"));
158                 state->dns_err = werr_to_dns_err(ret);
159                 tevent_req_done(req);
160                 return tevent_req_post(req, ev);
161         }
162
163         if (state->in_packet.operation & DNS_FLAG_REPLY) {
164                 DEBUG(1, ("Won't reply to replies.\n"));
165                 tevent_req_werror(req, WERR_INVALID_PARAM);
166                 return tevent_req_post(req, ev);
167         }
168
169         state->state.flags = state->in_packet.operation;
170         state->state.flags |= DNS_FLAG_REPLY;
171
172         
173         if (forwarder && *forwarder) {
174                 state->state.flags |= DNS_FLAG_RECURSION_AVAIL;
175         }
176
177         state->out_packet = state->in_packet;
178
179         switch (state->in_packet.operation & DNS_OPCODE) {
180         case DNS_OPCODE_QUERY:
181                 subreq = dns_server_process_query_send(
182                         state, ev, dns, &state->state, &state->in_packet);
183                 if (tevent_req_nomem(subreq, req)) {
184                         return tevent_req_post(req, ev);
185                 }
186                 tevent_req_set_callback(subreq, dns_process_done, req);
187                 return req;
188         case DNS_OPCODE_UPDATE:
189                 ret = dns_server_process_update(
190                         dns, &state->state, state, &state->in_packet,
191                         &state->out_packet.answers, &state->out_packet.ancount,
192                         &state->out_packet.nsrecs,  &state->out_packet.nscount,
193                         &state->out_packet.additional,
194                         &state->out_packet.arcount);
195                 break;
196         default:
197                 ret = WERR_DNS_ERROR_RCODE_NOT_IMPLEMENTED;
198         }
199         if (!W_ERROR_IS_OK(ret)) {
200                 state->dns_err = werr_to_dns_err(ret);
201         }
202         tevent_req_done(req);
203         return tevent_req_post(req, ev);
204 }
205
206 static void dns_process_done(struct tevent_req *subreq)
207 {
208         struct tevent_req *req = tevent_req_callback_data(
209                 subreq, struct tevent_req);
210         struct dns_process_state *state = tevent_req_data(
211                 req, struct dns_process_state);
212         WERROR ret;
213
214         ret = dns_server_process_query_recv(
215                 subreq, state,
216                 &state->out_packet.answers, &state->out_packet.ancount,
217                 &state->out_packet.nsrecs,  &state->out_packet.nscount,
218                 &state->out_packet.additional, &state->out_packet.arcount);
219         TALLOC_FREE(subreq);
220
221         if (!W_ERROR_IS_OK(ret)) {
222                 state->dns_err = werr_to_dns_err(ret);
223         }
224         tevent_req_done(req);
225 }
226
227 static WERROR dns_process_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
228                                DATA_BLOB *out)
229 {
230         struct dns_process_state *state = tevent_req_data(
231                 req, struct dns_process_state);
232         enum ndr_err_code ndr_err;
233         WERROR ret;
234
235         if (tevent_req_is_werror(req, &ret)) {
236                 return ret;
237         }
238         if ((state->dns_err != DNS_RCODE_OK) &&
239             (state->dns_err != DNS_RCODE_NXDOMAIN)) {
240                 goto drop;
241         }
242         if (state->dns_err != DNS_RCODE_OK) {
243                 state->out_packet.operation |= state->dns_err;
244         }
245         state->out_packet.operation |= state->state.flags;
246
247         if (state->state.sign) {
248                 ret = dns_sign_tsig(state->dns, mem_ctx, &state->state,
249                                     &state->out_packet, 0);
250                 if (!W_ERROR_IS_OK(ret)) {
251                         state->dns_err = DNS_RCODE_SERVFAIL;
252                         goto drop;
253                 }
254         }
255
256         if (DEBUGLVLC(DBGC_DNS, 8)) {
257                 NDR_PRINT_DEBUGC(DBGC_DNS, dns_name_packet, &state->out_packet);
258         }
259
260         ndr_err = ndr_push_struct_blob(
261                 out, mem_ctx, &state->out_packet,
262                 (ndr_push_flags_fn_t)ndr_push_dns_name_packet);
263         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
264                 DEBUG(1, ("Failed to push packet: %s!\n",
265                           ndr_errstr(ndr_err)));
266                 state->dns_err = DNS_RCODE_SERVFAIL;
267                 goto drop;
268         }
269         return WERR_OK;
270
271 drop:
272         *out = data_blob_talloc(mem_ctx, state->in->data, state->in->length);
273         if (out->data == NULL) {
274                 return WERR_NOMEM;
275         }
276         out->data[2] |= 0x80; /* Toggle DNS_FLAG_REPLY */
277         out->data[3] |= state->dns_err;
278         return WERR_OK;
279 }
280
281 struct dns_tcp_call {
282         struct dns_tcp_connection *dns_conn;
283         DATA_BLOB in;
284         DATA_BLOB out;
285         uint8_t out_hdr[4];
286         struct iovec out_iov[2];
287 };
288
289 static void dns_tcp_call_process_done(struct tevent_req *subreq);
290 static void dns_tcp_call_writev_done(struct tevent_req *subreq);
291
292 static void dns_tcp_call_loop(struct tevent_req *subreq)
293 {
294         struct dns_tcp_connection *dns_conn = tevent_req_callback_data(subreq,
295                                       struct dns_tcp_connection);
296         struct dns_server *dns = dns_conn->dns_socket->dns;
297         struct dns_tcp_call *call;
298         NTSTATUS status;
299
300         call = talloc(dns_conn, struct dns_tcp_call);
301         if (call == NULL) {
302                 dns_tcp_terminate_connection(dns_conn, "dns_tcp_call_loop: "
303                                 "no memory for dns_tcp_call");
304                 return;
305         }
306         call->dns_conn = dns_conn;
307
308         status = tstream_read_pdu_blob_recv(subreq,
309                                             call,
310                                             &call->in);
311         TALLOC_FREE(subreq);
312         if (!NT_STATUS_IS_OK(status)) {
313                 const char *reason;
314
315                 reason = talloc_asprintf(call, "dns_tcp_call_loop: "
316                                          "tstream_read_pdu_blob_recv() - %s",
317                                          nt_errstr(status));
318                 if (!reason) {
319                         reason = nt_errstr(status);
320                 }
321
322                 dns_tcp_terminate_connection(dns_conn, reason);
323                 return;
324         }
325
326         DEBUG(10,("Received DNS TCP packet of length %lu from %s\n",
327                  (long) call->in.length,
328                  tsocket_address_string(dns_conn->conn->remote_address, call)));
329
330         /* skip length header */
331         call->in.data += 2;
332         call->in.length -= 2;
333
334         subreq = dns_process_send(call, dns->task->event_ctx, dns,
335                                   &call->in);
336         if (subreq == NULL) {
337                 dns_tcp_terminate_connection(
338                         dns_conn, "dns_tcp_call_loop: dns_process_send "
339                         "failed\n");
340                 return;
341         }
342         tevent_req_set_callback(subreq, dns_tcp_call_process_done, call);
343
344         /*
345          * The dns tcp pdu's has the length as 2 byte (initial_read_size),
346          * packet_full_request_u16 provides the pdu length then.
347          */
348         subreq = tstream_read_pdu_blob_send(dns_conn,
349                                             dns_conn->conn->event.ctx,
350                                             dns_conn->tstream,
351                                             2, /* initial_read_size */
352                                             packet_full_request_u16,
353                                             dns_conn);
354         if (subreq == NULL) {
355                 dns_tcp_terminate_connection(dns_conn, "dns_tcp_call_loop: "
356                                 "no memory for tstream_read_pdu_blob_send");
357                 return;
358         }
359         tevent_req_set_callback(subreq, dns_tcp_call_loop, dns_conn);
360 }
361
362 static void dns_tcp_call_process_done(struct tevent_req *subreq)
363 {
364         struct dns_tcp_call *call = tevent_req_callback_data(subreq,
365                         struct dns_tcp_call);
366         struct dns_tcp_connection *dns_conn = call->dns_conn;
367         WERROR err;
368
369         err = dns_process_recv(subreq, call, &call->out);
370         TALLOC_FREE(subreq);
371         if (!W_ERROR_IS_OK(err)) {
372                 DEBUG(1, ("dns_process returned %s\n", win_errstr(err)));
373                 dns_tcp_terminate_connection(dns_conn,
374                                 "dns_tcp_call_loop: process function failed");
375                 return;
376         }
377
378         /* First add the length of the out buffer */
379         RSSVAL(call->out_hdr, 0, call->out.length);
380         call->out_iov[0].iov_base = (char *) call->out_hdr;
381         call->out_iov[0].iov_len = 2;
382
383         call->out_iov[1].iov_base = (char *) call->out.data;
384         call->out_iov[1].iov_len = call->out.length;
385
386         subreq = tstream_writev_queue_send(call,
387                                            dns_conn->conn->event.ctx,
388                                            dns_conn->tstream,
389                                            dns_conn->send_queue,
390                                            call->out_iov, 2);
391         if (subreq == NULL) {
392                 dns_tcp_terminate_connection(dns_conn, "dns_tcp_call_loop: "
393                                 "no memory for tstream_writev_queue_send");
394                 return;
395         }
396         tevent_req_set_callback(subreq, dns_tcp_call_writev_done, call);
397 }
398
399 static void dns_tcp_call_writev_done(struct tevent_req *subreq)
400 {
401         struct dns_tcp_call *call = tevent_req_callback_data(subreq,
402                         struct dns_tcp_call);
403         int sys_errno;
404         int rc;
405
406         rc = tstream_writev_queue_recv(subreq, &sys_errno);
407         TALLOC_FREE(subreq);
408         if (rc == -1) {
409                 const char *reason;
410
411                 reason = talloc_asprintf(call, "dns_tcp_call_writev_done: "
412                                          "tstream_writev_queue_recv() - %d:%s",
413                                          sys_errno, strerror(sys_errno));
414                 if (!reason) {
415                         reason = "dns_tcp_call_writev_done: tstream_writev_queue_recv() failed";
416                 }
417
418                 dns_tcp_terminate_connection(call->dns_conn, reason);
419                 return;
420         }
421
422         /* We don't care about errors */
423
424         talloc_free(call);
425 }
426
427 /*
428   called when we get a new connection
429 */
430 static void dns_tcp_accept(struct stream_connection *conn)
431 {
432         struct dns_socket *dns_socket;
433         struct dns_tcp_connection *dns_conn;
434         struct tevent_req *subreq;
435         int rc;
436
437         dns_conn = talloc_zero(conn, struct dns_tcp_connection);
438         if (dns_conn == NULL) {
439                 stream_terminate_connection(conn,
440                                 "dns_tcp_accept: out of memory");
441                 return;
442         }
443
444         dns_conn->send_queue = tevent_queue_create(conn, "dns_tcp_accept");
445         if (dns_conn->send_queue == NULL) {
446                 stream_terminate_connection(conn,
447                                 "dns_tcp_accept: out of memory");
448                 return;
449         }
450
451         dns_socket = talloc_get_type(conn->private_data, struct dns_socket);
452
453         TALLOC_FREE(conn->event.fde);
454
455         rc = tstream_bsd_existing_socket(dns_conn,
456                         socket_get_fd(conn->socket),
457                         &dns_conn->tstream);
458         if (rc < 0) {
459                 stream_terminate_connection(conn,
460                                 "dns_tcp_accept: out of memory");
461                 return;
462         }
463
464         dns_conn->conn = conn;
465         dns_conn->dns_socket = dns_socket;
466         conn->private_data = dns_conn;
467
468         /*
469          * The dns tcp pdu's has the length as 2 byte (initial_read_size),
470          * packet_full_request_u16 provides the pdu length then.
471          */
472         subreq = tstream_read_pdu_blob_send(dns_conn,
473                                             dns_conn->conn->event.ctx,
474                                             dns_conn->tstream,
475                                             2, /* initial_read_size */
476                                             packet_full_request_u16,
477                                             dns_conn);
478         if (subreq == NULL) {
479                 dns_tcp_terminate_connection(dns_conn, "dns_tcp_accept: "
480                                 "no memory for tstream_read_pdu_blob_send");
481                 return;
482         }
483         tevent_req_set_callback(subreq, dns_tcp_call_loop, dns_conn);
484 }
485
486 static const struct stream_server_ops dns_tcp_stream_ops = {
487         .name                   = "dns_tcp",
488         .accept_connection      = dns_tcp_accept,
489         .recv_handler           = dns_tcp_recv,
490         .send_handler           = dns_tcp_send
491 };
492
493 struct dns_udp_call {
494         struct dns_udp_socket *sock;
495         struct tsocket_address *src;
496         DATA_BLOB in;
497         DATA_BLOB out;
498 };
499
500 static void dns_udp_call_process_done(struct tevent_req *subreq);
501 static void dns_udp_call_sendto_done(struct tevent_req *subreq);
502
503 static void dns_udp_call_loop(struct tevent_req *subreq)
504 {
505         struct dns_udp_socket *sock = tevent_req_callback_data(subreq,
506                                       struct dns_udp_socket);
507         struct dns_server *dns = sock->dns_socket->dns;
508         struct dns_udp_call *call;
509         uint8_t *buf;
510         ssize_t len;
511         int sys_errno;
512
513         call = talloc(sock, struct dns_udp_call);
514         if (call == NULL) {
515                 talloc_free(call);
516                 goto done;
517         }
518         call->sock = sock;
519
520         len = tdgram_recvfrom_recv(subreq, &sys_errno,
521                                    call, &buf, &call->src);
522         TALLOC_FREE(subreq);
523         if (len == -1) {
524                 talloc_free(call);
525                 goto done;
526         }
527
528         call->in.data = buf;
529         call->in.length = len;
530
531         DEBUG(10,("Received DNS UDP packet of length %lu from %s\n",
532                  (long)call->in.length,
533                  tsocket_address_string(call->src, call)));
534
535         subreq = dns_process_send(call, dns->task->event_ctx, dns,
536                                   &call->in);
537         if (subreq == NULL) {
538                 TALLOC_FREE(call);
539                 goto done;
540         }
541         tevent_req_set_callback(subreq, dns_udp_call_process_done, call);
542
543 done:
544         subreq = tdgram_recvfrom_send(sock,
545                                       sock->dns_socket->dns->task->event_ctx,
546                                       sock->dgram);
547         if (subreq == NULL) {
548                 task_server_terminate(sock->dns_socket->dns->task,
549                                       "no memory for tdgram_recvfrom_send",
550                                       true);
551                 return;
552         }
553         tevent_req_set_callback(subreq, dns_udp_call_loop, sock);
554 }
555
556 static void dns_udp_call_process_done(struct tevent_req *subreq)
557 {
558         struct dns_udp_call *call = tevent_req_callback_data(
559                 subreq, struct dns_udp_call);
560         struct dns_udp_socket *sock = call->sock;
561         struct dns_server *dns = sock->dns_socket->dns;
562         WERROR err;
563
564         err = dns_process_recv(subreq, call, &call->out);
565         TALLOC_FREE(subreq);
566         if (!W_ERROR_IS_OK(err)) {
567                 DEBUG(1, ("dns_process returned %s\n", win_errstr(err)));
568                 TALLOC_FREE(call);
569                 return;
570         }
571
572         subreq = tdgram_sendto_queue_send(call,
573                                           dns->task->event_ctx,
574                                           sock->dgram,
575                                           sock->send_queue,
576                                           call->out.data,
577                                           call->out.length,
578                                           call->src);
579         if (subreq == NULL) {
580                 talloc_free(call);
581                 return;
582         }
583         tevent_req_set_callback(subreq, dns_udp_call_sendto_done, call);
584
585 }
586 static void dns_udp_call_sendto_done(struct tevent_req *subreq)
587 {
588         struct dns_udp_call *call = tevent_req_callback_data(subreq,
589                                        struct dns_udp_call);
590         int sys_errno;
591
592         tdgram_sendto_queue_recv(subreq, &sys_errno);
593
594         /* We don't care about errors */
595
596         talloc_free(call);
597 }
598
599 /*
600   start listening on the given address
601 */
602 static NTSTATUS dns_add_socket(struct dns_server *dns,
603                                const struct model_ops *model_ops,
604                                const char *name,
605                                const char *address,
606                                uint16_t port)
607 {
608         struct dns_socket *dns_socket;
609         struct dns_udp_socket *dns_udp_socket;
610         struct tevent_req *udpsubreq;
611         NTSTATUS status;
612         int ret;
613
614         dns_socket = talloc(dns, struct dns_socket);
615         NT_STATUS_HAVE_NO_MEMORY(dns_socket);
616
617         dns_socket->dns = dns;
618
619         ret = tsocket_address_inet_from_strings(dns_socket, "ip",
620                                                 address, port,
621                                                 &dns_socket->local_address);
622         if (ret != 0) {
623                 status = map_nt_error_from_unix_common(errno);
624                 return status;
625         }
626
627         status = stream_setup_socket(dns->task,
628                                      dns->task->event_ctx,
629                                      dns->task->lp_ctx,
630                                      model_ops,
631                                      &dns_tcp_stream_ops,
632                                      "ip", address, &port,
633                                      lpcfg_socket_options(dns->task->lp_ctx),
634                                      dns_socket);
635         if (!NT_STATUS_IS_OK(status)) {
636                 DEBUG(0,("Failed to bind to %s:%u TCP - %s\n",
637                          address, port, nt_errstr(status)));
638                 talloc_free(dns_socket);
639                 return status;
640         }
641
642         dns_udp_socket = talloc(dns_socket, struct dns_udp_socket);
643         NT_STATUS_HAVE_NO_MEMORY(dns_udp_socket);
644
645         dns_udp_socket->dns_socket = dns_socket;
646
647         ret = tdgram_inet_udp_socket(dns_socket->local_address,
648                                      NULL,
649                                      dns_udp_socket,
650                                      &dns_udp_socket->dgram);
651         if (ret != 0) {
652                 status = map_nt_error_from_unix_common(errno);
653                 DEBUG(0,("Failed to bind to %s:%u UDP - %s\n",
654                          address, port, nt_errstr(status)));
655                 return status;
656         }
657
658         dns_udp_socket->send_queue = tevent_queue_create(dns_udp_socket,
659                                                          "dns_udp_send_queue");
660         NT_STATUS_HAVE_NO_MEMORY(dns_udp_socket->send_queue);
661
662         udpsubreq = tdgram_recvfrom_send(dns_udp_socket,
663                                          dns->task->event_ctx,
664                                          dns_udp_socket->dgram);
665         NT_STATUS_HAVE_NO_MEMORY(udpsubreq);
666         tevent_req_set_callback(udpsubreq, dns_udp_call_loop, dns_udp_socket);
667
668         return NT_STATUS_OK;
669 }
670
671 /*
672   setup our listening sockets on the configured network interfaces
673 */
674 static NTSTATUS dns_startup_interfaces(struct dns_server *dns,
675                                        struct interface *ifaces)
676 {
677         const struct model_ops *model_ops;
678         int num_interfaces;
679         TALLOC_CTX *tmp_ctx = talloc_new(dns);
680         NTSTATUS status;
681         int i;
682
683         /* within the dns task we want to be a single process, so
684            ask for the single process model ops and pass these to the
685            stream_setup_socket() call. */
686         model_ops = process_model_startup("single");
687         if (!model_ops) {
688                 DEBUG(0,("Can't find 'single' process model_ops\n"));
689                 return NT_STATUS_INTERNAL_ERROR;
690         }
691
692         if (ifaces != NULL) {
693                 num_interfaces = iface_list_count(ifaces);
694
695                 for (i=0; i<num_interfaces; i++) {
696                         const char *address = talloc_strdup(tmp_ctx,
697                                                             iface_list_n_ip(ifaces, i));
698
699                         status = dns_add_socket(dns, model_ops, "dns", address,
700                                                 DNS_SERVICE_PORT);
701                         NT_STATUS_NOT_OK_RETURN(status);
702                 }
703         } else {
704                 int num_binds = 0;
705                 char **wcard;
706                 wcard = iface_list_wildcard(tmp_ctx);
707                 if (wcard == NULL) {
708                         DEBUG(0, ("No wildcard address available\n"));
709                         return NT_STATUS_INTERNAL_ERROR;
710                 }
711                 for (i = 0; wcard[i] != NULL; i++) {
712                         status = dns_add_socket(dns, model_ops, "dns", wcard[i],
713                                                 DNS_SERVICE_PORT);
714                         if (NT_STATUS_IS_OK(status)) {
715                                 num_binds++;
716                         }
717                 }
718                 if (num_binds == 0) {
719                         talloc_free(tmp_ctx);
720                         return NT_STATUS_INVALID_PARAMETER_MIX;
721                 }
722         }
723
724         talloc_free(tmp_ctx);
725
726         return NT_STATUS_OK;
727 }
728
729 static struct dns_server_tkey_store *tkey_store_init(TALLOC_CTX *mem_ctx,
730                                                      uint16_t size)
731 {
732         struct dns_server_tkey_store *buffer = talloc_zero(mem_ctx,
733                                                 struct dns_server_tkey_store);
734
735         if (buffer == NULL) {
736                 return NULL;
737         }
738
739         buffer->size = size;
740         buffer->next_idx = 0;
741
742         buffer->tkeys = talloc_zero_array(buffer, struct dns_server_tkey *, size);
743         if (buffer->tkeys == NULL) {
744                 TALLOC_FREE(buffer);
745         }
746
747         return buffer;
748 }
749
750 static NTSTATUS dns_server_reload_zones(struct dns_server *dns)
751 {
752         NTSTATUS status;
753         struct dns_server_zone *new_list = NULL;
754         struct dns_server_zone *old_list = NULL;
755         struct dns_server_zone *old_zone;
756         status = dns_common_zones(dns->samdb, dns, &new_list);
757         if (!NT_STATUS_IS_OK(status)) {
758                 return status;
759         }
760         dns->zones = new_list;
761         while ((old_zone = DLIST_TAIL(old_list)) != NULL) {
762                 DLIST_REMOVE(old_list, old_zone);
763                 talloc_free(old_zone);
764         }
765
766         return NT_STATUS_OK;
767 }
768
769 /**
770  * Called when the internal DNS server should reload the zones from DB, for
771  * example, when zones are added or deleted through RPC or replicated by
772  * inbound DRS.
773  */
774 static NTSTATUS dns_reload_zones(struct irpc_message *msg,
775                                  struct dnssrv_reload_dns_zones *r)
776 {
777         struct dns_server *dns;
778
779         dns = talloc_get_type(msg->private_data, struct dns_server);
780         if (dns == NULL) {
781                 r->out.result = NT_STATUS_INTERNAL_ERROR;
782                 return NT_STATUS_INTERNAL_ERROR;
783         }
784
785         r->out.result = dns_server_reload_zones(dns);
786
787         return NT_STATUS_OK;
788 }
789
790 static void dns_task_init(struct task_server *task)
791 {
792         struct dns_server *dns;
793         NTSTATUS status;
794         struct interface *ifaces = NULL;
795         int ret;
796         static const char * const attrs_none[] = { NULL};
797         struct ldb_message *dns_acc;
798         char *hostname_lower;
799         char *dns_spn;
800
801         switch (lpcfg_server_role(task->lp_ctx)) {
802         case ROLE_STANDALONE:
803                 task_server_terminate(task, "dns: no DNS required in standalone configuration", false);
804                 return;
805         case ROLE_DOMAIN_MEMBER:
806                 task_server_terminate(task, "dns: no DNS required in member server configuration", false);
807                 return;
808         case ROLE_ACTIVE_DIRECTORY_DC:
809                 /* Yes, we want a DNS */
810                 break;
811         }
812
813         if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) {
814                 load_interface_list(task, task->lp_ctx, &ifaces);
815
816                 if (iface_list_count(ifaces) == 0) {
817                         task_server_terminate(task, "dns: no network interfaces configured", false);
818                         return;
819                 }
820         }
821
822         task_server_set_title(task, "task[dns]");
823
824         dns = talloc_zero(task, struct dns_server);
825         if (dns == NULL) {
826                 task_server_terminate(task, "dns: out of memory", true);
827                 return;
828         }
829
830         dns->task = task;
831         /*FIXME: Make this a configurable option */
832         dns->max_payload = 4096;
833
834         dns->server_credentials = cli_credentials_init(dns);
835         if (!dns->server_credentials) {
836                 task_server_terminate(task, "Failed to init server credentials\n", true);
837                 return;
838         }
839
840         dns->samdb = samdb_connect(dns, dns->task->event_ctx, dns->task->lp_ctx,
841                               system_session(dns->task->lp_ctx), 0);
842         if (!dns->samdb) {
843                 task_server_terminate(task, "dns: samdb_connect failed", true);
844                 return;
845         }
846
847         cli_credentials_set_conf(dns->server_credentials, task->lp_ctx);
848
849         hostname_lower = strlower_talloc(dns, lpcfg_netbios_name(task->lp_ctx));
850         dns_spn = talloc_asprintf(dns, "DNS/%s.%s",
851                                   hostname_lower,
852                                   lpcfg_dnsdomain(task->lp_ctx));
853         TALLOC_FREE(hostname_lower);
854
855         ret = dsdb_search_one(dns->samdb, dns, &dns_acc,
856                               ldb_get_default_basedn(dns->samdb), LDB_SCOPE_SUBTREE,
857                               attrs_none, 0, "(servicePrincipalName=%s)",
858                               dns_spn);
859         if (ret == LDB_SUCCESS) {
860                 TALLOC_FREE(dns_acc);
861                 if (!dns_spn) {
862                         task_server_terminate(task, "dns: talloc_asprintf failed", true);
863                         return;
864                 }
865                 status = cli_credentials_set_stored_principal(dns->server_credentials, task->lp_ctx, dns_spn);
866                 if (!NT_STATUS_IS_OK(status)) {
867                         task_server_terminate(task,
868                                               talloc_asprintf(task, "Failed to obtain server credentials for DNS, "
869                                                               "despite finding it in the samdb! %s\n",
870                                                               nt_errstr(status)),
871                                               true);
872                         return;
873                 }
874         } else {
875                 TALLOC_FREE(dns_spn);
876                 status = cli_credentials_set_machine_account(dns->server_credentials, task->lp_ctx);
877                 if (!NT_STATUS_IS_OK(status)) {
878                         task_server_terminate(task,
879                                               talloc_asprintf(task, "Failed to obtain server credentials, perhaps a standalone server?: %s\n",
880                                                               nt_errstr(status)),
881                                               true);
882                         return;
883                 }
884         }
885
886         dns->tkeys = tkey_store_init(dns, TKEY_BUFFER_SIZE);
887         if (!dns->tkeys) {
888                 task_server_terminate(task, "Failed to allocate tkey storage\n", true);
889                 return;
890         }
891
892         status = dns_server_reload_zones(dns);
893         if (!NT_STATUS_IS_OK(status)) {
894                 task_server_terminate(task, "dns: failed to load DNS zones", true);
895                 return;
896         }
897
898         status = dns_startup_interfaces(dns, ifaces);
899         if (!NT_STATUS_IS_OK(status)) {
900                 task_server_terminate(task, "dns failed to setup interfaces", true);
901                 return;
902         }
903
904         /* Setup the IRPC interface and register handlers */
905         status = irpc_add_name(task->msg_ctx, "dnssrv");
906         if (!NT_STATUS_IS_OK(status)) {
907                 task_server_terminate(task, "dns: failed to register IRPC name", true);
908                 return;
909         }
910
911         status = IRPC_REGISTER(task->msg_ctx, irpc, DNSSRV_RELOAD_DNS_ZONES,
912                                dns_reload_zones, dns);
913         if (!NT_STATUS_IS_OK(status)) {
914                 task_server_terminate(task, "dns: failed to setup reload handler", true);
915                 return;
916         }
917 }
918
919 NTSTATUS server_service_dns_init(void)
920 {
921         return register_server_service("dns", dns_task_init);
922 }