docs: fix a typo in history file
[bbaumbach/samba-autobuild/.git] / source4 / dns_server / dns_query.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    DNS server handler for queries
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 "libcli/util/werror.h"
25 #include "librpc/ndr/libndr.h"
26 #include "librpc/gen_ndr/ndr_dns.h"
27 #include "librpc/gen_ndr/ndr_dnsp.h"
28 #include <ldb.h>
29 #include "param/param.h"
30 #include "dsdb/samdb/samdb.h"
31 #include "dsdb/common/util.h"
32 #include "dns_server/dns_server.h"
33 #include "libcli/dns/libdns.h"
34 #include "lib/util/dlinklist.h"
35 #include "lib/util/util_net.h"
36 #include "lib/util/tevent_werror.h"
37 #include "auth/auth.h"
38 #include "auth/credentials/credentials.h"
39 #include "auth/gensec/gensec.h"
40
41 #undef DBGC_CLASS
42 #define DBGC_CLASS DBGC_DNS
43 #define MAX_Q_RECURSION_DEPTH 20
44
45 struct forwarder_string {
46         const char *forwarder;
47         struct forwarder_string *prev, *next;
48 };
49
50 static WERROR add_response_rr(const char *name,
51                               const struct dnsp_DnssrvRpcRecord *rec,
52                               struct dns_res_rec **answers)
53 {
54         struct dns_res_rec *ans = *answers;
55         uint16_t ai = talloc_array_length(ans);
56         enum ndr_err_code ndr_err;
57
58         if (ai == UINT16_MAX) {
59                 return WERR_BUFFER_OVERFLOW;
60         }
61
62         /*
63          * "ans" is always non-NULL and thus its own talloc context
64          */
65         ans = talloc_realloc(ans, ans, struct dns_res_rec, ai+1);
66         if (ans == NULL) {
67                 return WERR_NOT_ENOUGH_MEMORY;
68         }
69
70         ZERO_STRUCT(ans[ai]);
71
72         switch (rec->wType) {
73         case DNS_QTYPE_CNAME:
74                 ans[ai].rdata.cname_record = talloc_strdup(ans, rec->data.cname);
75                 W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.cname_record);
76                 break;
77         case DNS_QTYPE_A:
78                 ans[ai].rdata.ipv4_record = talloc_strdup(ans, rec->data.ipv4);
79                 W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.ipv4_record);
80                 break;
81         case DNS_QTYPE_AAAA:
82                 ans[ai].rdata.ipv6_record = talloc_strdup(ans, rec->data.ipv6);
83                 W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.ipv6_record);
84                 break;
85         case DNS_TYPE_NS:
86                 ans[ai].rdata.ns_record = talloc_strdup(ans, rec->data.ns);
87                 W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.ns_record);
88                 break;
89         case DNS_QTYPE_SRV:
90                 ans[ai].rdata.srv_record.priority = rec->data.srv.wPriority;
91                 ans[ai].rdata.srv_record.weight   = rec->data.srv.wWeight;
92                 ans[ai].rdata.srv_record.port     = rec->data.srv.wPort;
93                 ans[ai].rdata.srv_record.target   = talloc_strdup(
94                         ans, rec->data.srv.nameTarget);
95                 W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.srv_record.target);
96                 break;
97         case DNS_QTYPE_SOA:
98                 ans[ai].rdata.soa_record.mname   = talloc_strdup(
99                         ans, rec->data.soa.mname);
100                 W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.soa_record.mname);
101                 ans[ai].rdata.soa_record.rname   = talloc_strdup(
102                         ans, rec->data.soa.rname);
103                 W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.soa_record.rname);
104                 ans[ai].rdata.soa_record.serial  = rec->data.soa.serial;
105                 ans[ai].rdata.soa_record.refresh = rec->data.soa.refresh;
106                 ans[ai].rdata.soa_record.retry   = rec->data.soa.retry;
107                 ans[ai].rdata.soa_record.expire  = rec->data.soa.expire;
108                 ans[ai].rdata.soa_record.minimum = rec->data.soa.minimum;
109                 break;
110         case DNS_QTYPE_PTR:
111                 ans[ai].rdata.ptr_record = talloc_strdup(ans, rec->data.ptr);
112                 W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.ptr_record);
113                 break;
114         case DNS_QTYPE_MX:
115                 ans[ai].rdata.mx_record.preference = rec->data.mx.wPriority;
116                 ans[ai].rdata.mx_record.exchange = talloc_strdup(
117                         ans, rec->data.mx.nameTarget);
118                 if (ans[ai].rdata.mx_record.exchange == NULL) {
119                         return WERR_NOT_ENOUGH_MEMORY;
120                 }
121                 break;
122         case DNS_QTYPE_TXT:
123                 ndr_err = ndr_dnsp_string_list_copy(ans,
124                                                     &rec->data.txt,
125                                                     &ans[ai].rdata.txt_record.txt);
126                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
127                         return WERR_NOT_ENOUGH_MEMORY;
128                 }
129                 break;
130         default:
131                 DEBUG(0, ("Got unhandled type %u query.\n", rec->wType));
132                 return DNS_ERR(NOT_IMPLEMENTED);
133         }
134
135         ans[ai].name = talloc_strdup(ans, name);
136         W_ERROR_HAVE_NO_MEMORY(ans[ai].name);
137         ans[ai].rr_type = (enum dns_qtype)rec->wType;
138         ans[ai].rr_class = DNS_QCLASS_IN;
139         ans[ai].ttl = rec->dwTtlSeconds;
140         ans[ai].length = UINT16_MAX;
141
142         *answers = ans;
143
144         return WERR_OK;
145 }
146
147 static WERROR add_dns_res_rec(struct dns_res_rec **pdst,
148                               const struct dns_res_rec *src)
149 {
150         struct dns_res_rec *dst = *pdst;
151         uint16_t di = talloc_array_length(dst);
152         enum ndr_err_code ndr_err;
153
154         if (di == UINT16_MAX) {
155                 return WERR_BUFFER_OVERFLOW;
156         }
157
158         dst = talloc_realloc(dst, dst, struct dns_res_rec, di+1);
159         if (dst == NULL) {
160                 return WERR_NOT_ENOUGH_MEMORY;
161         }
162
163         ZERO_STRUCT(dst[di]);
164
165         dst[di] = (struct dns_res_rec) {
166                 .name = talloc_strdup(dst, src->name),
167                 .rr_type = src->rr_type,
168                 .rr_class = src->rr_class,
169                 .ttl = src->ttl,
170                 .length = src->length
171         };
172
173         if (dst[di].name == NULL) {
174                 return WERR_NOT_ENOUGH_MEMORY;
175         }
176
177         switch (src->rr_type) {
178         case DNS_QTYPE_CNAME:
179                 dst[di].rdata.cname_record = talloc_strdup(
180                         dst, src->rdata.cname_record);
181                 if (dst[di].rdata.cname_record == NULL) {
182                         return WERR_NOT_ENOUGH_MEMORY;
183                 }
184                 break;
185         case DNS_QTYPE_A:
186                 dst[di].rdata.ipv4_record = talloc_strdup(
187                         dst, src->rdata.ipv4_record);
188                 if (dst[di].rdata.ipv4_record == NULL) {
189                         return WERR_NOT_ENOUGH_MEMORY;
190                 }
191                 break;
192         case DNS_QTYPE_AAAA:
193                 dst[di].rdata.ipv6_record = talloc_strdup(
194                         dst, src->rdata.ipv6_record);
195                 if (dst[di].rdata.ipv6_record == NULL) {
196                         return WERR_NOT_ENOUGH_MEMORY;
197                 }
198                 break;
199         case DNS_TYPE_NS:
200                 dst[di].rdata.ns_record = talloc_strdup(
201                         dst, src->rdata.ns_record);
202                 if (dst[di].rdata.ns_record == NULL) {
203                         return WERR_NOT_ENOUGH_MEMORY;
204                 }
205                 break;
206         case DNS_QTYPE_SRV:
207                 dst[di].rdata.srv_record = (struct dns_srv_record) {
208                         .priority = src->rdata.srv_record.priority,
209                         .weight   = src->rdata.srv_record.weight,
210                         .port     = src->rdata.srv_record.port,
211                         .target   = talloc_strdup(
212                                 dst, src->rdata.srv_record.target)
213                 };
214                 if (dst[di].rdata.srv_record.target == NULL) {
215                         return WERR_NOT_ENOUGH_MEMORY;
216                 }
217                 break;
218         case DNS_QTYPE_SOA:
219                 dst[di].rdata.soa_record = (struct dns_soa_record) {
220                         .mname   = talloc_strdup(
221                                 dst, src->rdata.soa_record.mname),
222                         .rname   = talloc_strdup(
223                                 dst, src->rdata.soa_record.rname),
224                         .serial  = src->rdata.soa_record.serial,
225                         .refresh = src->rdata.soa_record.refresh,
226                         .retry   = src->rdata.soa_record.retry,
227                         .expire  = src->rdata.soa_record.expire,
228                         .minimum = src->rdata.soa_record.minimum
229                 };
230
231                 if ((dst[di].rdata.soa_record.mname == NULL) ||
232                     (dst[di].rdata.soa_record.rname == NULL)) {
233                         return WERR_NOT_ENOUGH_MEMORY;
234                 }
235
236                 break;
237         case DNS_QTYPE_PTR:
238                 dst[di].rdata.ptr_record = talloc_strdup(
239                         dst, src->rdata.ptr_record);
240                 if (dst[di].rdata.ptr_record == NULL) {
241                         return WERR_NOT_ENOUGH_MEMORY;
242                 }
243                 break;
244         case DNS_QTYPE_MX:
245                 dst[di].rdata.mx_record = (struct dns_mx_record) {
246                         .preference = src->rdata.mx_record.preference,
247                         .exchange   = talloc_strdup(
248                                 src, src->rdata.mx_record.exchange)
249                 };
250
251                 if (dst[di].rdata.mx_record.exchange == NULL) {
252                         return WERR_NOT_ENOUGH_MEMORY;
253                 }
254                 break;
255         case DNS_QTYPE_TXT:
256                 ndr_err = ndr_dnsp_string_list_copy(dst,
257                                                     &src->rdata.txt_record.txt,
258                                                     &dst[di].rdata.txt_record.txt);
259                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
260                         return WERR_NOT_ENOUGH_MEMORY;
261                 }
262                 break;
263         default:
264                 DBG_WARNING("Got unhandled type %u query.\n", src->rr_type);
265                 return DNS_ERR(NOT_IMPLEMENTED);
266         }
267
268         *pdst = dst;
269
270         return WERR_OK;
271 }
272
273 struct ask_forwarder_state {
274         struct dns_name_packet *reply;
275 };
276
277 static void ask_forwarder_done(struct tevent_req *subreq);
278
279 static struct tevent_req *ask_forwarder_send(
280         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
281         const char *forwarder, struct dns_name_question *question)
282 {
283         struct tevent_req *req, *subreq;
284         struct ask_forwarder_state *state;
285
286         req = tevent_req_create(mem_ctx, &state, struct ask_forwarder_state);
287         if (req == NULL) {
288                 return NULL;
289         }
290
291         subreq = dns_cli_request_send(state, ev, forwarder,
292                                       question->name, question->question_class,
293                                       question->question_type);
294         if (tevent_req_nomem(subreq, req)) {
295                 return tevent_req_post(req, ev);
296         }
297         tevent_req_set_callback(subreq, ask_forwarder_done, req);
298         return req;
299 }
300
301 static void ask_forwarder_done(struct tevent_req *subreq)
302 {
303         struct tevent_req *req = tevent_req_callback_data(
304                 subreq, struct tevent_req);
305         struct ask_forwarder_state *state = tevent_req_data(
306                 req, struct ask_forwarder_state);
307         int ret;
308
309         ret = dns_cli_request_recv(subreq, state, &state->reply);
310         TALLOC_FREE(subreq);
311
312         if (ret != 0) {
313                 tevent_req_werror(req, unix_to_werror(ret));
314                 return;
315         }
316
317         tevent_req_done(req);
318 }
319
320 static WERROR ask_forwarder_recv(
321         struct tevent_req *req, TALLOC_CTX *mem_ctx,
322         struct dns_res_rec **answers, uint16_t *ancount,
323         struct dns_res_rec **nsrecs, uint16_t *nscount,
324         struct dns_res_rec **additional, uint16_t *arcount)
325 {
326         struct ask_forwarder_state *state = tevent_req_data(
327                 req, struct ask_forwarder_state);
328         struct dns_name_packet *in_packet = state->reply;
329         WERROR err;
330
331         if (tevent_req_is_werror(req, &err)) {
332                 return err;
333         }
334
335         *ancount = in_packet->ancount;
336         *answers = talloc_move(mem_ctx, &in_packet->answers);
337
338         *nscount = in_packet->nscount;
339         *nsrecs = talloc_move(mem_ctx, &in_packet->nsrecs);
340
341         *arcount = in_packet->arcount;
342         *additional = talloc_move(mem_ctx, &in_packet->additional);
343
344         return WERR_OK;
345 }
346
347 static WERROR add_zone_authority_record(struct dns_server *dns,
348                                         TALLOC_CTX *mem_ctx,
349                                         const struct dns_name_question *question,
350                                         struct dns_res_rec **nsrecs)
351 {
352         const char *zone = NULL;
353         struct dnsp_DnssrvRpcRecord *recs;
354         struct dns_res_rec *ns = *nsrecs;
355         uint16_t rec_count;
356         struct ldb_dn *dn = NULL;
357         unsigned int ri;
358         WERROR werror;
359
360         zone = dns_get_authoritative_zone(dns, question->name);
361         DEBUG(10, ("Creating zone authority record for '%s'\n", zone));
362
363         werror = dns_name2dn(dns, mem_ctx, zone, &dn);
364         if (!W_ERROR_IS_OK(werror)) {
365                 return werror;
366         }
367
368         werror = dns_lookup_records(dns, mem_ctx, dn, &recs, &rec_count);
369         if (!W_ERROR_IS_OK(werror)) {
370                 return werror;
371         }
372
373         for (ri = 0; ri < rec_count; ri++) {
374                 if (recs[ri].wType == DNS_TYPE_SOA) {
375                         werror = add_response_rr(zone, &recs[ri], &ns);
376                         if (!W_ERROR_IS_OK(werror)) {
377                                 return werror;
378                         }
379                 }
380         }
381
382         *nsrecs = ns;
383
384         return WERR_OK;
385 }
386
387 static struct tevent_req *handle_authoritative_send(
388         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
389         struct dns_server *dns, const char *forwarder,
390         struct dns_name_question *question,
391         struct dns_res_rec **answers, struct dns_res_rec **nsrecs,
392         size_t cname_depth);
393 static WERROR handle_authoritative_recv(struct tevent_req *req);
394
395 struct handle_dnsrpcrec_state {
396         struct dns_res_rec **answers;
397         struct dns_res_rec **nsrecs;
398 };
399
400 static void handle_dnsrpcrec_gotauth(struct tevent_req *subreq);
401 static void handle_dnsrpcrec_gotforwarded(struct tevent_req *subreq);
402
403 static struct tevent_req *handle_dnsrpcrec_send(
404         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
405         struct dns_server *dns, const char *forwarder,
406         const struct dns_name_question *question,
407         struct dnsp_DnssrvRpcRecord *rec,
408         struct dns_res_rec **answers, struct dns_res_rec **nsrecs,
409         size_t cname_depth)
410 {
411         struct tevent_req *req, *subreq;
412         struct handle_dnsrpcrec_state *state;
413         struct dns_name_question *new_q;
414         bool resolve_cname;
415         WERROR werr;
416
417         req = tevent_req_create(mem_ctx, &state,
418                                 struct handle_dnsrpcrec_state);
419         if (req == NULL) {
420                 return NULL;
421         }
422         state->answers = answers;
423         state->nsrecs = nsrecs;
424
425         if (cname_depth >= MAX_Q_RECURSION_DEPTH) {
426                 tevent_req_done(req);
427                 return tevent_req_post(req, ev);
428         }
429
430         resolve_cname = ((rec->wType == DNS_TYPE_CNAME) &&
431                          ((question->question_type == DNS_QTYPE_A) ||
432                           (question->question_type == DNS_QTYPE_AAAA)));
433
434         if (!resolve_cname) {
435                 if ((question->question_type != DNS_QTYPE_ALL) &&
436                     (rec->wType !=
437                      (enum dns_record_type) question->question_type)) {
438                         tevent_req_done(req);
439                         return tevent_req_post(req, ev);
440                 }
441
442                 werr = add_response_rr(question->name, rec, state->answers);
443                 if (tevent_req_werror(req, werr)) {
444                         return tevent_req_post(req, ev);
445                 }
446
447                 tevent_req_done(req);
448                 return tevent_req_post(req, ev);
449         }
450
451         werr = add_response_rr(question->name, rec, state->answers);
452         if (tevent_req_werror(req, werr)) {
453                 return tevent_req_post(req, ev);
454         }
455
456         new_q = talloc(state, struct dns_name_question);
457         if (tevent_req_nomem(new_q, req)) {
458                 return tevent_req_post(req, ev);
459         }
460
461         *new_q = (struct dns_name_question) {
462                 .question_type = question->question_type,
463                 .question_class = question->question_class,
464                 .name = rec->data.cname
465         };
466
467         if (dns_authoritative_for_zone(dns, new_q->name)) {
468                 subreq = handle_authoritative_send(
469                         state, ev, dns, forwarder, new_q,
470                         state->answers, state->nsrecs,
471                         cname_depth + 1);
472                 if (tevent_req_nomem(subreq, req)) {
473                         return tevent_req_post(req, ev);
474                 }
475                 tevent_req_set_callback(subreq, handle_dnsrpcrec_gotauth, req);
476                 return req;
477         }
478
479         subreq = ask_forwarder_send(state, ev, forwarder, new_q);
480         if (tevent_req_nomem(subreq, req)) {
481                 return tevent_req_post(req, ev);
482         }
483         tevent_req_set_callback(subreq, handle_dnsrpcrec_gotforwarded, req);
484
485         return req;
486 }
487
488 static void handle_dnsrpcrec_gotauth(struct tevent_req *subreq)
489 {
490         struct tevent_req *req = tevent_req_callback_data(
491                 subreq, struct tevent_req);
492         WERROR werr;
493
494         werr = handle_authoritative_recv(subreq);
495         TALLOC_FREE(subreq);
496         if (tevent_req_werror(req, werr)) {
497                 return;
498         }
499         tevent_req_done(req);
500 }
501
502 static void handle_dnsrpcrec_gotforwarded(struct tevent_req *subreq)
503 {
504         struct tevent_req *req = tevent_req_callback_data(
505                 subreq, struct tevent_req);
506         struct handle_dnsrpcrec_state *state = tevent_req_data(
507                 req, struct handle_dnsrpcrec_state);
508         struct dns_res_rec *answers, *nsrecs, *additional;
509         uint16_t ancount = 0;
510         uint16_t nscount = 0;
511         uint16_t arcount = 0;
512         uint16_t i;
513         WERROR werr;
514
515         werr = ask_forwarder_recv(subreq, state, &answers, &ancount,
516                                   &nsrecs, &nscount, &additional, &arcount);
517         if (tevent_req_werror(req, werr)) {
518                 return;
519         }
520
521         for (i=0; i<ancount; i++) {
522                 werr = add_dns_res_rec(state->answers, &answers[i]);
523                 if (tevent_req_werror(req, werr)) {
524                         return;
525                 }
526         }
527
528         for (i=0; i<nscount; i++) {
529                 werr = add_dns_res_rec(state->nsrecs, &nsrecs[i]);
530                 if (tevent_req_werror(req, werr)) {
531                         return;
532                 }
533         }
534
535         tevent_req_done(req);
536 }
537
538 static WERROR handle_dnsrpcrec_recv(struct tevent_req *req)
539 {
540         return tevent_req_simple_recv_werror(req);
541 }
542
543 struct handle_authoritative_state {
544         struct tevent_context *ev;
545         struct dns_server *dns;
546         struct dns_name_question *question;
547         const char *forwarder;
548
549         struct dnsp_DnssrvRpcRecord *recs;
550         uint16_t rec_count;
551         uint16_t recs_done;
552
553         struct dns_res_rec **answers;
554         struct dns_res_rec **nsrecs;
555
556         size_t cname_depth;
557 };
558
559 static void handle_authoritative_done(struct tevent_req *subreq);
560
561 static struct tevent_req *handle_authoritative_send(
562         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
563         struct dns_server *dns, const char *forwarder,
564         struct dns_name_question *question,
565         struct dns_res_rec **answers, struct dns_res_rec **nsrecs,
566         size_t cname_depth)
567 {
568         struct tevent_req *req, *subreq;
569         struct handle_authoritative_state *state;
570         struct ldb_dn *dn = NULL;
571         WERROR werr;
572
573         req = tevent_req_create(mem_ctx, &state,
574                                 struct handle_authoritative_state);
575         if (req == NULL) {
576                 return NULL;
577         }
578         state->ev = ev;
579         state->dns = dns;
580         state->question = question;
581         state->forwarder = forwarder;
582         state->answers = answers;
583         state->nsrecs = nsrecs;
584         state->cname_depth = cname_depth;
585
586         werr = dns_name2dn(dns, state, question->name, &dn);
587         if (tevent_req_werror(req, werr)) {
588                 return tevent_req_post(req, ev);
589         }
590         werr = dns_lookup_records_wildcard(dns, state, dn, &state->recs,
591                                            &state->rec_count);
592         TALLOC_FREE(dn);
593         if (tevent_req_werror(req, werr)) {
594                 return tevent_req_post(req, ev);
595         }
596
597         if (state->rec_count == 0) {
598                 tevent_req_werror(req, DNS_ERR(NAME_ERROR));
599                 return tevent_req_post(req, ev);
600         }
601
602         subreq = handle_dnsrpcrec_send(
603                 state, state->ev, state->dns, state->forwarder,
604                 state->question, &state->recs[state->recs_done],
605                 state->answers, state->nsrecs,
606                 state->cname_depth);
607         if (tevent_req_nomem(subreq, req)) {
608                 return tevent_req_post(req, ev);
609         }
610         tevent_req_set_callback(subreq, handle_authoritative_done, req);
611         return req;
612 }
613
614 static void handle_authoritative_done(struct tevent_req *subreq)
615 {
616         struct tevent_req *req = tevent_req_callback_data(
617                 subreq, struct tevent_req);
618         struct handle_authoritative_state *state = tevent_req_data(
619                 req, struct handle_authoritative_state);
620         WERROR werr;
621
622         werr = handle_dnsrpcrec_recv(subreq);
623         TALLOC_FREE(subreq);
624         if (tevent_req_werror(req, werr)) {
625                 return;
626         }
627
628         state->recs_done += 1;
629
630         if (state->recs_done == state->rec_count) {
631                 tevent_req_done(req);
632                 return;
633         }
634
635         subreq = handle_dnsrpcrec_send(
636                 state, state->ev, state->dns, state->forwarder,
637                 state->question, &state->recs[state->recs_done],
638                 state->answers, state->nsrecs,
639                 state->cname_depth);
640         if (tevent_req_nomem(subreq, req)) {
641                 return;
642         }
643         tevent_req_set_callback(subreq, handle_authoritative_done, req);
644 }
645
646 static WERROR handle_authoritative_recv(struct tevent_req *req)
647 {
648         WERROR werr;
649
650         if (tevent_req_is_werror(req, &werr)) {
651                 return werr;
652         }
653
654         return WERR_OK;
655 }
656
657 static NTSTATUS create_tkey(struct dns_server *dns,
658                             const char* name,
659                             const char* algorithm,
660                             const struct tsocket_address *remote_address,
661                             const struct tsocket_address *local_address,
662                             struct dns_server_tkey **tkey)
663 {
664         NTSTATUS status;
665         struct dns_server_tkey_store *store = dns->tkeys;
666         struct dns_server_tkey *k = talloc_zero(store, struct dns_server_tkey);
667
668         if (k == NULL) {
669                 return NT_STATUS_NO_MEMORY;
670         }
671
672         k->name = talloc_strdup(k, name);
673
674         if (k->name  == NULL) {
675                 return NT_STATUS_NO_MEMORY;
676         }
677
678         k->algorithm = talloc_strdup(k, algorithm);
679         if (k->algorithm == NULL) {
680                 return NT_STATUS_NO_MEMORY;
681         }
682
683         /*
684          * We only allow SPNEGO/KRB5 currently
685          * and rely on the backend to be RPC/IPC free.
686          *
687          * It allows gensec_update() not to block.
688          */
689         status = samba_server_gensec_krb5_start(k,
690                                                 dns->task->event_ctx,
691                                                 dns->task->msg_ctx,
692                                                 dns->task->lp_ctx,
693                                                 dns->server_credentials,
694                                                 "dns",
695                                                 &k->gensec);
696         if (!NT_STATUS_IS_OK(status)) {
697                 DEBUG(1, ("Failed to start GENSEC server code: %s\n", nt_errstr(status)));
698                 *tkey = NULL;
699                 return status;
700         }
701
702         gensec_want_feature(k->gensec, GENSEC_FEATURE_SIGN);
703
704         status = gensec_set_remote_address(k->gensec,
705                                            remote_address);
706         if (!NT_STATUS_IS_OK(status)) {
707                 DEBUG(1, ("Failed to set remote address into GENSEC: %s\n",
708                           nt_errstr(status)));
709                 *tkey = NULL;
710                 return status;
711         }
712
713         status = gensec_set_local_address(k->gensec,
714                                           local_address);
715         if (!NT_STATUS_IS_OK(status)) {
716                 DEBUG(1, ("Failed to set local address into GENSEC: %s\n",
717                           nt_errstr(status)));
718                 *tkey = NULL;
719                 return status;
720         }
721
722         status = gensec_start_mech_by_oid(k->gensec, GENSEC_OID_SPNEGO);
723
724         if (!NT_STATUS_IS_OK(status)) {
725                 DEBUG(1, ("Failed to start GENSEC server code: %s\n",
726                           nt_errstr(status)));
727                 *tkey = NULL;
728                 return status;
729         }
730
731         TALLOC_FREE(store->tkeys[store->next_idx]);
732
733         store->tkeys[store->next_idx] = k;
734         (store->next_idx)++;
735         store->next_idx %= store->size;
736
737         *tkey = k;
738         return NT_STATUS_OK;
739 }
740
741 static NTSTATUS accept_gss_ticket(TALLOC_CTX *mem_ctx,
742                                   struct dns_server *dns,
743                                   struct dns_server_tkey *tkey,
744                                   const DATA_BLOB *key,
745                                   DATA_BLOB *reply,
746                                   uint16_t *dns_auth_error)
747 {
748         NTSTATUS status;
749
750         /*
751          * We use samba_server_gensec_krb5_start(),
752          * which only allows SPNEGO/KRB5 currently
753          * and makes sure the backend to be RPC/IPC free.
754          *
755          * See gensec_gssapi_update_internal() as
756          * GENSEC_SERVER.
757          *
758          * It allows gensec_update() not to block.
759          *
760          * If that changes in future we need to use
761          * gensec_update_send/recv here!
762          */
763         status = gensec_update(tkey->gensec, mem_ctx,
764                                *key, reply);
765
766         if (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
767                 *dns_auth_error = DNS_RCODE_OK;
768                 return status;
769         }
770
771         if (NT_STATUS_IS_OK(status)) {
772
773                 status = gensec_session_info(tkey->gensec, tkey, &tkey->session_info);
774                 if (!NT_STATUS_IS_OK(status)) {
775                         *dns_auth_error = DNS_RCODE_BADKEY;
776                         return status;
777                 }
778                 *dns_auth_error = DNS_RCODE_OK;
779         }
780
781         return status;
782 }
783
784 static WERROR handle_tkey(struct dns_server *dns,
785                           TALLOC_CTX *mem_ctx,
786                           const struct dns_name_packet *in,
787                           struct dns_request_state *state,
788                           struct dns_res_rec **answers,
789                           uint16_t *ancount)
790 {
791         struct dns_res_rec *in_tkey = NULL;
792         struct dns_res_rec *ret_tkey;
793         uint16_t i;
794
795         for (i = 0; i < in->arcount; i++) {
796                 if (in->additional[i].rr_type == DNS_QTYPE_TKEY) {
797                         in_tkey = &in->additional[i];
798                         break;
799                 }
800         }
801
802         /* If this is a TKEY query, it should have a TKEY RR.
803          * Behaviour is not really specified in RFC 2930 or RFC 3645, but
804          * FORMAT_ERROR seems to be what BIND uses .*/
805         if (in_tkey == NULL) {
806                 return DNS_ERR(FORMAT_ERROR);
807         }
808
809         ret_tkey = talloc_zero(mem_ctx, struct dns_res_rec);
810         if (ret_tkey == NULL) {
811                 return WERR_NOT_ENOUGH_MEMORY;
812         }
813
814         ret_tkey->name = talloc_strdup(ret_tkey, in_tkey->name);
815         if (ret_tkey->name == NULL) {
816                 return WERR_NOT_ENOUGH_MEMORY;
817         }
818
819         ret_tkey->rr_type = DNS_QTYPE_TKEY;
820         ret_tkey->rr_class = DNS_QCLASS_ANY;
821         ret_tkey->length = UINT16_MAX;
822
823         ret_tkey->rdata.tkey_record.algorithm = talloc_strdup(ret_tkey,
824                         in_tkey->rdata.tkey_record.algorithm);
825         if (ret_tkey->rdata.tkey_record.algorithm  == NULL) {
826                 return WERR_NOT_ENOUGH_MEMORY;
827         }
828
829         ret_tkey->rdata.tkey_record.inception = in_tkey->rdata.tkey_record.inception;
830         ret_tkey->rdata.tkey_record.expiration = in_tkey->rdata.tkey_record.expiration;
831         ret_tkey->rdata.tkey_record.mode = in_tkey->rdata.tkey_record.mode;
832
833         switch (in_tkey->rdata.tkey_record.mode) {
834         case DNS_TKEY_MODE_DH:
835                 /* FIXME: According to RFC 2930, we MUST support this, but we don't.
836                  * Still, claim it's a bad key instead of a bad mode */
837                 ret_tkey->rdata.tkey_record.error = DNS_RCODE_BADKEY;
838                 break;
839         case DNS_TKEY_MODE_GSSAPI: {
840                 NTSTATUS status;
841                 struct dns_server_tkey *tkey;
842                 DATA_BLOB key;
843                 DATA_BLOB reply;
844
845                 tkey = dns_find_tkey(dns->tkeys, in->questions[0].name);
846                 if (tkey != NULL && tkey->complete) {
847                         /* TODO: check if the key is still valid */
848                         DEBUG(1, ("Rejecting tkey negotiation for already established key\n"));
849                         ret_tkey->rdata.tkey_record.error = DNS_RCODE_BADNAME;
850                         break;
851                 }
852
853                 if (tkey == NULL) {
854                         status  = create_tkey(dns, in->questions[0].name,
855                                               in_tkey->rdata.tkey_record.algorithm,
856                                               state->remote_address,
857                                               state->local_address,
858                                               &tkey);
859                         if (!NT_STATUS_IS_OK(status)) {
860                                 ret_tkey->rdata.tkey_record.error = DNS_RCODE_BADKEY;
861                                 return ntstatus_to_werror(status);
862                         }
863                 }
864
865                 key.data = in_tkey->rdata.tkey_record.key_data;
866                 key.length = in_tkey->rdata.tkey_record.key_size;
867
868                 status = accept_gss_ticket(ret_tkey, dns, tkey, &key, &reply,
869                                            &ret_tkey->rdata.tkey_record.error);
870                 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
871                         DEBUG(1, ("More processing required\n"));
872                         ret_tkey->rdata.tkey_record.error = DNS_RCODE_BADKEY;
873                 } else if (NT_STATUS_IS_OK(status)) {
874                         DBG_DEBUG("Tkey handshake completed\n");
875                         ret_tkey->rdata.tkey_record.key_size = reply.length;
876                         ret_tkey->rdata.tkey_record.key_data = talloc_memdup(ret_tkey,
877                                                                 reply.data,
878                                                                 reply.length);
879                         if (ret_tkey->rdata.tkey_record.key_data == NULL) {
880                                 return WERR_NOT_ENOUGH_MEMORY;
881                         }
882                         state->sign = true;
883                         state->key_name = talloc_strdup(state->mem_ctx, tkey->name);
884                         if (state->key_name == NULL) {
885                                 return WERR_NOT_ENOUGH_MEMORY;
886                         }
887                 } else {
888                         DEBUG(1, ("GSS key negotiation returned %s\n", nt_errstr(status)));
889                         ret_tkey->rdata.tkey_record.error = DNS_RCODE_BADKEY;
890                 }
891
892                 break;
893                 }
894         case DNS_TKEY_MODE_DELETE:
895                 /* TODO: implement me */
896                 DEBUG(1, ("Should delete tkey here\n"));
897                 ret_tkey->rdata.tkey_record.error = DNS_RCODE_OK;
898                 break;
899         case DNS_TKEY_MODE_NULL:
900         case DNS_TKEY_MODE_SERVER:
901         case DNS_TKEY_MODE_CLIENT:
902         case DNS_TKEY_MODE_LAST:
903                 /* We don't have to implement these, return a mode error */
904                 ret_tkey->rdata.tkey_record.error = DNS_RCODE_BADMODE;
905                 break;
906         default:
907                 DEBUG(1, ("Unsupported TKEY mode %d\n",
908                       in_tkey->rdata.tkey_record.mode));
909         }
910
911         *answers = ret_tkey;
912         *ancount = 1;
913
914         return WERR_OK;
915 }
916
917 struct dns_server_process_query_state {
918         struct tevent_context *ev;
919         struct dns_server *dns;
920         struct dns_name_question *question;
921
922         struct dns_res_rec *answers;
923         uint16_t ancount;
924         struct dns_res_rec *nsrecs;
925         uint16_t nscount;
926         struct dns_res_rec *additional;
927         uint16_t arcount;
928         struct forwarder_string *forwarders;
929 };
930
931 static void dns_server_process_query_got_auth(struct tevent_req *subreq);
932 static void dns_server_process_query_got_response(struct tevent_req *subreq);
933
934 struct tevent_req *dns_server_process_query_send(
935         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
936         struct dns_server *dns, struct dns_request_state *req_state,
937         const struct dns_name_packet *in)
938 {
939         struct tevent_req *req, *subreq;
940         struct dns_server_process_query_state *state;
941         const char **forwarders = NULL;
942         unsigned int i;
943
944         req = tevent_req_create(mem_ctx, &state,
945                                 struct dns_server_process_query_state);
946         if (req == NULL) {
947                 return NULL;
948         }
949         if (in->qdcount != 1) {
950                 tevent_req_werror(req, DNS_ERR(FORMAT_ERROR));
951                 return tevent_req_post(req, ev);
952         }
953
954         /* Windows returns NOT_IMPLEMENTED on this as well */
955         if (in->questions[0].question_class == DNS_QCLASS_NONE) {
956                 tevent_req_werror(req, DNS_ERR(NOT_IMPLEMENTED));
957                 return tevent_req_post(req, ev);
958         }
959
960         if (in->questions[0].question_type == DNS_QTYPE_TKEY) {
961                 WERROR err;
962
963                 err = handle_tkey(dns, state, in, req_state,
964                                   &state->answers, &state->ancount);
965                 if (tevent_req_werror(req, err)) {
966                         return tevent_req_post(req, ev);
967                 }
968                 tevent_req_done(req);
969                 return tevent_req_post(req, ev);
970         }
971
972         state->dns = dns;
973         state->ev = ev;
974         state->question = &in->questions[0];
975
976         forwarders = lpcfg_dns_forwarder(dns->task->lp_ctx);
977         for (i = 0; forwarders != NULL && forwarders[i] != NULL; i++) {
978                 struct forwarder_string *f = talloc_zero(state,
979                                                          struct forwarder_string);
980                 f->forwarder = forwarders[i];
981                 DLIST_ADD_END(state->forwarders, f);
982         }
983
984         if (dns_authoritative_for_zone(dns, in->questions[0].name)) {
985
986                 req_state->flags |= DNS_FLAG_AUTHORITATIVE;
987
988                 /*
989                  * Initialize the response arrays, so that we can use
990                  * them as their own talloc contexts when doing the
991                  * realloc
992                  */
993                 state->answers = talloc_array(state, struct dns_res_rec, 0);
994                 if (tevent_req_nomem(state->answers, req)) {
995                         return tevent_req_post(req, ev);
996                 }
997                 state->nsrecs = talloc_array(state, struct dns_res_rec, 0);
998                 if (tevent_req_nomem(state->nsrecs, req)) {
999                         return tevent_req_post(req, ev);
1000                 }
1001
1002                 subreq = handle_authoritative_send(
1003                         state, ev, dns, (forwarders == NULL ? NULL : forwarders[0]),
1004                         &in->questions[0], &state->answers, &state->nsrecs,
1005                         0); /* cname_depth */
1006                 if (tevent_req_nomem(subreq, req)) {
1007                         return tevent_req_post(req, ev);
1008                 }
1009                 tevent_req_set_callback(
1010                         subreq, dns_server_process_query_got_auth, req);
1011                 return req;
1012         }
1013
1014         if ((req_state->flags & DNS_FLAG_RECURSION_DESIRED) &&
1015             (req_state->flags & DNS_FLAG_RECURSION_AVAIL)) {
1016                 DEBUG(5, ("Not authoritative for '%s', forwarding\n",
1017                           in->questions[0].name));
1018
1019                 subreq = ask_forwarder_send(state, ev,
1020                                             (forwarders == NULL ? NULL : forwarders[0]),
1021                                             &in->questions[0]);
1022                 if (tevent_req_nomem(subreq, req)) {
1023                         return tevent_req_post(req, ev);
1024                 }
1025                 tevent_req_set_callback(
1026                         subreq, dns_server_process_query_got_response, req);
1027                 return req;
1028         }
1029
1030         tevent_req_werror(req, DNS_ERR(NAME_ERROR));
1031         return tevent_req_post(req, ev);
1032 }
1033
1034 static void dns_server_process_query_got_response(struct tevent_req *subreq)
1035 {
1036         struct tevent_req *req = tevent_req_callback_data(
1037                 subreq, struct tevent_req);
1038         struct dns_server_process_query_state *state = tevent_req_data(
1039                 req, struct dns_server_process_query_state);
1040         WERROR werr;
1041
1042         werr = ask_forwarder_recv(subreq, state,
1043                                   &state->answers, &state->ancount,
1044                                   &state->nsrecs, &state->nscount,
1045                                   &state->additional, &state->arcount);
1046         TALLOC_FREE(subreq);
1047
1048         /* If you get an error, attempt a different forwarder */
1049         if (!W_ERROR_IS_OK(werr)) {
1050                 if (state->forwarders != NULL) {
1051                         DLIST_REMOVE(state->forwarders, state->forwarders);
1052                 }
1053
1054                 /* If you have run out of forwarders, simply finish */
1055                 if (state->forwarders == NULL) {
1056                         tevent_req_werror(req, werr);
1057                         return;
1058                 }
1059
1060                 DEBUG(5, ("DNS query returned %s, trying another forwarder.\n",
1061                           win_errstr(werr)));
1062                 subreq = ask_forwarder_send(state, state->ev,
1063                                             state->forwarders->forwarder,
1064                                             state->question);
1065
1066                 if (tevent_req_nomem(subreq, req)) {
1067                         return;
1068                 }
1069
1070                 tevent_req_set_callback(subreq,
1071                                         dns_server_process_query_got_response,
1072                                         req);
1073                 return;
1074         }
1075
1076         tevent_req_done(req);
1077 }
1078
1079 static void dns_server_process_query_got_auth(struct tevent_req *subreq)
1080 {
1081         struct tevent_req *req = tevent_req_callback_data(
1082                 subreq, struct tevent_req);
1083         struct dns_server_process_query_state *state = tevent_req_data(
1084                 req, struct dns_server_process_query_state);
1085         WERROR werr;
1086         WERROR werr2;
1087
1088         werr = handle_authoritative_recv(subreq);
1089         TALLOC_FREE(subreq);
1090
1091         /* If you get an error, attempt a different forwarder */
1092         if (!W_ERROR_IS_OK(werr)) {
1093                 if (state->forwarders != NULL) {
1094                         DLIST_REMOVE(state->forwarders, state->forwarders);
1095                 }
1096
1097                 /* If you have run out of forwarders, simply finish */
1098                 if (state->forwarders == NULL) {
1099                         werr2 = add_zone_authority_record(state->dns,
1100                                                           state,
1101                                                           state->question,
1102                                                           &state->nsrecs);
1103                         if (tevent_req_werror(req, werr2)) {
1104                                 DBG_WARNING("Failed to add SOA record: %s\n",
1105                                             win_errstr(werr2));
1106                                 return;
1107                         }
1108
1109                         state->ancount = talloc_array_length(state->answers);
1110                         state->nscount = talloc_array_length(state->nsrecs);
1111                         state->arcount = talloc_array_length(state->additional);
1112
1113                         tevent_req_werror(req, werr);
1114                         return;
1115                 }
1116
1117                 DEBUG(5, ("Error: %s, trying a different forwarder.\n",
1118                           win_errstr(werr)));
1119                 subreq = handle_authoritative_send(state, state->ev, state->dns,
1120                                                    state->forwarders->forwarder,
1121                                                    state->question, &state->answers,
1122                                                    &state->nsrecs,
1123                                                    0); /* cname_depth */
1124
1125                 if (tevent_req_nomem(subreq, req)) {
1126                         return;
1127                 }
1128
1129                 tevent_req_set_callback(subreq,
1130                                         dns_server_process_query_got_auth,
1131                                         req);
1132                 return;
1133         }
1134
1135         werr2 = add_zone_authority_record(state->dns,
1136                                           state,
1137                                           state->question,
1138                                           &state->nsrecs);
1139         if (tevent_req_werror(req, werr2)) {
1140                 DBG_WARNING("Failed to add SOA record: %s\n",
1141                                 win_errstr(werr2));
1142                 return;
1143         }
1144
1145         state->ancount = talloc_array_length(state->answers);
1146         state->nscount = talloc_array_length(state->nsrecs);
1147         state->arcount = talloc_array_length(state->additional);
1148
1149         tevent_req_done(req);
1150 }
1151
1152 WERROR dns_server_process_query_recv(
1153         struct tevent_req *req, TALLOC_CTX *mem_ctx,
1154         struct dns_res_rec **answers,    uint16_t *ancount,
1155         struct dns_res_rec **nsrecs,     uint16_t *nscount,
1156         struct dns_res_rec **additional, uint16_t *arcount)
1157 {
1158         struct dns_server_process_query_state *state = tevent_req_data(
1159                 req, struct dns_server_process_query_state);
1160         WERROR err = WERR_OK;
1161
1162         if (tevent_req_is_werror(req, &err)) {
1163
1164                 if ((!W_ERROR_EQUAL(err, DNS_ERR(NAME_ERROR))) &&
1165                     (!W_ERROR_EQUAL(err, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST))) {
1166                         return err;
1167                 }
1168         }
1169         *answers = talloc_move(mem_ctx, &state->answers);
1170         *ancount = state->ancount;
1171         *nsrecs = talloc_move(mem_ctx, &state->nsrecs);
1172         *nscount = state->nscount;
1173         *additional = talloc_move(mem_ctx, &state->additional);
1174         *arcount = state->arcount;
1175         return err;
1176 }