s4:dns_server: make use of tstream_bsd_fail_readv_first_error(true)
[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 "samba/service_task.h"
24 #include "samba/service.h"
25 #include "samba/service_stream.h"
26 #include "samba/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(TALLOC_CTX *);
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         WERROR 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                                            const struct tsocket_address *remote_address,
121                                            const struct tsocket_address *local_address,
122                                            DATA_BLOB *in)
123 {
124         struct tevent_req *req, *subreq;
125         struct dns_process_state *state;
126         enum ndr_err_code ndr_err;
127         WERROR ret;
128         const char **forwarder = lpcfg_dns_forwarder(dns->task->lp_ctx);
129         req = tevent_req_create(mem_ctx, &state, struct dns_process_state);
130         if (req == NULL) {
131                 return NULL;
132         }
133         state->state.mem_ctx = state;
134         state->in = in;
135
136         state->dns = dns;
137
138         if (in->length < 12) {
139                 tevent_req_werror(req, WERR_INVALID_PARAMETER);
140                 return tevent_req_post(req, ev);
141         }
142         dump_data_dbgc(DBGC_DNS, 8, in->data, in->length);
143
144         ndr_err = ndr_pull_struct_blob(
145                 in, state, &state->in_packet,
146                 (ndr_pull_flags_fn_t)ndr_pull_dns_name_packet);
147
148         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
149                 DBG_NOTICE("ndr_pull_dns_name_packet() failed with %s\n",
150                            ndr_map_error2string(ndr_err));
151                 state->dns_err = DNS_ERR(FORMAT_ERROR);
152                 tevent_req_done(req);
153                 return tevent_req_post(req, ev);
154         }
155         if (DEBUGLVLC(DBGC_DNS, 8)) {
156                 NDR_PRINT_DEBUGC(DBGC_DNS, dns_name_packet, &state->in_packet);
157         }
158
159         if (state->in_packet.operation & DNS_FLAG_REPLY) {
160                 DBG_INFO("Won't reply to replies.\n");
161                 tevent_req_werror(req, WERR_INVALID_PARAMETER);
162                 return tevent_req_post(req, ev);
163         }
164
165         state->state.flags = state->in_packet.operation;
166         state->state.flags |= DNS_FLAG_REPLY;
167
168         state->state.local_address = local_address;
169         state->state.remote_address = remote_address;
170
171         if (forwarder && *forwarder && **forwarder) {
172                 state->state.flags |= DNS_FLAG_RECURSION_AVAIL;
173         }
174
175         state->out_packet = state->in_packet;
176
177         ret = dns_verify_tsig(dns, state, &state->state,
178                               &state->out_packet, in);
179         if (!W_ERROR_IS_OK(ret)) {
180                 DBG_INFO("dns_verify_tsig() failed with %s\n",
181                          win_errstr(ret));
182                 state->dns_err = ret;
183                 tevent_req_done(req);
184                 return tevent_req_post(req, ev);
185         }
186
187         switch (state->in_packet.operation & DNS_OPCODE) {
188         case DNS_OPCODE_QUERY:
189                 subreq = dns_server_process_query_send(
190                         state, ev, dns,
191                         &state->state, &state->in_packet);
192                 if (tevent_req_nomem(subreq, req)) {
193                         return tevent_req_post(req, ev);
194                 }
195                 tevent_req_set_callback(subreq, dns_process_done, req);
196                 return req;
197         case DNS_OPCODE_UPDATE:
198                 ret = dns_server_process_update(
199                         dns, &state->state, state, &state->in_packet,
200                         &state->out_packet.answers, &state->out_packet.ancount,
201                         &state->out_packet.nsrecs,  &state->out_packet.nscount,
202                         &state->out_packet.additional,
203                         &state->out_packet.arcount);
204                 DBG_DEBUG("dns_server_process_update(): %s\n",
205                           win_errstr(ret));
206                 break;
207         default:
208                 ret = WERR_DNS_ERROR_RCODE_NOT_IMPLEMENTED;
209                 DBG_NOTICE("OPCODE[0x%x]: %s\n",
210                            (state->in_packet.operation & DNS_OPCODE),
211                            win_errstr(ret));
212         }
213         state->dns_err = ret;
214         tevent_req_done(req);
215         return tevent_req_post(req, ev);
216 }
217
218 static void dns_process_done(struct tevent_req *subreq)
219 {
220         struct tevent_req *req = tevent_req_callback_data(
221                 subreq, struct tevent_req);
222         struct dns_process_state *state = tevent_req_data(
223                 req, struct dns_process_state);
224         WERROR ret;
225
226         ret = dns_server_process_query_recv(
227                 subreq, state,
228                 &state->out_packet.answers, &state->out_packet.ancount,
229                 &state->out_packet.nsrecs,  &state->out_packet.nscount,
230                 &state->out_packet.additional, &state->out_packet.arcount);
231         TALLOC_FREE(subreq);
232
233         DBG_DEBUG("dns_server_process_query_recv(): %s\n",
234                   win_errstr(ret));
235         state->dns_err = ret;
236         tevent_req_done(req);
237 }
238
239 static WERROR dns_process_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
240                                DATA_BLOB *out)
241 {
242         struct dns_process_state *state = tevent_req_data(
243                 req, struct dns_process_state);
244         enum ndr_err_code ndr_err;
245         uint16_t dns_err;
246         WERROR ret;
247
248         if (tevent_req_is_werror(req, &ret)) {
249                 DBG_NOTICE("ERROR: %s from %s\n", win_errstr(ret),
250                            tevent_req_print(state, req));
251                 return ret;
252         }
253         dns_err = werr_to_dns_err(state->dns_err);
254         if ((dns_err != DNS_RCODE_OK) &&
255             (dns_err != DNS_RCODE_NXDOMAIN) &&
256             (dns_err != DNS_RCODE_NOTAUTH))
257         {
258                 DBG_INFO("FAILURE: %s from %s\n",
259                          win_errstr(state->dns_err),
260                          tevent_req_print(state, req));
261                 goto drop;
262         }
263         if (dns_err != DNS_RCODE_OK) {
264                 DBG_DEBUG("INFO: %s from %s\n",
265                           win_errstr(state->dns_err),
266                           tevent_req_print(state, req));
267                 state->out_packet.operation |= dns_err;
268         } else {
269                 DBG_DEBUG("OK: %s\n",
270                           tevent_req_print(state, req));
271         }
272         state->out_packet.operation |= state->state.flags;
273
274         if (state->state.sign) {
275                 ret = dns_sign_tsig(state->dns, mem_ctx, &state->state,
276                                     &state->out_packet, 0);
277                 if (!W_ERROR_IS_OK(ret)) {
278                         DBG_WARNING("dns_sign_tsig() failed %s\n",
279                                     win_errstr(ret));
280                         dns_err = DNS_RCODE_SERVFAIL;
281                         goto drop;
282                 }
283         }
284
285         if (DEBUGLVLC(DBGC_DNS, 8)) {
286                 NDR_PRINT_DEBUGC(DBGC_DNS, dns_name_packet, &state->out_packet);
287         }
288
289         ndr_err = ndr_push_struct_blob(
290                 out, mem_ctx, &state->out_packet,
291                 (ndr_push_flags_fn_t)ndr_push_dns_name_packet);
292         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
293                 DBG_WARNING("Failed to push packet: %s!\n",
294                             ndr_errstr(ndr_err));
295                 dns_err = DNS_RCODE_SERVFAIL;
296                 goto drop;
297         }
298         return WERR_OK;
299
300 drop:
301         *out = data_blob_talloc(mem_ctx, state->in->data, state->in->length);
302         if (out->data == NULL) {
303                 return WERR_NOT_ENOUGH_MEMORY;
304         }
305         out->data[2] |= 0x80; /* Toggle DNS_FLAG_REPLY */
306         out->data[3] |= dns_err;
307         return WERR_OK;
308 }
309
310 struct dns_tcp_call {
311         struct dns_tcp_connection *dns_conn;
312         DATA_BLOB in;
313         DATA_BLOB out;
314         uint8_t out_hdr[4];
315         struct iovec out_iov[2];
316 };
317
318 static void dns_tcp_call_process_done(struct tevent_req *subreq);
319 static void dns_tcp_call_writev_done(struct tevent_req *subreq);
320
321 static void dns_tcp_call_loop(struct tevent_req *subreq)
322 {
323         struct dns_tcp_connection *dns_conn = tevent_req_callback_data(subreq,
324                                       struct dns_tcp_connection);
325         struct dns_server *dns = dns_conn->dns_socket->dns;
326         struct dns_tcp_call *call;
327         NTSTATUS status;
328
329         call = talloc(dns_conn, struct dns_tcp_call);
330         if (call == NULL) {
331                 dns_tcp_terminate_connection(dns_conn, "dns_tcp_call_loop: "
332                                 "no memory for dns_tcp_call");
333                 return;
334         }
335         call->dns_conn = dns_conn;
336
337         status = tstream_read_pdu_blob_recv(subreq,
338                                             call,
339                                             &call->in);
340         TALLOC_FREE(subreq);
341         if (!NT_STATUS_IS_OK(status)) {
342                 const char *reason;
343
344                 reason = talloc_asprintf(call, "dns_tcp_call_loop: "
345                                          "tstream_read_pdu_blob_recv() - %s",
346                                          nt_errstr(status));
347                 if (!reason) {
348                         reason = nt_errstr(status);
349                 }
350
351                 dns_tcp_terminate_connection(dns_conn, reason);
352                 return;
353         }
354
355         DEBUG(10,("Received DNS TCP packet of length %lu from %s\n",
356                  (long) call->in.length,
357                  tsocket_address_string(dns_conn->conn->remote_address, call)));
358
359         /* skip length header */
360         call->in.data += 2;
361         call->in.length -= 2;
362
363         subreq = dns_process_send(call, dns->task->event_ctx, dns,
364                                   dns_conn->conn->remote_address,
365                                   dns_conn->conn->local_address,
366                                   &call->in);
367         if (subreq == NULL) {
368                 dns_tcp_terminate_connection(
369                         dns_conn, "dns_tcp_call_loop: dns_process_send "
370                         "failed\n");
371                 return;
372         }
373         tevent_req_set_callback(subreq, dns_tcp_call_process_done, call);
374
375         /*
376          * The dns tcp pdu's has the length as 2 byte (initial_read_size),
377          * packet_full_request_u16 provides the pdu length then.
378          */
379         subreq = tstream_read_pdu_blob_send(dns_conn,
380                                             dns_conn->conn->event.ctx,
381                                             dns_conn->tstream,
382                                             2, /* initial_read_size */
383                                             packet_full_request_u16,
384                                             dns_conn);
385         if (subreq == NULL) {
386                 dns_tcp_terminate_connection(dns_conn, "dns_tcp_call_loop: "
387                                 "no memory for tstream_read_pdu_blob_send");
388                 return;
389         }
390         tevent_req_set_callback(subreq, dns_tcp_call_loop, dns_conn);
391 }
392
393 static void dns_tcp_call_process_done(struct tevent_req *subreq)
394 {
395         struct dns_tcp_call *call = tevent_req_callback_data(subreq,
396                         struct dns_tcp_call);
397         struct dns_tcp_connection *dns_conn = call->dns_conn;
398         WERROR err;
399
400         err = dns_process_recv(subreq, call, &call->out);
401         TALLOC_FREE(subreq);
402         if (!W_ERROR_IS_OK(err)) {
403                 DEBUG(1, ("dns_process returned %s\n", win_errstr(err)));
404                 dns_tcp_terminate_connection(dns_conn,
405                                 "dns_tcp_call_loop: process function failed");
406                 return;
407         }
408
409         /* First add the length of the out buffer */
410         RSSVAL(call->out_hdr, 0, call->out.length);
411         call->out_iov[0].iov_base = (char *) call->out_hdr;
412         call->out_iov[0].iov_len = 2;
413
414         call->out_iov[1].iov_base = (char *) call->out.data;
415         call->out_iov[1].iov_len = call->out.length;
416
417         subreq = tstream_writev_queue_send(call,
418                                            dns_conn->conn->event.ctx,
419                                            dns_conn->tstream,
420                                            dns_conn->send_queue,
421                                            call->out_iov, 2);
422         if (subreq == NULL) {
423                 dns_tcp_terminate_connection(dns_conn, "dns_tcp_call_loop: "
424                                 "no memory for tstream_writev_queue_send");
425                 return;
426         }
427         tevent_req_set_callback(subreq, dns_tcp_call_writev_done, call);
428 }
429
430 static void dns_tcp_call_writev_done(struct tevent_req *subreq)
431 {
432         struct dns_tcp_call *call = tevent_req_callback_data(subreq,
433                         struct dns_tcp_call);
434         int sys_errno;
435         int rc;
436
437         rc = tstream_writev_queue_recv(subreq, &sys_errno);
438         TALLOC_FREE(subreq);
439         if (rc == -1) {
440                 const char *reason;
441
442                 reason = talloc_asprintf(call, "dns_tcp_call_writev_done: "
443                                          "tstream_writev_queue_recv() - %d:%s",
444                                          sys_errno, strerror(sys_errno));
445                 if (!reason) {
446                         reason = "dns_tcp_call_writev_done: tstream_writev_queue_recv() failed";
447                 }
448
449                 dns_tcp_terminate_connection(call->dns_conn, reason);
450                 return;
451         }
452
453         /* We don't care about errors */
454
455         talloc_free(call);
456 }
457
458 /*
459   called when we get a new connection
460 */
461 static void dns_tcp_accept(struct stream_connection *conn)
462 {
463         struct dns_socket *dns_socket;
464         struct dns_tcp_connection *dns_conn;
465         struct tevent_req *subreq;
466         int rc;
467
468         dns_conn = talloc_zero(conn, struct dns_tcp_connection);
469         if (dns_conn == NULL) {
470                 stream_terminate_connection(conn,
471                                 "dns_tcp_accept: out of memory");
472                 return;
473         }
474
475         dns_conn->send_queue = tevent_queue_create(conn, "dns_tcp_accept");
476         if (dns_conn->send_queue == NULL) {
477                 stream_terminate_connection(conn,
478                                 "dns_tcp_accept: out of memory");
479                 return;
480         }
481
482         dns_socket = talloc_get_type(conn->private_data, struct dns_socket);
483
484         TALLOC_FREE(conn->event.fde);
485
486         rc = tstream_bsd_existing_socket(dns_conn,
487                         socket_get_fd(conn->socket),
488                         &dns_conn->tstream);
489         if (rc < 0) {
490                 stream_terminate_connection(conn,
491                                 "dns_tcp_accept: out of memory");
492                 return;
493         }
494         /* as server we want to fail early */
495         tstream_bsd_fail_readv_first_error(dns_conn->tstream, true);
496
497         dns_conn->conn = conn;
498         dns_conn->dns_socket = dns_socket;
499         conn->private_data = dns_conn;
500
501         /*
502          * The dns tcp pdu's has the length as 2 byte (initial_read_size),
503          * packet_full_request_u16 provides the pdu length then.
504          */
505         subreq = tstream_read_pdu_blob_send(dns_conn,
506                                             dns_conn->conn->event.ctx,
507                                             dns_conn->tstream,
508                                             2, /* initial_read_size */
509                                             packet_full_request_u16,
510                                             dns_conn);
511         if (subreq == NULL) {
512                 dns_tcp_terminate_connection(dns_conn, "dns_tcp_accept: "
513                                 "no memory for tstream_read_pdu_blob_send");
514                 return;
515         }
516         tevent_req_set_callback(subreq, dns_tcp_call_loop, dns_conn);
517 }
518
519 static const struct stream_server_ops dns_tcp_stream_ops = {
520         .name                   = "dns_tcp",
521         .accept_connection      = dns_tcp_accept,
522         .recv_handler           = dns_tcp_recv,
523         .send_handler           = dns_tcp_send
524 };
525
526 struct dns_udp_call {
527         struct dns_udp_socket *sock;
528         struct tsocket_address *src;
529         DATA_BLOB in;
530         DATA_BLOB out;
531 };
532
533 static void dns_udp_call_process_done(struct tevent_req *subreq);
534 static void dns_udp_call_sendto_done(struct tevent_req *subreq);
535
536 static void dns_udp_call_loop(struct tevent_req *subreq)
537 {
538         struct dns_udp_socket *sock = tevent_req_callback_data(subreq,
539                                       struct dns_udp_socket);
540         struct dns_server *dns = sock->dns_socket->dns;
541         struct dns_udp_call *call;
542         uint8_t *buf;
543         ssize_t len;
544         int sys_errno;
545
546         call = talloc(sock, struct dns_udp_call);
547         if (call == NULL) {
548                 talloc_free(call);
549                 goto done;
550         }
551         call->sock = sock;
552
553         len = tdgram_recvfrom_recv(subreq, &sys_errno,
554                                    call, &buf, &call->src);
555         TALLOC_FREE(subreq);
556         if (len == -1) {
557                 talloc_free(call);
558                 goto done;
559         }
560
561         call->in.data = buf;
562         call->in.length = len;
563
564         DEBUG(10,("Received DNS UDP packet of length %lu from %s\n",
565                  (long)call->in.length,
566                  tsocket_address_string(call->src, call)));
567
568         subreq = dns_process_send(call, dns->task->event_ctx, dns,
569                                   call->src,
570                                   sock->dns_socket->local_address,
571                                   &call->in);
572         if (subreq == NULL) {
573                 TALLOC_FREE(call);
574                 goto done;
575         }
576         tevent_req_set_callback(subreq, dns_udp_call_process_done, call);
577
578 done:
579         subreq = tdgram_recvfrom_send(sock,
580                                       sock->dns_socket->dns->task->event_ctx,
581                                       sock->dgram);
582         if (subreq == NULL) {
583                 task_server_terminate(sock->dns_socket->dns->task,
584                                       "no memory for tdgram_recvfrom_send",
585                                       true);
586                 return;
587         }
588         tevent_req_set_callback(subreq, dns_udp_call_loop, sock);
589 }
590
591 static void dns_udp_call_process_done(struct tevent_req *subreq)
592 {
593         struct dns_udp_call *call = tevent_req_callback_data(
594                 subreq, struct dns_udp_call);
595         struct dns_udp_socket *sock = call->sock;
596         struct dns_server *dns = sock->dns_socket->dns;
597         WERROR err;
598
599         err = dns_process_recv(subreq, call, &call->out);
600         TALLOC_FREE(subreq);
601         if (!W_ERROR_IS_OK(err)) {
602                 DEBUG(1, ("dns_process returned %s\n", win_errstr(err)));
603                 TALLOC_FREE(call);
604                 return;
605         }
606
607         subreq = tdgram_sendto_queue_send(call,
608                                           dns->task->event_ctx,
609                                           sock->dgram,
610                                           sock->send_queue,
611                                           call->out.data,
612                                           call->out.length,
613                                           call->src);
614         if (subreq == NULL) {
615                 talloc_free(call);
616                 return;
617         }
618         tevent_req_set_callback(subreq, dns_udp_call_sendto_done, call);
619
620 }
621 static void dns_udp_call_sendto_done(struct tevent_req *subreq)
622 {
623         struct dns_udp_call *call = tevent_req_callback_data(subreq,
624                                        struct dns_udp_call);
625         int sys_errno;
626
627         tdgram_sendto_queue_recv(subreq, &sys_errno);
628
629         /* We don't care about errors */
630
631         talloc_free(call);
632 }
633
634 /*
635   start listening on the given address
636 */
637 static NTSTATUS dns_add_socket(struct dns_server *dns,
638                                const struct model_ops *model_ops,
639                                const char *name,
640                                const char *address,
641                                uint16_t port)
642 {
643         struct dns_socket *dns_socket;
644         struct dns_udp_socket *dns_udp_socket;
645         struct tevent_req *udpsubreq;
646         NTSTATUS status;
647         int ret;
648
649         dns_socket = talloc(dns, struct dns_socket);
650         NT_STATUS_HAVE_NO_MEMORY(dns_socket);
651
652         dns_socket->dns = dns;
653
654         ret = tsocket_address_inet_from_strings(dns_socket, "ip",
655                                                 address, port,
656                                                 &dns_socket->local_address);
657         if (ret != 0) {
658                 status = map_nt_error_from_unix_common(errno);
659                 return status;
660         }
661
662         status = stream_setup_socket(dns->task,
663                                      dns->task->event_ctx,
664                                      dns->task->lp_ctx,
665                                      model_ops,
666                                      &dns_tcp_stream_ops,
667                                      "ip", address, &port,
668                                      lpcfg_socket_options(dns->task->lp_ctx),
669                                      dns_socket,
670                                      dns->task->process_context);
671         if (!NT_STATUS_IS_OK(status)) {
672                 DEBUG(0,("Failed to bind to %s:%u TCP - %s\n",
673                          address, port, nt_errstr(status)));
674                 talloc_free(dns_socket);
675                 return status;
676         }
677
678         dns_udp_socket = talloc(dns_socket, struct dns_udp_socket);
679         NT_STATUS_HAVE_NO_MEMORY(dns_udp_socket);
680
681         dns_udp_socket->dns_socket = dns_socket;
682
683         ret = tdgram_inet_udp_socket(dns_socket->local_address,
684                                      NULL,
685                                      dns_udp_socket,
686                                      &dns_udp_socket->dgram);
687         if (ret != 0) {
688                 status = map_nt_error_from_unix_common(errno);
689                 DEBUG(0,("Failed to bind to %s:%u UDP - %s\n",
690                          address, port, nt_errstr(status)));
691                 return status;
692         }
693
694         dns_udp_socket->send_queue = tevent_queue_create(dns_udp_socket,
695                                                          "dns_udp_send_queue");
696         NT_STATUS_HAVE_NO_MEMORY(dns_udp_socket->send_queue);
697
698         udpsubreq = tdgram_recvfrom_send(dns_udp_socket,
699                                          dns->task->event_ctx,
700                                          dns_udp_socket->dgram);
701         NT_STATUS_HAVE_NO_MEMORY(udpsubreq);
702         tevent_req_set_callback(udpsubreq, dns_udp_call_loop, dns_udp_socket);
703
704         return NT_STATUS_OK;
705 }
706
707 /*
708   setup our listening sockets on the configured network interfaces
709 */
710 static NTSTATUS dns_startup_interfaces(struct dns_server *dns,
711                                        struct interface *ifaces,
712                                        const struct model_ops *model_ops)
713 {
714         size_t num_interfaces;
715         TALLOC_CTX *tmp_ctx = talloc_new(dns);
716         NTSTATUS status;
717         int i;
718
719         if (ifaces != NULL) {
720                 num_interfaces = iface_list_count(ifaces);
721
722                 for (i=0; i<num_interfaces; i++) {
723                         const char *address = talloc_strdup(tmp_ctx,
724                                                             iface_list_n_ip(ifaces, i));
725
726                         status = dns_add_socket(dns, model_ops, "dns", address,
727                                                 lpcfg_dns_port(dns->task->lp_ctx));
728                         NT_STATUS_NOT_OK_RETURN(status);
729                 }
730         } else {
731                 size_t num_binds = 0;
732                 char **wcard;
733                 wcard = iface_list_wildcard(tmp_ctx);
734                 if (wcard == NULL) {
735                         DEBUG(0, ("No wildcard address available\n"));
736                         return NT_STATUS_INTERNAL_ERROR;
737                 }
738                 for (i = 0; wcard[i] != NULL; i++) {
739                         status = dns_add_socket(dns, model_ops, "dns", wcard[i],
740                                                 lpcfg_dns_port(dns->task->lp_ctx));
741                         if (NT_STATUS_IS_OK(status)) {
742                                 num_binds++;
743                         }
744                 }
745                 if (num_binds == 0) {
746                         talloc_free(tmp_ctx);
747                         return NT_STATUS_INVALID_PARAMETER_MIX;
748                 }
749         }
750
751         talloc_free(tmp_ctx);
752
753         return NT_STATUS_OK;
754 }
755
756 static struct dns_server_tkey_store *tkey_store_init(TALLOC_CTX *mem_ctx,
757                                                      uint16_t size)
758 {
759         struct dns_server_tkey_store *buffer = talloc_zero(mem_ctx,
760                                                 struct dns_server_tkey_store);
761
762         if (buffer == NULL) {
763                 return NULL;
764         }
765
766         buffer->size = size;
767         buffer->next_idx = 0;
768
769         buffer->tkeys = talloc_zero_array(buffer, struct dns_server_tkey *, size);
770         if (buffer->tkeys == NULL) {
771                 TALLOC_FREE(buffer);
772         }
773
774         return buffer;
775 }
776
777 static NTSTATUS dns_server_reload_zones(struct dns_server *dns)
778 {
779         NTSTATUS status;
780         struct dns_server_zone *new_list = NULL;
781         struct dns_server_zone *old_list = dns->zones;
782         struct dns_server_zone *old_zone;
783         status = dns_common_zones(dns->samdb, dns, NULL, &new_list);
784         if (!NT_STATUS_IS_OK(status)) {
785                 return status;
786         }
787         dns->zones = new_list;
788         while ((old_zone = DLIST_TAIL(old_list)) != NULL) {
789                 DLIST_REMOVE(old_list, old_zone);
790                 talloc_free(old_zone);
791         }
792
793         return NT_STATUS_OK;
794 }
795
796 /**
797  * Called when the internal DNS server should reload the zones from DB, for
798  * example, when zones are added or deleted through RPC or replicated by
799  * inbound DRS.
800  */
801 static NTSTATUS dns_reload_zones(struct irpc_message *msg,
802                                  struct dnssrv_reload_dns_zones *r)
803 {
804         struct dns_server *dns;
805
806         dns = talloc_get_type(msg->private_data, struct dns_server);
807         if (dns == NULL) {
808                 r->out.result = NT_STATUS_INTERNAL_ERROR;
809                 return NT_STATUS_INTERNAL_ERROR;
810         }
811
812         r->out.result = dns_server_reload_zones(dns);
813
814         return NT_STATUS_OK;
815 }
816
817 static NTSTATUS dns_task_init(struct task_server *task)
818 {
819         struct dns_server *dns;
820         NTSTATUS status;
821         struct interface *ifaces = NULL;
822         int ret;
823         static const char * const attrs_none[] = { NULL};
824         struct ldb_message *dns_acc;
825         char *hostname_lower;
826         char *dns_spn;
827         bool ok;
828
829         switch (lpcfg_server_role(task->lp_ctx)) {
830         case ROLE_STANDALONE:
831                 task_server_terminate(task, "dns: no DNS required in standalone configuration", false);
832                 return NT_STATUS_INVALID_DOMAIN_ROLE;
833         case ROLE_DOMAIN_MEMBER:
834                 task_server_terminate(task, "dns: no DNS required in member server configuration", false);
835                 return NT_STATUS_INVALID_DOMAIN_ROLE;
836         case ROLE_ACTIVE_DIRECTORY_DC:
837                 /* Yes, we want a DNS */
838                 break;
839         }
840
841         if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) {
842                 load_interface_list(task, task->lp_ctx, &ifaces);
843
844                 if (iface_list_count(ifaces) == 0) {
845                         task_server_terminate(task, "dns: no network interfaces configured", false);
846                         return NT_STATUS_UNSUCCESSFUL;
847                 }
848         }
849
850         task_server_set_title(task, "task[dns]");
851
852         dns = talloc_zero(task, struct dns_server);
853         if (dns == NULL) {
854                 task_server_terminate(task, "dns: out of memory", true);
855                 return NT_STATUS_NO_MEMORY;
856         }
857
858         dns->task = task;
859
860         dns->server_credentials = cli_credentials_init(dns);
861         if (!dns->server_credentials) {
862                 task_server_terminate(task, "Failed to init server credentials\n", true);
863                 return NT_STATUS_UNSUCCESSFUL;
864         }
865
866         dns->samdb = samdb_connect(dns,
867                                    dns->task->event_ctx,
868                                    dns->task->lp_ctx,
869                                    system_session(dns->task->lp_ctx),
870                                    NULL,
871                                    0);
872         if (!dns->samdb) {
873                 task_server_terminate(task, "dns: samdb_connect failed", true);
874                 return NT_STATUS_UNSUCCESSFUL;
875         }
876
877         ok = cli_credentials_set_conf(dns->server_credentials, task->lp_ctx);
878         if (!ok) {
879                 task_server_terminate(task,
880                                       "dns: failed to load smb.conf",
881                                       true);
882                 return NT_STATUS_UNSUCCESSFUL;
883         }
884
885         hostname_lower = strlower_talloc(dns, lpcfg_netbios_name(task->lp_ctx));
886         dns_spn = talloc_asprintf(dns, "DNS/%s.%s",
887                                   hostname_lower,
888                                   lpcfg_dnsdomain(task->lp_ctx));
889         TALLOC_FREE(hostname_lower);
890
891         ret = dsdb_search_one(dns->samdb, dns, &dns_acc,
892                               ldb_get_default_basedn(dns->samdb), LDB_SCOPE_SUBTREE,
893                               attrs_none, 0, "(servicePrincipalName=%s)",
894                               dns_spn);
895         if (ret == LDB_SUCCESS) {
896                 TALLOC_FREE(dns_acc);
897                 if (!dns_spn) {
898                         task_server_terminate(task, "dns: talloc_asprintf failed", true);
899                         return NT_STATUS_UNSUCCESSFUL;
900                 }
901                 status = cli_credentials_set_stored_principal(dns->server_credentials, task->lp_ctx, dns_spn);
902                 if (!NT_STATUS_IS_OK(status)) {
903                         task_server_terminate(task,
904                                               talloc_asprintf(task, "Failed to obtain server credentials for DNS, "
905                                                               "despite finding it in the samdb! %s\n",
906                                                               nt_errstr(status)),
907                                               true);
908                         return status;
909                 }
910         } else {
911                 TALLOC_FREE(dns_spn);
912                 status = cli_credentials_set_machine_account(dns->server_credentials, task->lp_ctx);
913                 if (!NT_STATUS_IS_OK(status)) {
914                         task_server_terminate(task,
915                                               talloc_asprintf(task, "Failed to obtain server credentials, perhaps a standalone server?: %s\n",
916                                                               nt_errstr(status)),
917                                               true);
918                         return status;
919                 }
920         }
921
922         dns->tkeys = tkey_store_init(dns, TKEY_BUFFER_SIZE);
923         if (!dns->tkeys) {
924                 task_server_terminate(task, "Failed to allocate tkey storage\n", true);
925                 return NT_STATUS_NO_MEMORY;
926         }
927
928         status = dns_server_reload_zones(dns);
929         if (!NT_STATUS_IS_OK(status)) {
930                 task_server_terminate(task, "dns: failed to load DNS zones", true);
931                 return status;
932         }
933
934         status = dns_startup_interfaces(dns, ifaces, task->model_ops);
935         if (!NT_STATUS_IS_OK(status)) {
936                 task_server_terminate(task, "dns failed to setup interfaces", true);
937                 return status;
938         }
939
940         /* Setup the IRPC interface and register handlers */
941         status = irpc_add_name(task->msg_ctx, "dnssrv");
942         if (!NT_STATUS_IS_OK(status)) {
943                 task_server_terminate(task, "dns: failed to register IRPC name", true);
944                 return status;
945         }
946
947         status = IRPC_REGISTER(task->msg_ctx, irpc, DNSSRV_RELOAD_DNS_ZONES,
948                                dns_reload_zones, dns);
949         if (!NT_STATUS_IS_OK(status)) {
950                 task_server_terminate(task, "dns: failed to setup reload handler", true);
951                 return status;
952         }
953         return NT_STATUS_OK;
954 }
955
956 NTSTATUS server_service_dns_init(TALLOC_CTX *ctx)
957 {
958         static const struct service_details details = {
959                 .inhibit_fork_on_accept = true,
960                 .inhibit_pre_fork = true,
961                 .task_init = dns_task_init,
962                 .post_fork = NULL
963         };
964         return register_server_service(ctx, "dns", &details);
965 }