Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : DNS server handler for update requests
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 "libcli/util/ntstatus.h"
24 : #include "librpc/ndr/libndr.h"
25 : #include "librpc/gen_ndr/ndr_dns.h"
26 : #include "librpc/gen_ndr/ndr_dnsp.h"
27 : #include <ldb.h>
28 : #include "param/param.h"
29 : #include "param/loadparm.h"
30 : #include "dsdb/samdb/samdb.h"
31 : #include "dsdb/common/util.h"
32 : #include "samba/service_task.h"
33 : #include "dns_server/dns_server.h"
34 : #include "auth/auth.h"
35 :
36 : #undef DBGC_CLASS
37 : #define DBGC_CLASS DBGC_DNS
38 :
39 : static WERROR dns_rr_to_dnsp(TALLOC_CTX *mem_ctx,
40 : const struct dns_res_rec *rrec,
41 : struct dnsp_DnssrvRpcRecord *r,
42 : bool name_is_static);
43 :
44 202 : static WERROR check_one_prerequisite(struct dns_server *dns,
45 : TALLOC_CTX *mem_ctx,
46 : const struct dns_name_question *zone,
47 : const struct dns_res_rec *pr,
48 : bool *final_result)
49 : {
50 : bool match;
51 : WERROR werror;
52 : struct ldb_dn *dn;
53 : uint16_t i;
54 202 : bool found = false;
55 202 : struct dnsp_DnssrvRpcRecord *rec = NULL;
56 : struct dnsp_DnssrvRpcRecord *ans;
57 : uint16_t acount;
58 :
59 202 : size_t host_part_len = 0;
60 :
61 202 : *final_result = true;
62 :
63 202 : if (pr->ttl != 0) {
64 4 : return DNS_ERR(FORMAT_ERROR);
65 : }
66 :
67 198 : match = dns_name_match(zone->name, pr->name, &host_part_len);
68 198 : if (!match) {
69 6 : return DNS_ERR(NOTZONE);
70 : }
71 :
72 192 : werror = dns_name2dn(dns, mem_ctx, pr->name, &dn);
73 192 : W_ERROR_NOT_OK_RETURN(werror);
74 :
75 192 : if (pr->rr_class == DNS_QCLASS_ANY) {
76 :
77 8 : if (pr->length != 0) {
78 0 : return DNS_ERR(FORMAT_ERROR);
79 : }
80 :
81 :
82 8 : if (pr->rr_type == DNS_QTYPE_ALL) {
83 : /*
84 : */
85 0 : werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount);
86 0 : if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) {
87 0 : return DNS_ERR(NAME_ERROR);
88 : }
89 0 : W_ERROR_NOT_OK_RETURN(werror);
90 :
91 0 : if (acount == 0) {
92 0 : return DNS_ERR(NAME_ERROR);
93 : }
94 : } else {
95 : /*
96 : */
97 8 : werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount);
98 8 : if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) {
99 4 : return DNS_ERR(NXRRSET);
100 : }
101 4 : if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) {
102 0 : return DNS_ERR(NXRRSET);
103 : }
104 4 : W_ERROR_NOT_OK_RETURN(werror);
105 :
106 12 : for (i = 0; i < acount; i++) {
107 8 : if (ans[i].wType == (enum dns_record_type) pr->rr_type) {
108 0 : found = true;
109 0 : break;
110 : }
111 : }
112 4 : if (!found) {
113 4 : return DNS_ERR(NXRRSET);
114 : }
115 : }
116 :
117 : /*
118 : * RFC2136 3.2.5 doesn't actually mention the need to return
119 : * OK here, but otherwise we'd always return a FORMAT_ERROR
120 : * later on. This also matches Microsoft DNS behavior.
121 : */
122 0 : return WERR_OK;
123 : }
124 :
125 184 : if (pr->rr_class == DNS_QCLASS_NONE) {
126 134 : if (pr->length != 0) {
127 0 : return DNS_ERR(FORMAT_ERROR);
128 : }
129 :
130 134 : if (pr->rr_type == DNS_QTYPE_ALL) {
131 : /*
132 : */
133 0 : werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount);
134 0 : if (W_ERROR_EQUAL(werror, WERR_OK)) {
135 0 : return DNS_ERR(YXDOMAIN);
136 : }
137 : } else {
138 : /*
139 : */
140 134 : werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount);
141 134 : if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) {
142 110 : werror = WERR_OK;
143 : }
144 134 : if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) {
145 0 : werror = WERR_OK;
146 : }
147 :
148 166 : for (i = 0; i < acount; i++) {
149 32 : if (ans[i].wType == (enum dns_record_type) pr->rr_type) {
150 0 : found = true;
151 0 : break;
152 : }
153 : }
154 134 : if (found) {
155 0 : return DNS_ERR(YXRRSET);
156 : }
157 : }
158 :
159 : /*
160 : * RFC2136 3.2.5 doesn't actually mention the need to return
161 : * OK here, but otherwise we'd always return a FORMAT_ERROR
162 : * later on. This also matches Microsoft DNS behavior.
163 : */
164 134 : return WERR_OK;
165 : }
166 :
167 50 : if (pr->rr_class != zone->question_class) {
168 0 : return DNS_ERR(FORMAT_ERROR);
169 : }
170 :
171 50 : *final_result = false;
172 :
173 50 : werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount);
174 50 : if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) {
175 44 : return DNS_ERR(NXRRSET);
176 : }
177 6 : if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) {
178 0 : return DNS_ERR(NXRRSET);
179 : }
180 6 : W_ERROR_NOT_OK_RETURN(werror);
181 :
182 6 : rec = talloc_zero(mem_ctx, struct dnsp_DnssrvRpcRecord);
183 6 : W_ERROR_HAVE_NO_MEMORY(rec);
184 :
185 6 : werror = dns_rr_to_dnsp(rec, pr, rec, dns_name_is_static(ans, acount));
186 6 : W_ERROR_NOT_OK_RETURN(werror);
187 :
188 10 : for (i = 0; i < acount; i++) {
189 6 : if (dns_record_match(rec, &ans[i])) {
190 2 : found = true;
191 2 : break;
192 : }
193 : }
194 :
195 6 : if (!found) {
196 4 : return DNS_ERR(NXRRSET);
197 : }
198 :
199 2 : return WERR_OK;
200 : }
201 :
202 2729 : static WERROR check_prerequisites(struct dns_server *dns,
203 : TALLOC_CTX *mem_ctx,
204 : const struct dns_name_question *zone,
205 : const struct dns_res_rec *prereqs, uint16_t count)
206 : {
207 : uint16_t i;
208 2729 : WERROR final_error = WERR_OK;
209 :
210 2913 : for (i = 0; i < count; i++) {
211 : bool final;
212 : WERROR werror;
213 :
214 202 : werror = check_one_prerequisite(dns, mem_ctx, zone,
215 202 : &prereqs[i], &final);
216 202 : if (!W_ERROR_IS_OK(werror)) {
217 66 : if (final) {
218 18 : return werror;
219 : }
220 48 : if (W_ERROR_IS_OK(final_error)) {
221 28 : final_error = werror;
222 : }
223 : }
224 : }
225 :
226 2711 : if (!W_ERROR_IS_OK(final_error)) {
227 28 : return final_error;
228 : }
229 :
230 2683 : return WERR_OK;
231 : }
232 :
233 1295 : static WERROR update_prescan(const struct dns_name_question *zone,
234 : const struct dns_res_rec *updates, uint16_t count)
235 : {
236 : const struct dns_res_rec *r;
237 : uint16_t i;
238 : size_t host_part_len;
239 : bool match;
240 :
241 2648 : for (i = 0; i < count; i++) {
242 1353 : r = &updates[i];
243 1353 : match = dns_name_match(zone->name, r->name, &host_part_len);
244 1353 : if (!match) {
245 0 : return DNS_ERR(NOTZONE);
246 : }
247 1353 : if (zone->question_class == r->rr_class) {
248 1184 : if (r->rr_type == DNS_QTYPE_ALL) {
249 0 : return DNS_ERR(FORMAT_ERROR);
250 : }
251 1184 : if (r->rr_type == DNS_QTYPE_AXFR) {
252 0 : return DNS_ERR(FORMAT_ERROR);
253 : }
254 1184 : if (r->rr_type == DNS_QTYPE_MAILB) {
255 0 : return DNS_ERR(FORMAT_ERROR);
256 : }
257 1184 : if (r->rr_type == DNS_QTYPE_MAILA) {
258 0 : return DNS_ERR(FORMAT_ERROR);
259 : }
260 169 : } else if (r->rr_class == DNS_QCLASS_ANY) {
261 40 : if (r->ttl != 0) {
262 0 : return DNS_ERR(FORMAT_ERROR);
263 : }
264 40 : if (r->length != 0) {
265 0 : return DNS_ERR(FORMAT_ERROR);
266 : }
267 40 : if (r->rr_type == DNS_QTYPE_AXFR) {
268 0 : return DNS_ERR(FORMAT_ERROR);
269 : }
270 40 : if (r->rr_type == DNS_QTYPE_MAILB) {
271 0 : return DNS_ERR(FORMAT_ERROR);
272 : }
273 40 : if (r->rr_type == DNS_QTYPE_MAILA) {
274 0 : return DNS_ERR(FORMAT_ERROR);
275 : }
276 129 : } else if (r->rr_class == DNS_QCLASS_NONE) {
277 129 : if (r->ttl != 0) {
278 0 : return DNS_ERR(FORMAT_ERROR);
279 : }
280 129 : if (r->rr_type == DNS_QTYPE_ALL) {
281 0 : return DNS_ERR(FORMAT_ERROR);
282 : }
283 129 : if (r->rr_type == DNS_QTYPE_AXFR) {
284 0 : return DNS_ERR(FORMAT_ERROR);
285 : }
286 129 : if (r->rr_type == DNS_QTYPE_MAILB) {
287 0 : return DNS_ERR(FORMAT_ERROR);
288 : }
289 129 : if (r->rr_type == DNS_QTYPE_MAILA) {
290 0 : return DNS_ERR(FORMAT_ERROR);
291 : }
292 : } else {
293 0 : return DNS_ERR(FORMAT_ERROR);
294 : }
295 : }
296 1295 : return WERR_OK;
297 : }
298 :
299 1317 : static WERROR dns_rr_to_dnsp(TALLOC_CTX *mem_ctx,
300 : const struct dns_res_rec *rrec,
301 : struct dnsp_DnssrvRpcRecord *r,
302 : bool name_is_static)
303 : {
304 : enum ndr_err_code ndr_err;
305 :
306 1317 : if (rrec->rr_type == DNS_QTYPE_ALL) {
307 0 : return DNS_ERR(FORMAT_ERROR);
308 : }
309 :
310 1317 : ZERO_STRUCTP(r);
311 :
312 1317 : r->wType = (enum dns_record_type) rrec->rr_type;
313 1317 : r->dwTtlSeconds = rrec->ttl;
314 1317 : r->rank = DNS_RANK_ZONE;
315 1317 : if (name_is_static) {
316 247 : r->dwTimeStamp = 0;
317 : } else {
318 1070 : r->dwTimeStamp = unix_to_dns_timestamp(time(NULL));
319 : }
320 :
321 : /* If we get QCLASS_ANY, we're done here */
322 1317 : if (rrec->rr_class == DNS_QCLASS_ANY) {
323 0 : goto done;
324 : }
325 :
326 1317 : switch(rrec->rr_type) {
327 232 : case DNS_QTYPE_A:
328 232 : r->data.ipv4 = talloc_strdup(mem_ctx, rrec->rdata.ipv4_record);
329 232 : W_ERROR_HAVE_NO_MEMORY(r->data.ipv4);
330 711 : break;
331 128 : case DNS_QTYPE_AAAA:
332 128 : r->data.ipv6 = talloc_strdup(mem_ctx, rrec->rdata.ipv6_record);
333 128 : W_ERROR_HAVE_NO_MEMORY(r->data.ipv6);
334 128 : break;
335 6 : case DNS_QTYPE_NS:
336 6 : r->data.ns = talloc_strdup(mem_ctx, rrec->rdata.ns_record);
337 6 : W_ERROR_HAVE_NO_MEMORY(r->data.ns);
338 6 : break;
339 45 : case DNS_QTYPE_CNAME:
340 45 : r->data.cname = talloc_strdup(mem_ctx, rrec->rdata.cname_record);
341 45 : W_ERROR_HAVE_NO_MEMORY(r->data.cname);
342 45 : break;
343 146 : case DNS_QTYPE_SRV:
344 146 : r->data.srv.wPriority = rrec->rdata.srv_record.priority;
345 146 : r->data.srv.wWeight = rrec->rdata.srv_record.weight;
346 146 : r->data.srv.wPort = rrec->rdata.srv_record.port;
347 171 : r->data.srv.nameTarget = talloc_strdup(mem_ctx,
348 25 : rrec->rdata.srv_record.target);
349 146 : W_ERROR_HAVE_NO_MEMORY(r->data.srv.nameTarget);
350 146 : break;
351 0 : case DNS_QTYPE_PTR:
352 0 : r->data.ptr = talloc_strdup(mem_ctx, rrec->rdata.ptr_record);
353 0 : W_ERROR_HAVE_NO_MEMORY(r->data.ptr);
354 0 : break;
355 2 : case DNS_QTYPE_MX:
356 2 : r->data.mx.wPriority = rrec->rdata.mx_record.preference;
357 3 : r->data.mx.nameTarget = talloc_strdup(mem_ctx,
358 1 : rrec->rdata.mx_record.exchange);
359 2 : W_ERROR_HAVE_NO_MEMORY(r->data.mx.nameTarget);
360 2 : break;
361 758 : case DNS_QTYPE_TXT:
362 758 : ndr_err = ndr_dnsp_string_list_copy(mem_ctx,
363 : &rrec->rdata.txt_record.txt,
364 : &r->data.txt);
365 758 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
366 0 : return WERR_NOT_ENOUGH_MEMORY;
367 : }
368 :
369 758 : break;
370 0 : default:
371 0 : DEBUG(0, ("Got a qytpe of %d\n", rrec->rr_type));
372 0 : return DNS_ERR(NOT_IMPLEMENTED);
373 : }
374 :
375 1317 : done:
376 :
377 1317 : return WERR_OK;
378 : }
379 :
380 :
381 1351 : static WERROR handle_one_update(struct dns_server *dns,
382 : TALLOC_CTX *mem_ctx,
383 : const struct dns_name_question *zone,
384 : const struct dns_res_rec *update,
385 : const struct dns_server_tkey *tkey)
386 : {
387 1351 : struct dnsp_DnssrvRpcRecord *recs = NULL;
388 1351 : uint16_t rcount = 0;
389 : struct ldb_dn *dn;
390 : uint16_t i;
391 1351 : uint16_t first = 0;
392 : WERROR werror;
393 1351 : bool tombstoned = false;
394 1351 : bool needs_add = false;
395 : bool name_is_static;
396 :
397 1351 : DEBUG(2, ("Looking at record: \n"));
398 1351 : if (DEBUGLVL(2)) {
399 0 : NDR_PRINT_DEBUG(dns_res_rec, discard_const(update));
400 : }
401 :
402 1351 : switch (update->rr_type) {
403 1351 : case DNS_QTYPE_A:
404 : case DNS_QTYPE_NS:
405 : case DNS_QTYPE_CNAME:
406 : case DNS_QTYPE_SOA:
407 : case DNS_QTYPE_PTR:
408 : case DNS_QTYPE_MX:
409 : case DNS_QTYPE_AAAA:
410 : case DNS_QTYPE_SRV:
411 : case DNS_QTYPE_TXT:
412 : case DNS_QTYPE_ALL:
413 1351 : break;
414 0 : default:
415 0 : DEBUG(0, ("Can't handle updates of type %u yet\n",
416 : update->rr_type));
417 0 : return DNS_ERR(NOT_IMPLEMENTED);
418 : }
419 :
420 1351 : werror = dns_name2dn(dns, mem_ctx, update->name, &dn);
421 1351 : W_ERROR_NOT_OK_RETURN(werror);
422 :
423 1351 : werror = dns_common_lookup(dns->samdb, mem_ctx, dn,
424 : &recs, &rcount, &tombstoned);
425 1351 : if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) {
426 340 : needs_add = true;
427 340 : werror = WERR_OK;
428 : }
429 1351 : W_ERROR_NOT_OK_RETURN(werror);
430 :
431 1351 : if (tombstoned) {
432 : /*
433 : * we need to keep the existing tombstone record
434 : * and ignore it.
435 : *
436 : * There *should* only be a single record of type TOMBSTONE,
437 : * but we don't insist.
438 : */
439 18 : if (rcount != 1) {
440 0 : DBG_WARNING("Tombstoned dnsNode has %u records, "
441 : "expected 1\n", rcount);
442 0 : if (DEBUGLVL(1)) {
443 0 : NDR_PRINT_DEBUG(dns_res_rec, discard_const(update));
444 : }
445 : }
446 18 : first = rcount;
447 : }
448 :
449 1351 : name_is_static = dns_name_is_static(recs, rcount);
450 :
451 1351 : if (update->rr_class == zone->question_class) {
452 1182 : if (update->rr_type == DNS_QTYPE_CNAME) {
453 : /*
454 : * If there is a record in the directory
455 : * that's not a CNAME, ignore update
456 : */
457 66 : for (i = first; i < rcount; i++) {
458 10 : if (recs[i].wType != DNS_TYPE_CNAME) {
459 0 : DEBUG(5, ("Skipping update\n"));
460 0 : return WERR_OK;
461 : }
462 10 : break;
463 : }
464 :
465 : /*
466 : * There should be no entries besides one CNAME record
467 : * per name, so replace everything with the new CNAME
468 : */
469 :
470 43 : rcount = first;
471 43 : recs = talloc_realloc(mem_ctx, recs,
472 : struct dnsp_DnssrvRpcRecord, rcount + 1);
473 43 : W_ERROR_HAVE_NO_MEMORY(recs);
474 :
475 66 : werror = dns_rr_to_dnsp(
476 43 : recs, update, &recs[rcount], name_is_static);
477 43 : W_ERROR_NOT_OK_RETURN(werror);
478 43 : rcount += 1;
479 :
480 43 : werror = dns_replace_records(dns, mem_ctx, dn,
481 : needs_add, recs, rcount);
482 43 : W_ERROR_NOT_OK_RETURN(werror);
483 :
484 41 : return WERR_OK;
485 : } else {
486 : /*
487 : * If there is a CNAME record for this name,
488 : * ignore update
489 : */
490 4537 : for (i = first; i < rcount; i++) {
491 3398 : if (recs[i].wType == DNS_TYPE_CNAME) {
492 0 : DEBUG(5, ("Skipping update\n"));
493 0 : return WERR_OK;
494 : }
495 : }
496 : }
497 1139 : if (update->rr_type == DNS_QTYPE_SOA) {
498 0 : bool found = false;
499 :
500 : /*
501 : * If the zone has no SOA record?? or update's
502 : * serial number is smaller than existing SOA's,
503 : * ignore update
504 : */
505 0 : for (i = first; i < rcount; i++) {
506 0 : if (recs[i].wType == DNS_TYPE_SOA) {
507 : uint16_t n, o;
508 :
509 0 : n = update->rdata.soa_record.serial;
510 0 : o = recs[i].data.soa.serial;
511 : /*
512 : * TODO: Implement RFC 1982 comparison
513 : * logic for RFC2136
514 : */
515 0 : if (n <= o) {
516 0 : DEBUG(5, ("Skipping update\n"));
517 0 : return WERR_OK;
518 : }
519 0 : found = true;
520 0 : break;
521 : }
522 : }
523 0 : if (!found) {
524 0 : DEBUG(5, ("Skipping update\n"));
525 0 : return WERR_OK;
526 : }
527 :
528 0 : werror = dns_rr_to_dnsp(
529 0 : mem_ctx, update, &recs[i], name_is_static);
530 0 : W_ERROR_NOT_OK_RETURN(werror);
531 :
532 : /*
533 : * There should only be one SOA, which we have already
534 : * found and replaced. We now check for and tombstone
535 : * any others.
536 : */
537 0 : for (i++; i < rcount; i++) {
538 0 : if (recs[i].wType != DNS_TYPE_SOA) {
539 0 : continue;
540 : }
541 0 : DBG_ERR("Duplicate SOA records found.\n");
542 0 : if (DEBUGLVL(0)) {
543 0 : NDR_PRINT_DEBUG(dns_res_rec,
544 : discard_const(update));
545 : }
546 0 : recs[i] = (struct dnsp_DnssrvRpcRecord) {
547 : .wType = DNS_TYPE_TOMBSTONE,
548 : };
549 : }
550 :
551 0 : werror = dns_replace_records(dns, mem_ctx, dn,
552 : needs_add, recs, rcount);
553 0 : W_ERROR_NOT_OK_RETURN(werror);
554 :
555 0 : return WERR_OK;
556 : }
557 : /* All but CNAME, SOA */
558 1139 : recs = talloc_realloc(mem_ctx, recs,
559 : struct dnsp_DnssrvRpcRecord, rcount+1);
560 1139 : W_ERROR_HAVE_NO_MEMORY(recs);
561 :
562 640 : werror =
563 1139 : dns_rr_to_dnsp(recs, update, &recs[rcount], name_is_static);
564 1139 : W_ERROR_NOT_OK_RETURN(werror);
565 :
566 6336 : for (i = first; i < rcount; i++) {
567 3258 : if (!dns_record_match(&recs[i], &recs[rcount])) {
568 2970 : continue;
569 : }
570 :
571 288 : recs[i].data = recs[rcount].data;
572 288 : recs[i].wType = recs[rcount].wType;
573 288 : recs[i].dwTtlSeconds = recs[rcount].dwTtlSeconds;
574 288 : recs[i].rank = recs[rcount].rank;
575 288 : recs[i].dwReserved = 0;
576 288 : recs[i].flags = 0;
577 288 : werror = dns_replace_records(dns, mem_ctx, dn,
578 : needs_add, recs, rcount);
579 432 : W_ERROR_NOT_OK_RETURN(werror);
580 :
581 288 : return WERR_OK;
582 : }
583 : /* we did not find a matching record. This is new. */
584 851 : werror = dns_replace_records(dns, mem_ctx, dn,
585 851 : needs_add, recs, rcount+1);
586 851 : W_ERROR_NOT_OK_RETURN(werror);
587 :
588 851 : return WERR_OK;
589 169 : } else if (update->rr_class == DNS_QCLASS_ANY) {
590 : /*
591 : * Mass-deleting records by type, which we do by adding a
592 : * tombstone with zero timestamp. dns_replace_records() will
593 : * work out if the node as a whole needs tombstoning.
594 : */
595 40 : if (update->rr_type == DNS_QTYPE_ALL) {
596 32 : if (samba_dns_name_equal(update->name, zone->name)) {
597 0 : for (i = first; i < rcount; i++) {
598 :
599 0 : if (recs[i].wType == DNS_TYPE_SOA) {
600 0 : continue;
601 : }
602 :
603 0 : if (recs[i].wType == DNS_TYPE_NS) {
604 0 : continue;
605 : }
606 :
607 0 : recs[i] = (struct dnsp_DnssrvRpcRecord) {
608 : .wType = DNS_TYPE_TOMBSTONE,
609 : };
610 : }
611 :
612 : } else {
613 40 : for (i = first; i < rcount; i++) {
614 8 : recs[i] = (struct dnsp_DnssrvRpcRecord) {
615 : .wType = DNS_TYPE_TOMBSTONE,
616 : };
617 : }
618 : }
619 :
620 8 : } else if (samba_dns_name_equal(update->name, zone->name)) {
621 :
622 0 : if (update->rr_type == DNS_QTYPE_SOA) {
623 0 : return WERR_OK;
624 : }
625 :
626 0 : if (update->rr_type == DNS_QTYPE_NS) {
627 0 : return WERR_OK;
628 : }
629 : }
630 84 : for (i = first; i < rcount; i++) {
631 44 : if (recs[i].wType == (enum dns_record_type) update->rr_type) {
632 12 : recs[i] = (struct dnsp_DnssrvRpcRecord) {
633 : .wType = DNS_TYPE_TOMBSTONE,
634 : };
635 : }
636 : }
637 :
638 40 : werror = dns_replace_records(dns, mem_ctx, dn,
639 : needs_add, recs, rcount);
640 40 : W_ERROR_NOT_OK_RETURN(werror);
641 :
642 38 : return WERR_OK;
643 129 : } else if (update->rr_class == DNS_QCLASS_NONE) {
644 : /* deleting individual records */
645 : struct dnsp_DnssrvRpcRecord *del_rec;
646 :
647 129 : if (update->rr_type == DNS_QTYPE_SOA) {
648 0 : return WERR_OK;
649 : }
650 129 : if (update->rr_type == DNS_QTYPE_NS) {
651 0 : bool found = false;
652 0 : struct dnsp_DnssrvRpcRecord *ns_rec = talloc(mem_ctx,
653 : struct dnsp_DnssrvRpcRecord);
654 0 : W_ERROR_HAVE_NO_MEMORY(ns_rec);
655 :
656 0 : werror = dns_rr_to_dnsp(
657 : ns_rec, update, ns_rec, name_is_static);
658 0 : W_ERROR_NOT_OK_RETURN(werror);
659 :
660 0 : for (i = first; i < rcount; i++) {
661 0 : if (dns_record_match(ns_rec, &recs[i])) {
662 0 : found = true;
663 0 : break;
664 : }
665 : }
666 0 : if (found) {
667 0 : return WERR_OK;
668 : }
669 : }
670 :
671 129 : del_rec = talloc(mem_ctx, struct dnsp_DnssrvRpcRecord);
672 129 : W_ERROR_HAVE_NO_MEMORY(del_rec);
673 :
674 72 : werror =
675 129 : dns_rr_to_dnsp(del_rec, update, del_rec, name_is_static);
676 129 : W_ERROR_NOT_OK_RETURN(werror);
677 :
678 415 : for (i = first; i < rcount; i++) {
679 286 : if (dns_record_match(del_rec, &recs[i])) {
680 127 : recs[i] = (struct dnsp_DnssrvRpcRecord) {
681 : .wType = DNS_TYPE_TOMBSTONE,
682 : };
683 : }
684 : }
685 :
686 129 : werror = dns_replace_records(dns, mem_ctx, dn,
687 : needs_add, recs, rcount);
688 129 : W_ERROR_NOT_OK_RETURN(werror);
689 : }
690 :
691 129 : return WERR_OK;
692 : }
693 :
694 1295 : static WERROR handle_updates(struct dns_server *dns,
695 : TALLOC_CTX *mem_ctx,
696 : const struct dns_name_question *zone,
697 : const struct dns_res_rec *prereqs, uint16_t pcount,
698 : struct dns_res_rec *updates, uint16_t upd_count,
699 : struct dns_server_tkey *tkey)
700 : {
701 1295 : struct ldb_dn *zone_dn = NULL;
702 1295 : WERROR werror = WERR_OK;
703 : int ret;
704 : uint16_t ri;
705 1295 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
706 :
707 1295 : if (tkey != NULL) {
708 195 : ret = ldb_set_opaque(
709 : dns->samdb,
710 : DSDB_SESSION_INFO,
711 195 : tkey->session_info);
712 195 : if (ret != LDB_SUCCESS) {
713 0 : DEBUG(1, ("unable to set session info\n"));
714 0 : werror = DNS_ERR(SERVER_FAILURE);
715 0 : goto failed;
716 : }
717 : }
718 :
719 1295 : werror = dns_name2dn(dns, tmp_ctx, zone->name, &zone_dn);
720 1295 : W_ERROR_NOT_OK_GOTO(werror, failed);
721 :
722 1295 : ret = ldb_transaction_start(dns->samdb);
723 1295 : if (ret != LDB_SUCCESS) {
724 0 : werror = DNS_ERR(SERVER_FAILURE);
725 0 : goto failed;
726 : }
727 :
728 1295 : werror = check_prerequisites(dns, tmp_ctx, zone, prereqs, pcount);
729 1295 : W_ERROR_NOT_OK_GOTO(werror, failed);
730 :
731 1295 : DBG_DEBUG("dns update count is %u\n", upd_count);
732 :
733 2642 : for (ri = 0; ri < upd_count; ri++) {
734 1351 : werror = handle_one_update(dns, tmp_ctx, zone,
735 1351 : &updates[ri], tkey);
736 1351 : W_ERROR_NOT_OK_GOTO(werror, failed);
737 : }
738 :
739 1291 : ldb_transaction_commit(dns->samdb);
740 1291 : TALLOC_FREE(tmp_ctx);
741 :
742 1291 : if (tkey != NULL) {
743 193 : ldb_set_opaque(
744 : dns->samdb,
745 : DSDB_SESSION_INFO,
746 193 : system_session(dns->task->lp_ctx));
747 : }
748 :
749 1291 : return WERR_OK;
750 :
751 4 : failed:
752 4 : ldb_transaction_cancel(dns->samdb);
753 :
754 4 : if (tkey != NULL) {
755 2 : ldb_set_opaque(
756 : dns->samdb,
757 : DSDB_SESSION_INFO,
758 2 : system_session(dns->task->lp_ctx));
759 : }
760 :
761 4 : TALLOC_FREE(tmp_ctx);
762 4 : return werror;
763 :
764 : }
765 :
766 1388 : static WERROR dns_update_allowed(struct dns_server *dns,
767 : const struct dns_request_state *state,
768 : struct dns_server_tkey **tkey)
769 : {
770 1388 : if (lpcfg_allow_dns_updates(dns->task->lp_ctx) == DNS_UPDATE_ON) {
771 1100 : DEBUG(2, ("All updates allowed.\n"));
772 1100 : return WERR_OK;
773 : }
774 :
775 288 : if (lpcfg_allow_dns_updates(dns->task->lp_ctx) == DNS_UPDATE_OFF) {
776 0 : DEBUG(2, ("Updates disabled.\n"));
777 0 : return DNS_ERR(REFUSED);
778 : }
779 :
780 288 : if (state->authenticated == false ) {
781 93 : DEBUG(2, ("Update not allowed for unsigned packet.\n"));
782 93 : return DNS_ERR(REFUSED);
783 : }
784 :
785 195 : *tkey = dns_find_tkey(dns->tkeys, state->key_name);
786 195 : if (*tkey == NULL) {
787 0 : DEBUG(0, ("Authenticated, but key not found. Something is wrong.\n"));
788 0 : return DNS_ERR(REFUSED);
789 : }
790 :
791 195 : return WERR_OK;
792 : }
793 :
794 :
795 1442 : WERROR dns_server_process_update(struct dns_server *dns,
796 : const struct dns_request_state *state,
797 : TALLOC_CTX *mem_ctx,
798 : const struct dns_name_packet *in,
799 : struct dns_res_rec **prereqs, uint16_t *prereq_count,
800 : struct dns_res_rec **updates, uint16_t *update_count,
801 : struct dns_res_rec **additional, uint16_t *arcount)
802 : {
803 : struct dns_name_question *zone;
804 : const struct dns_server_zone *z;
805 1442 : size_t host_part_len = 0;
806 1442 : WERROR werror = DNS_ERR(NOT_IMPLEMENTED);
807 1442 : struct dns_server_tkey *tkey = NULL;
808 :
809 1442 : if (in->qdcount != 1) {
810 4 : return DNS_ERR(FORMAT_ERROR);
811 : }
812 :
813 1438 : zone = &in->questions[0];
814 :
815 1441 : if (zone->question_class != DNS_QCLASS_IN &&
816 4 : zone->question_class != DNS_QCLASS_ANY) {
817 4 : return DNS_ERR(NOT_IMPLEMENTED);
818 : }
819 :
820 1434 : if (zone->question_type != DNS_QTYPE_SOA) {
821 0 : return DNS_ERR(FORMAT_ERROR);
822 : }
823 :
824 1434 : DEBUG(2, ("Got a dns update request.\n"));
825 :
826 2166 : for (z = dns->zones; z != NULL; z = z->next) {
827 : bool match;
828 :
829 2166 : match = dns_name_match(z->name, zone->name, &host_part_len);
830 2166 : if (match) {
831 1434 : break;
832 : }
833 : }
834 :
835 1434 : if (z == NULL) {
836 0 : DEBUG(1, ("We're not authoritative for this zone\n"));
837 0 : return DNS_ERR(NOTAUTH);
838 : }
839 :
840 1434 : if (host_part_len != 0) {
841 : /* TODO: We need to delegate this one */
842 0 : DEBUG(1, ("Would have to delegate zone '%s'.\n", zone->name));
843 0 : return DNS_ERR(NOT_IMPLEMENTED);
844 : }
845 :
846 1434 : *prereq_count = in->ancount;
847 1434 : *prereqs = in->answers;
848 1434 : werror = check_prerequisites(dns, mem_ctx, in->questions, *prereqs,
849 1434 : *prereq_count);
850 1434 : W_ERROR_NOT_OK_RETURN(werror);
851 :
852 1388 : werror = dns_update_allowed(dns, state, &tkey);
853 1388 : if (!W_ERROR_IS_OK(werror)) {
854 93 : return werror;
855 : }
856 :
857 1295 : *update_count = in->nscount;
858 1295 : *updates = in->nsrecs;
859 1295 : werror = update_prescan(in->questions, *updates, *update_count);
860 1295 : W_ERROR_NOT_OK_RETURN(werror);
861 :
862 2745 : werror = handle_updates(dns, mem_ctx, in->questions, *prereqs,
863 2020 : *prereq_count, *updates, *update_count, tkey);
864 1295 : W_ERROR_NOT_OK_RETURN(werror);
865 :
866 1291 : return werror;
867 : }
|