2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Bartlett 2012
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "torture/smbtorture.h"
22 #include "system/network.h"
23 #include "dns_server/dlz_minimal.h"
26 #include "lib/param/param.h"
27 #include "dsdb/samdb/samdb.h"
28 #include "dsdb/common/util.h"
29 #include "auth/session.h"
30 #include "auth/gensec/gensec.h"
31 #include "auth/credentials/credentials.h"
32 #include "lib/cmdline/cmdline.h"
33 #include "system/network.h"
34 #include "dns_server/dnsserver_common.h"
35 #include "librpc/gen_ndr/ndr_dnsserver.h"
36 #include "librpc/gen_ndr/ndr_dnsserver_c.h"
37 #include "torture/rpc/torture_rpc.h"
38 #include "librpc/gen_ndr/ndr_dnsp.h"
40 #include "librpc/rpc/dcerpc.h"
41 #include "librpc/rpc/dcerpc_proto.h"
43 /* Tests that configure multiple DLZs will use this. Increase to add stress. */
44 #define NUM_DLZS_TO_CONFIGURE 4
46 struct torture_context
*tctx_static
;
48 static void dlz_bind9_log_wrapper(int level
, const char *fmt
, ...)
49 PRINTF_ATTRIBUTE(2,3);
51 static void dlz_bind9_log_wrapper(int level
, const char *fmt
, ...)
56 msg
= talloc_vasprintf(NULL
, fmt
, ap
);
57 torture_comment(tctx_static
, "%s\n", msg
);
62 static bool test_dlz_bind9_version(struct torture_context
*tctx
)
64 unsigned int flags
= 0;
65 torture_assert_int_equal(tctx
, dlz_version(&flags
),
66 DLZ_DLOPEN_VERSION
, "got wrong DLZ version");
70 static char *dlz_bind9_binddns_dir(struct torture_context
*tctx
,
73 return talloc_asprintf(tctx
,
75 lpcfg_binddns_dir(tctx
->lp_ctx
),
79 static bool test_dlz_bind9_create(struct torture_context
*tctx
)
82 const char *argv
[] = {
85 dlz_bind9_binddns_dir(tctx
, "dns/sam.ldb"),
89 torture_assert_int_equal(tctx
, dlz_create("samba_dlz", 3, argv
, &dbdata
,
90 "log", dlz_bind9_log_wrapper
, NULL
), ISC_R_SUCCESS
,
91 "Failed to create samba_dlz");
98 static bool calls_zone_hook
= false;
100 static isc_result_t
dlz_bind9_writeable_zone_hook(dns_view_t
*view
,
102 const char *zone_name
)
104 struct torture_context
*tctx
= talloc_get_type((void *)view
, struct torture_context
);
105 struct ldb_context
*samdb
= NULL
;
106 char *errstring
= NULL
;
107 int ret
= samdb_connect_url(
111 system_session(tctx
->lp_ctx
),
113 dlz_bind9_binddns_dir(tctx
, "dns/sam.ldb"),
117 struct ldb_message
*msg
;
118 const char *attrs
[] = {
121 if (ret
!= LDB_SUCCESS
) {
122 torture_comment(tctx
, "Failed to connect to samdb");
123 return ISC_R_FAILURE
;
126 ret
= dsdb_search_one(samdb
, tctx
, &msg
, NULL
,
127 LDB_SCOPE_SUBTREE
, attrs
, DSDB_SEARCH_SEARCH_ALL_PARTITIONS
,
128 "(&(objectClass=dnsZone)(name=%s))", zone_name
);
129 if (ret
!= LDB_SUCCESS
) {
130 torture_comment(tctx
,
131 "Failed to search for %s: %s",
133 ldb_errstring(samdb
));
134 return ISC_R_FAILURE
;
138 calls_zone_hook
= true;
140 return ISC_R_SUCCESS
;
143 static bool test_dlz_bind9_configure(struct torture_context
*tctx
)
146 dns_dlzdb_t
*dlzdb
= NULL
;
148 const char *argv
[] = {
151 dlz_bind9_binddns_dir(tctx
, "dns/sam.ldb"),
155 ret
= dlz_create("samba_dlz", 3, argv
, &dbdata
,
156 "log", dlz_bind9_log_wrapper
,
157 "writeable_zone", dlz_bind9_writeable_zone_hook
,
159 torture_assert_int_equal(tctx
,
162 "Failed to create samba_dlz");
164 calls_zone_hook
= false;
165 torture_assert_int_equal(tctx
, dlz_configure((void*)tctx
,
169 "Failed to configure samba_dlz");
173 torture_assert_int_equal(tctx
, calls_zone_hook
, 1, "Hasn't called zone hook");
178 static bool test_dlz_bind9_multiple_configure(struct torture_context
*tctx
)
181 for(i
= 0; i
< NUM_DLZS_TO_CONFIGURE
; i
++){
182 test_dlz_bind9_configure(tctx
);
187 static bool configure_multiple_dlzs(struct torture_context
*tctx
,
188 void **dbdata
, int count
)
191 dns_dlzdb_t
*dlzdb
= NULL
;
192 const char *argv
[] = {
195 dlz_bind9_binddns_dir(tctx
, "dns/sam.ldb"),
200 for(i
= 0; i
< count
; i
++){
201 res
= dlz_create("samba_dlz", 3, argv
, &(dbdata
[i
]),
202 "log", dlz_bind9_log_wrapper
,
204 dlz_bind9_writeable_zone_hook
, NULL
);
205 torture_assert_int_equal(tctx
, res
, ISC_R_SUCCESS
,
206 "Failed to create samba_dlz");
208 res
= dlz_configure((void*)tctx
, dlzdb
, dbdata
[i
]);
209 torture_assert_int_equal(tctx
, res
, ISC_R_SUCCESS
,
210 "Failed to configure samba_dlz");
216 static bool test_dlz_bind9_destroy_oldest_first(struct torture_context
*tctx
)
218 void *dbdata
[NUM_DLZS_TO_CONFIGURE
];
220 bool ret
= configure_multiple_dlzs(tctx
,
222 NUM_DLZS_TO_CONFIGURE
);
224 /* failure: has already been printed */
228 /* Reload faults are reported to happen on the first destroy */
229 dlz_destroy(dbdata
[0]);
231 for(i
= 1; i
< NUM_DLZS_TO_CONFIGURE
; i
++){
232 dlz_destroy(dbdata
[i
]);
238 static bool test_dlz_bind9_destroy_newest_first(struct torture_context
*tctx
)
240 void *dbdata
[NUM_DLZS_TO_CONFIGURE
];
242 bool ret
= configure_multiple_dlzs(tctx
,
244 NUM_DLZS_TO_CONFIGURE
);
246 /* failure: has already been printed */
250 for(i
= NUM_DLZS_TO_CONFIGURE
- 1; i
>= 0; i
--) {
251 dlz_destroy(dbdata
[i
]);
258 * Test that a ticket obtained for the DNS service will be accepted on the Samba DLZ side
261 static bool test_dlz_bind9_gensec(struct torture_context
*tctx
, const char *mech
)
264 dns_dlzdb_t
*dlzdb
= NULL
;
266 struct gensec_security
*gensec_client_context
;
268 DATA_BLOB client_to_server
, server_to_client
;
271 const char *argv
[] = {
274 dlz_bind9_binddns_dir(tctx
, "dns/sam.ldb"),
278 torture_assert_int_equal(tctx
, dlz_create("samba_dlz", 3, argv
, &dbdata
,
279 "log", dlz_bind9_log_wrapper
,
280 "writeable_zone", dlz_bind9_writeable_zone_hook
, NULL
),
282 "Failed to create samba_dlz");
284 torture_assert_int_equal(tctx
, dlz_configure((void*)tctx
,
287 "Failed to configure samba_dlz");
289 status
= gensec_client_start(tctx
, &gensec_client_context
,
290 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
));
291 torture_assert_ntstatus_ok(tctx
, status
, "gensec_client_start (client) failed");
294 * dlz_bind9 use the special dns/host.domain account
296 status
= gensec_set_target_hostname(gensec_client_context
,
297 talloc_asprintf(tctx
,
299 torture_setting_string(tctx
, "host", NULL
),
300 lpcfg_dnsdomain(tctx
->lp_ctx
)));
301 torture_assert_ntstatus_ok(tctx
, status
, "gensec_set_target_hostname (client) failed");
303 status
= gensec_set_target_service(gensec_client_context
, "dns");
304 torture_assert_ntstatus_ok(tctx
, status
, "gensec_set_target_service failed");
306 status
= gensec_set_credentials(gensec_client_context
,
307 samba_cmdline_get_creds());
308 torture_assert_ntstatus_ok(tctx
, status
, "gensec_set_credentials (client) failed");
310 status
= gensec_start_mech_by_sasl_name(gensec_client_context
, mech
);
311 torture_assert_ntstatus_ok(tctx
, status
, "gensec_start_mech_by_sasl_name (client) failed");
313 server_to_client
= data_blob(NULL
, 0);
315 /* Do one step of the client-server update dance */
316 status
= gensec_update(gensec_client_context
, tctx
, server_to_client
, &client_to_server
);
317 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {;
318 torture_assert_ntstatus_ok(tctx
, status
, "gensec_update (client) failed");
321 torture_assert_int_equal(tctx
, dlz_ssumatch(
322 cli_credentials_get_username(
323 samba_cmdline_get_creds()),
324 lpcfg_dnsdomain(tctx
->lp_ctx
),
325 "127.0.0.1", "type", "key",
326 client_to_server
.length
,
327 client_to_server
.data
,
330 "Failed to check key for update rights samba_dlz");
337 static bool test_dlz_bind9_gssapi(struct torture_context
*tctx
)
339 return test_dlz_bind9_gensec(tctx
, "GSSAPI");
342 static bool test_dlz_bind9_spnego(struct torture_context
*tctx
)
344 return test_dlz_bind9_gensec(tctx
, "GSS-SPNEGO");
347 struct test_expected_record
{
356 struct test_expected_rr
{
357 struct torture_context
*tctx
;
358 const char *query_name
;
360 struct test_expected_record
*records
;
364 static bool dlz_bind9_putnamedrr_torture_hook(struct test_expected_rr
*expected
,
372 torture_assert(expected
->tctx
, name
!= NULL
,
373 talloc_asprintf(expected
->tctx
,
374 "Got unnamed record type[%s] data[%s]\n",
378 torture_comment(expected
->tctx
, "%u: name[%s] type[%s] ttl[%u] data[%s]\n",
379 (unsigned)expected
->num_rr
, name
, type
, (unsigned)ttl
, data
);
381 for (i
= 0; i
< expected
->num_records
; i
++) {
382 if (expected
->records
[i
].name
!= NULL
) {
383 if (strcmp(name
, expected
->records
[i
].name
) != 0) {
388 if (strcmp(type
, expected
->records
[i
].type
) != 0) {
392 if (expected
->records
[i
].data
!= NULL
) {
394 * For most types the data will have been reformatted
395 * or normalised, so we need to do approximately the
398 const char *data2
= expected
->records
[i
].data
;
399 if (strcmp(type
, "aaaa") == 0) {
400 struct in6_addr adr1
;
401 struct in6_addr adr2
;
403 ret
= inet_pton(AF_INET6
, data
, &adr1
);
407 ret
= inet_pton(AF_INET6
, data2
, &adr2
);
411 if (memcmp(&adr1
, &adr2
, sizeof(adr1
)) != 0) {
414 } else if (strcmp(type
, "cname") == 0 ||
415 strcmp(type
, "ptr") == 0 ||
416 strcmp(type
, "ns") == 0) {
417 if (!samba_dns_name_equal(data
, data2
)) {
420 } else if (strcmp(type
, "mx") == 0) {
422 * samba_dns_name_equal works for MX records
423 * because the space in "10 example.com." is
424 * theoretically OK as a DNS character. And we
425 * need it because dlz will add the trailing
428 if (!samba_dns_name_equal(data
, data2
)) {
431 } else if (strcmp(data
, data2
) != 0) {
432 /* default, works for A records */
437 torture_assert_int_equal(expected
->tctx
, ttl
,
438 expected
->records
[i
].ttl
,
439 talloc_asprintf(expected
->tctx
,
440 "TTL did not match expectations for type %s",
443 expected
->records
[i
].printed
= true;
450 * Lookups in these tests end up coming round to run this function.
452 static isc_result_t
dlz_bind9_putrr_hook(dns_sdlzlookup_t
*lookup
,
457 struct test_expected_rr
*expected
=
458 talloc_get_type_abort(lookup
, struct test_expected_rr
);
461 ok
= dlz_bind9_putnamedrr_torture_hook(expected
, expected
->query_name
,
464 return ISC_R_FAILURE
;
467 return ISC_R_SUCCESS
;
470 static isc_result_t
dlz_bind9_putnamedrr_hook(dns_sdlzallnodes_t
*allnodes
,
476 struct test_expected_rr
*expected
=
477 talloc_get_type_abort(allnodes
, struct test_expected_rr
);
480 ok
= dlz_bind9_putnamedrr_torture_hook(expected
, name
, type
, ttl
, data
);
482 return ISC_R_FAILURE
;
485 return ISC_R_SUCCESS
;
491 static bool test_dlz_bind9_lookup(struct torture_context
*tctx
)
495 dns_clientinfomethods_t
*methods
= NULL
;
496 dns_clientinfo_t
*clientinfo
= NULL
;
497 dns_dlzdb_t
*dlzdb
= NULL
;
498 const char *argv
[] = {
501 dlz_bind9_binddns_dir(tctx
, "dns/sam.ldb"),
504 struct test_expected_rr
*expected1
= NULL
;
505 struct test_expected_rr
*expected2
= NULL
;
508 torture_assert_int_equal(tctx
, dlz_create("samba_dlz", 3, argv
, &dbdata
,
509 "log", dlz_bind9_log_wrapper
,
510 "writeable_zone", dlz_bind9_writeable_zone_hook
,
511 "putrr", dlz_bind9_putrr_hook
,
512 "putnamedrr", dlz_bind9_putnamedrr_hook
,
515 "Failed to create samba_dlz");
517 torture_assert_int_equal(tctx
,
518 dlz_configure((void*)tctx
, dlzdb
, dbdata
),
520 "Failed to configure samba_dlz");
522 expected1
= talloc_zero(tctx
, struct test_expected_rr
);
523 torture_assert(tctx
, expected1
!= NULL
, "talloc failed");
524 expected1
->tctx
= tctx
;
526 expected1
->query_name
= "@";
528 expected1
->num_records
= 4;
529 expected1
->records
= talloc_zero_array(expected1
,
530 struct test_expected_record
,
531 expected1
->num_records
);
532 torture_assert(tctx
, expected1
->records
!= NULL
, "talloc failed");
534 expected1
->records
[0].name
= expected1
->query_name
;
535 expected1
->records
[0].type
= "soa";
536 expected1
->records
[0].ttl
= 3600;
537 expected1
->records
[0].data
= talloc_asprintf(expected1
->records
,
538 "%s.%s. hostmaster.%s. 1 900 600 86400 3600",
539 torture_setting_string(tctx
, "host", NULL
),
540 lpcfg_dnsdomain(tctx
->lp_ctx
),
541 lpcfg_dnsdomain(tctx
->lp_ctx
));
542 torture_assert(tctx
, expected1
->records
[0].data
!= NULL
, "talloc failed");
544 expected1
->records
[1].name
= expected1
->query_name
;
545 expected1
->records
[1].type
= "ns";
546 expected1
->records
[1].ttl
= 900;
547 expected1
->records
[1].data
= talloc_asprintf(expected1
->records
, "%s.%s.",
548 torture_setting_string(tctx
, "host", NULL
),
549 lpcfg_dnsdomain(tctx
->lp_ctx
));
550 torture_assert(tctx
, expected1
->records
[1].data
!= NULL
, "talloc failed");
552 expected1
->records
[2].name
= expected1
->query_name
;
553 expected1
->records
[2].type
= "aaaa";
554 expected1
->records
[2].ttl
= 900;
556 expected1
->records
[3].name
= expected1
->query_name
;
557 expected1
->records
[3].type
= "a";
558 expected1
->records
[3].ttl
= 900;
560 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
561 expected1
->query_name
, dbdata
,
562 (dns_sdlzlookup_t
*)expected1
,
563 methods
, clientinfo
),
565 "Failed to lookup @");
566 for (i
= 0; i
< expected1
->num_records
; i
++) {
567 torture_assert(tctx
, expected1
->records
[i
].printed
,
568 talloc_asprintf(tctx
,
569 "Failed to have putrr callback run for type %s",
570 expected1
->records
[i
].type
));
572 torture_assert_int_equal(tctx
, expected1
->num_rr
,
573 expected1
->num_records
,
574 "Got too much data");
576 expected2
= talloc_zero(tctx
, struct test_expected_rr
);
577 torture_assert(tctx
, expected2
!= NULL
, "talloc failed");
578 expected2
->tctx
= tctx
;
580 expected2
->query_name
= torture_setting_string(tctx
, "host", NULL
);
581 torture_assert(tctx
, expected2
->query_name
!= NULL
, "unknown host");
583 expected2
->num_records
= 2;
584 expected2
->records
= talloc_zero_array(expected2
,
585 struct test_expected_record
,
586 expected2
->num_records
);
587 torture_assert(tctx
, expected2
->records
!= NULL
, "talloc failed");
589 expected2
->records
[0].name
= expected2
->query_name
;
590 expected2
->records
[0].type
= "aaaa";
591 expected2
->records
[0].ttl
= 900;
593 expected2
->records
[1].name
= expected2
->query_name
;
594 expected2
->records
[1].type
= "a";
595 expected2
->records
[1].ttl
= 900;
597 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
598 expected2
->query_name
, dbdata
,
599 (dns_sdlzlookup_t
*)expected2
,
600 methods
, clientinfo
),
602 "Failed to lookup hostname");
603 for (i
= 0; i
< expected2
->num_records
; i
++) {
604 torture_assert(tctx
, expected2
->records
[i
].printed
,
605 talloc_asprintf(tctx
,
606 "Failed to have putrr callback run name[%s] for type %s",
607 expected2
->records
[i
].name
,
608 expected2
->records
[i
].type
));
610 torture_assert_int_equal(tctx
, expected2
->num_rr
,
611 expected2
->num_records
,
612 "Got too much data");
620 * Test some zone dumps
622 static bool test_dlz_bind9_zonedump(struct torture_context
*tctx
)
626 dns_dlzdb_t
*dlzdb
= NULL
;
627 const char *argv
[] = {
630 dlz_bind9_binddns_dir(tctx
, "dns/sam.ldb"),
633 struct test_expected_rr
*expected1
= NULL
;
636 torture_assert_int_equal(tctx
, dlz_create("samba_dlz", 3, argv
, &dbdata
,
637 "log", dlz_bind9_log_wrapper
,
638 "writeable_zone", dlz_bind9_writeable_zone_hook
,
639 "putrr", dlz_bind9_putrr_hook
,
640 "putnamedrr", dlz_bind9_putnamedrr_hook
,
643 "Failed to create samba_dlz");
645 torture_assert_int_equal(tctx
, dlz_configure((void*)tctx
, dlzdb
, dbdata
),
647 "Failed to configure samba_dlz");
649 expected1
= talloc_zero(tctx
, struct test_expected_rr
);
650 torture_assert(tctx
, expected1
!= NULL
, "talloc failed");
651 expected1
->tctx
= tctx
;
653 expected1
->num_records
= 7;
654 expected1
->records
= talloc_zero_array(expected1
,
655 struct test_expected_record
,
656 expected1
->num_records
);
657 torture_assert(tctx
, expected1
->records
!= NULL
, "talloc failed");
659 expected1
->records
[0].name
= talloc_asprintf(expected1
->records
,
660 "%s.", lpcfg_dnsdomain(tctx
->lp_ctx
));
661 expected1
->records
[0].type
= "soa";
662 expected1
->records
[0].ttl
= 3600;
663 expected1
->records
[0].data
= talloc_asprintf(expected1
->records
,
664 "%s.%s. hostmaster.%s. 1 900 600 86400 3600",
665 torture_setting_string(tctx
, "host", NULL
),
666 lpcfg_dnsdomain(tctx
->lp_ctx
),
667 lpcfg_dnsdomain(tctx
->lp_ctx
));
668 torture_assert(tctx
, expected1
->records
[0].data
!= NULL
, "talloc failed");
670 expected1
->records
[1].name
= talloc_asprintf(expected1
->records
,
671 "%s.", lpcfg_dnsdomain(tctx
->lp_ctx
));
672 expected1
->records
[1].type
= "ns";
673 expected1
->records
[1].ttl
= 900;
674 expected1
->records
[1].data
= talloc_asprintf(expected1
->records
, "%s.%s.",
675 torture_setting_string(tctx
, "host", NULL
),
676 lpcfg_dnsdomain(tctx
->lp_ctx
));
677 torture_assert(tctx
, expected1
->records
[1].data
!= NULL
, "talloc failed");
679 expected1
->records
[2].name
= talloc_asprintf(expected1
->records
,
680 "%s.", lpcfg_dnsdomain(tctx
->lp_ctx
));
681 expected1
->records
[2].type
= "aaaa";
682 expected1
->records
[2].ttl
= 900;
684 expected1
->records
[3].name
= talloc_asprintf(expected1
->records
,
685 "%s.", lpcfg_dnsdomain(tctx
->lp_ctx
));
686 expected1
->records
[3].type
= "a";
687 expected1
->records
[3].ttl
= 900;
689 expected1
->records
[4].name
= talloc_asprintf(expected1
->records
, "%s.%s.",
690 torture_setting_string(tctx
, "host", NULL
),
691 lpcfg_dnsdomain(tctx
->lp_ctx
));
692 torture_assert(tctx
, expected1
->records
[4].name
!= NULL
, "unknown host");
693 expected1
->records
[4].type
= "aaaa";
694 expected1
->records
[4].ttl
= 900;
696 expected1
->records
[5].name
= talloc_asprintf(expected1
->records
, "%s.%s.",
697 torture_setting_string(tctx
, "host", NULL
),
698 lpcfg_dnsdomain(tctx
->lp_ctx
));
699 torture_assert(tctx
, expected1
->records
[5].name
!= NULL
, "unknown host");
700 expected1
->records
[5].type
= "a";
701 expected1
->records
[5].ttl
= 900;
704 * We expect multiple srv records
706 expected1
->records
[6].name
= NULL
;
707 expected1
->records
[6].type
= "srv";
708 expected1
->records
[6].ttl
= 900;
710 torture_assert_int_equal(tctx
, dlz_allnodes(lpcfg_dnsdomain(tctx
->lp_ctx
),
711 dbdata
, (dns_sdlzallnodes_t
*)expected1
),
713 "Failed to configure samba_dlz");
714 for (i
= 0; i
< expected1
->num_records
; i
++) {
715 torture_assert(tctx
, expected1
->records
[i
].printed
,
716 talloc_asprintf(tctx
,
717 "Failed to have putrr callback run name[%s] for type %s",
718 expected1
->records
[i
].name
,
719 expected1
->records
[i
].type
));
721 torture_assert_int_equal(tctx
, expected1
->num_rr
, 24,
722 "Got wrong record count");
732 static bool test_dlz_bind9_update01(struct torture_context
*tctx
)
735 struct gensec_security
*gensec_client_context
;
736 DATA_BLOB client_to_server
, server_to_client
;
738 dns_dlzdb_t
*dlzdb
= NULL
;
739 void *version
= NULL
;
740 const char *argv
[] = {
743 dlz_bind9_binddns_dir(tctx
, "dns/sam.ldb"),
746 struct test_expected_rr
*expected1
= NULL
;
752 dns_clientinfomethods_t
*methods
= NULL
;
753 dns_clientinfo_t
*clientinfo
= NULL
;
756 torture_assert_int_equal(tctx
, dlz_create("samba_dlz", 3, argv
, &dbdata
,
757 "log", dlz_bind9_log_wrapper
,
758 "writeable_zone", dlz_bind9_writeable_zone_hook
,
759 "putrr", dlz_bind9_putrr_hook
,
760 "putnamedrr", dlz_bind9_putnamedrr_hook
,
763 "Failed to create samba_dlz");
765 torture_assert_int_equal(tctx
, dlz_configure((void*)tctx
, dlzdb
, dbdata
),
767 "Failed to configure samba_dlz");
769 expected1
= talloc_zero(tctx
, struct test_expected_rr
);
770 torture_assert(tctx
, expected1
!= NULL
, "talloc failed");
771 expected1
->tctx
= tctx
;
773 expected1
->query_name
= __func__
;
775 name
= talloc_asprintf(expected1
, "%s.%s",
776 expected1
->query_name
,
777 lpcfg_dnsdomain(tctx
->lp_ctx
));
778 torture_assert(tctx
, name
!= NULL
, "talloc failed");
780 expected1
->num_records
= 2;
781 expected1
->records
= talloc_zero_array(expected1
,
782 struct test_expected_record
,
783 expected1
->num_records
);
784 torture_assert(tctx
, expected1
->records
!= NULL
, "talloc failed");
786 expected1
->records
[0].name
= expected1
->query_name
;
787 expected1
->records
[0].type
= "a";
788 expected1
->records
[0].ttl
= 3600;
789 expected1
->records
[0].data
= "127.1.2.3";
790 expected1
->records
[0].printed
= false;
792 data0
= talloc_asprintf(expected1
,
793 "%s.\t" "%u\t" "%s\t" "%s\t" "%s",
795 (unsigned)expected1
->records
[0].ttl
,
797 expected1
->records
[0].type
,
798 expected1
->records
[0].data
);
799 torture_assert(tctx
, data0
!= NULL
, "talloc failed");
801 expected1
->records
[1].name
= expected1
->query_name
;
802 expected1
->records
[1].type
= "a";
803 expected1
->records
[1].ttl
= 3600;
804 expected1
->records
[1].data
= "127.3.2.1";
805 expected1
->records
[1].printed
= false;
807 data1
= talloc_asprintf(expected1
,
808 "%s.\t" "%u\t" "%s\t" "%s\t" "%s",
810 (unsigned)expected1
->records
[1].ttl
,
812 expected1
->records
[1].type
,
813 expected1
->records
[1].data
);
814 torture_assert(tctx
, data1
!= NULL
, "talloc failed");
816 data2
= talloc_asprintf(expected1
,
817 "%s.\t" "0\t" "in\t" "a\t" "127.3.3.3",
819 torture_assert(tctx
, data2
!= NULL
, "talloc failed");
822 * Prepare session info
824 status
= gensec_client_start(tctx
, &gensec_client_context
,
825 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
));
826 torture_assert_ntstatus_ok(tctx
, status
, "gensec_client_start (client) failed");
829 * dlz_bind9 use the special dns/host.domain account
831 status
= gensec_set_target_hostname(gensec_client_context
,
832 talloc_asprintf(tctx
,
834 torture_setting_string(tctx
, "host", NULL
),
835 lpcfg_dnsdomain(tctx
->lp_ctx
)));
836 torture_assert_ntstatus_ok(tctx
, status
, "gensec_set_target_hostname (client) failed");
838 status
= gensec_set_target_service(gensec_client_context
, "dns");
839 torture_assert_ntstatus_ok(tctx
, status
, "gensec_set_target_service failed");
841 status
= gensec_set_credentials(gensec_client_context
,
842 samba_cmdline_get_creds());
843 torture_assert_ntstatus_ok(tctx
, status
, "gensec_set_credentials (client) failed");
845 status
= gensec_start_mech_by_sasl_name(gensec_client_context
, "GSS-SPNEGO");
846 torture_assert_ntstatus_ok(tctx
, status
, "gensec_start_mech_by_sasl_name (client) failed");
848 server_to_client
= data_blob(NULL
, 0);
850 /* Do one step of the client-server update dance */
851 status
= gensec_update(gensec_client_context
, tctx
, server_to_client
, &client_to_server
);
852 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {;
853 torture_assert_ntstatus_ok(tctx
, status
, "gensec_update (client) failed");
856 torture_assert_int_equal(tctx
, dlz_ssumatch(
857 cli_credentials_get_username(
858 samba_cmdline_get_creds()),
861 expected1
->records
[0].type
,
863 client_to_server
.length
,
864 client_to_server
.data
,
867 "Failed to check key for update rights samba_dlz");
870 * We test the following:
872 * 1. lookup the records => NOT_FOUND
873 * 2. delete all records => NOT_FOUND
874 * 3. delete 1st record => NOT_FOUND
875 * 4. create 1st record => SUCCESS
876 * 5. lookup the records => found 1st
877 * 6. create 2nd record => SUCCESS
878 * 7. lookup the records => found 1st and 2nd
879 * 8. delete unknown record => NOT_FOUND
880 * 9. lookup the records => found 1st and 2nd
881 * 10. delete 1st record => SUCCESS
882 * 11. lookup the records => found 2nd
883 * 12. delete 2nd record => SUCCESS
884 * 13. lookup the records => NOT_FOUND
885 * 14. create 1st record => SUCCESS
886 * 15. lookup the records => found 1st
887 * 16. create 2nd record => SUCCESS
888 * 17. lookup the records => found 1st and 2nd
889 * 18. update 1st record => SUCCESS
890 * 19. lookup the records => found 1st and 2nd
891 * 20. delete all unknown type records => NOT_FOUND
892 * 21. lookup the records => found 1st and 2nd
893 * 22. delete all records => SUCCESS
894 * 23. lookup the records => NOT_FOUND
898 expected1
->num_rr
= 0;
899 expected1
->records
[0].printed
= false;
900 expected1
->records
[1].printed
= false;
901 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
902 expected1
->query_name
, dbdata
,
903 (dns_sdlzlookup_t
*)expected1
,
904 methods
, clientinfo
),
907 torture_assert_int_equal(tctx
, expected1
->num_rr
, 0,
908 "Got wrong record count");
911 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
914 "Failed to start transaction");
915 torture_assert_int_equal_goto(tctx
,
916 dlz_delrdataset(name
,
917 expected1
->records
[0].type
,
919 ISC_R_NOTFOUND
, ret
, cancel_version
,
920 talloc_asprintf(tctx
, "Deleted name[%s] type[%s]\n",
921 name
, expected1
->records
[0].type
));
922 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), false, dbdata
, &version
);
925 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
928 "Failed to start transaction");
929 torture_assert_int_equal_goto(tctx
,
930 dlz_subrdataset(name
, data0
, dbdata
, version
),
931 ISC_R_NOTFOUND
, ret
, cancel_version
,
932 talloc_asprintf(tctx
, "Deleted name[%s] data[%s]\n",
934 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), false, dbdata
, &version
);
937 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
940 "Failed to start transaction");
941 torture_assert_int_equal_goto(tctx
,
942 dlz_addrdataset(name
, data0
, dbdata
, version
),
943 ISC_R_SUCCESS
, ret
, cancel_version
,
944 talloc_asprintf(tctx
, "Failed to add name[%s] data[%s]\n",
946 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), true, dbdata
, &version
);
949 expected1
->num_rr
= 0;
950 expected1
->records
[0].printed
= false;
951 expected1
->records
[1].printed
= false;
952 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
953 expected1
->query_name
, dbdata
,
954 (dns_sdlzlookup_t
*)expected1
,
955 methods
, clientinfo
),
957 "Not found hostname");
958 torture_assert(tctx
, expected1
->records
[0].printed
,
959 talloc_asprintf(tctx
,
960 "Failed to have putrr callback run name[%s] for type %s",
961 expected1
->records
[0].name
,
962 expected1
->records
[0].type
));
963 torture_assert_int_equal(tctx
, expected1
->num_rr
, 1,
964 "Got wrong record count");
967 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
970 "Failed to start transaction");
971 torture_assert_int_equal_goto(tctx
,
972 dlz_addrdataset(name
, data1
, dbdata
, version
),
973 ISC_R_SUCCESS
, ret
, cancel_version
,
974 talloc_asprintf(tctx
, "Failed to add name[%s] data[%s]\n",
976 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), true, dbdata
, &version
);
979 expected1
->num_rr
= 0;
980 expected1
->records
[0].printed
= false;
981 expected1
->records
[1].printed
= false;
982 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
983 expected1
->query_name
, dbdata
,
984 (dns_sdlzlookup_t
*)expected1
,
985 methods
, clientinfo
),
987 "Not found hostname");
988 torture_assert(tctx
, expected1
->records
[0].printed
,
989 talloc_asprintf(tctx
,
990 "Failed to have putrr callback run name[%s] for type %s",
991 expected1
->records
[0].name
,
992 expected1
->records
[0].type
));
993 torture_assert(tctx
, expected1
->records
[1].printed
,
994 talloc_asprintf(tctx
,
995 "Failed to have putrr callback run name[%s] for type %s",
996 expected1
->records
[1].name
,
997 expected1
->records
[1].type
));
998 torture_assert_int_equal(tctx
, expected1
->num_rr
, 2,
999 "Got wrong record count");
1002 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
1005 "Failed to start transaction");
1006 torture_assert_int_equal_goto(tctx
,
1007 dlz_subrdataset(name
, data2
, dbdata
, version
),
1008 ISC_R_NOTFOUND
, ret
, cancel_version
,
1009 talloc_asprintf(tctx
, "Deleted name[%s] data[%s]\n",
1011 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), true, dbdata
, &version
);
1014 expected1
->num_rr
= 0;
1015 expected1
->records
[0].printed
= false;
1016 expected1
->records
[1].printed
= false;
1017 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
1018 expected1
->query_name
, dbdata
,
1019 (dns_sdlzlookup_t
*)expected1
,
1020 methods
, clientinfo
),
1022 "Not found hostname");
1023 torture_assert(tctx
, expected1
->records
[0].printed
,
1024 talloc_asprintf(tctx
,
1025 "Failed to have putrr callback run name[%s] for type %s",
1026 expected1
->records
[0].name
,
1027 expected1
->records
[0].type
));
1028 torture_assert(tctx
, expected1
->records
[1].printed
,
1029 talloc_asprintf(tctx
,
1030 "Failed to have putrr callback run name[%s] for type %s",
1031 expected1
->records
[1].name
,
1032 expected1
->records
[1].type
));
1033 torture_assert_int_equal(tctx
, expected1
->num_rr
, 2,
1034 "Got wrong record count");
1037 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
1040 "Failed to start transaction");
1041 torture_assert_int_equal_goto(tctx
,
1042 dlz_subrdataset(name
, data0
, dbdata
, version
),
1043 ISC_R_SUCCESS
, ret
, cancel_version
,
1044 talloc_asprintf(tctx
, "Failed to delete name[%s] data[%s]\n",
1046 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), true, dbdata
, &version
);
1049 expected1
->num_rr
= 0;
1050 expected1
->records
[0].printed
= false;
1051 expected1
->records
[1].printed
= false;
1052 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
1053 expected1
->query_name
, dbdata
,
1054 (dns_sdlzlookup_t
*)expected1
,
1055 methods
, clientinfo
),
1057 "Not found hostname");
1058 torture_assert(tctx
, expected1
->records
[1].printed
,
1059 talloc_asprintf(tctx
,
1060 "Failed to have putrr callback run name[%s] for type %s",
1061 expected1
->records
[1].name
,
1062 expected1
->records
[1].type
));
1063 torture_assert_int_equal(tctx
, expected1
->num_rr
, 1,
1064 "Got wrong record count");
1067 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
1070 "Failed to start transaction");
1071 torture_assert_int_equal_goto(tctx
,
1072 dlz_subrdataset(name
, data1
, dbdata
, version
),
1073 ISC_R_SUCCESS
, ret
, cancel_version
,
1074 talloc_asprintf(tctx
, "Failed to delete name[%s] data[%s]\n",
1076 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), true, dbdata
, &version
);
1079 expected1
->num_rr
= 0;
1080 expected1
->records
[0].printed
= false;
1081 expected1
->records
[1].printed
= false;
1082 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
1083 expected1
->query_name
, dbdata
,
1084 (dns_sdlzlookup_t
*)expected1
,
1085 methods
, clientinfo
),
1088 torture_assert_int_equal(tctx
, expected1
->num_rr
, 0,
1089 "Got wrong record count");
1092 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
1095 "Failed to start transaction");
1096 torture_assert_int_equal_goto(tctx
,
1097 dlz_addrdataset(name
, data0
, dbdata
, version
),
1098 ISC_R_SUCCESS
, ret
, cancel_version
,
1099 talloc_asprintf(tctx
, "Failed to add name[%s] data[%s]\n",
1101 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), true, dbdata
, &version
);
1104 expected1
->num_rr
= 0;
1105 expected1
->records
[0].printed
= false;
1106 expected1
->records
[1].printed
= false;
1107 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
1108 expected1
->query_name
, dbdata
,
1109 (dns_sdlzlookup_t
*)expected1
,
1110 methods
, clientinfo
),
1112 "Not found hostname");
1113 torture_assert(tctx
, expected1
->records
[0].printed
,
1114 talloc_asprintf(tctx
,
1115 "Failed to have putrr callback run name[%s] for type %s",
1116 expected1
->records
[0].name
,
1117 expected1
->records
[0].type
));
1118 torture_assert_int_equal(tctx
, expected1
->num_rr
, 1,
1119 "Got wrong record count");
1122 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
1125 "Failed to start transaction");
1126 torture_assert_int_equal_goto(tctx
,
1127 dlz_addrdataset(name
, data1
, dbdata
, version
),
1128 ISC_R_SUCCESS
, ret
, cancel_version
,
1129 talloc_asprintf(tctx
, "Failed to add name[%s] data[%s]\n",
1131 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), true, dbdata
, &version
);
1134 expected1
->num_rr
= 0;
1135 expected1
->records
[0].printed
= false;
1136 expected1
->records
[1].printed
= false;
1137 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
1138 expected1
->query_name
, dbdata
,
1139 (dns_sdlzlookup_t
*)expected1
,
1140 methods
, clientinfo
),
1142 "Not found hostname");
1143 torture_assert(tctx
, expected1
->records
[0].printed
,
1144 talloc_asprintf(tctx
,
1145 "Failed to have putrr callback run name[%s] for type %s",
1146 expected1
->records
[0].name
,
1147 expected1
->records
[0].type
));
1148 torture_assert(tctx
, expected1
->records
[1].printed
,
1149 talloc_asprintf(tctx
,
1150 "Failed to have putrr callback run name[%s] for type %s",
1151 expected1
->records
[1].name
,
1152 expected1
->records
[1].type
));
1153 torture_assert_int_equal(tctx
, expected1
->num_rr
, 2,
1154 "Got wrong record count");
1157 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
1160 "Failed to start transaction");
1161 torture_assert_int_equal_goto(tctx
,
1162 dlz_addrdataset(name
, data0
, dbdata
, version
),
1163 ISC_R_SUCCESS
, ret
, cancel_version
,
1164 talloc_asprintf(tctx
, "Failed to update name[%s] data[%s]\n",
1166 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), true, dbdata
, &version
);
1169 expected1
->num_rr
= 0;
1170 expected1
->records
[0].printed
= false;
1171 expected1
->records
[1].printed
= false;
1172 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
1173 expected1
->query_name
, dbdata
,
1174 (dns_sdlzlookup_t
*)expected1
,
1175 methods
, clientinfo
),
1177 "Not found hostname");
1178 torture_assert(tctx
, expected1
->records
[0].printed
,
1179 talloc_asprintf(tctx
,
1180 "Failed to have putrr callback run name[%s] for type %s",
1181 expected1
->records
[0].name
,
1182 expected1
->records
[0].type
));
1183 torture_assert(tctx
, expected1
->records
[1].printed
,
1184 talloc_asprintf(tctx
,
1185 "Failed to have putrr callback run name[%s] for type %s",
1186 expected1
->records
[1].name
,
1187 expected1
->records
[1].type
));
1188 torture_assert_int_equal(tctx
, expected1
->num_rr
, 2,
1189 "Got wrong record count");
1192 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
1195 "Failed to start transaction");
1196 torture_assert_int_equal_goto(tctx
,
1197 dlz_delrdataset(name
, "txt", dbdata
, version
),
1198 ISC_R_FAILURE
, ret
, cancel_version
,
1199 talloc_asprintf(tctx
, "Deleted name[%s] type[%s]\n",
1201 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), false, dbdata
, &version
);
1204 expected1
->num_rr
= 0;
1205 expected1
->records
[0].printed
= false;
1206 expected1
->records
[1].printed
= false;
1207 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
1208 expected1
->query_name
, dbdata
,
1209 (dns_sdlzlookup_t
*)expected1
,
1210 methods
, clientinfo
),
1212 "Not found hostname");
1213 torture_assert(tctx
, expected1
->records
[0].printed
,
1214 talloc_asprintf(tctx
,
1215 "Failed to have putrr callback run name[%s] for type %s",
1216 expected1
->records
[0].name
,
1217 expected1
->records
[0].type
));
1218 torture_assert(tctx
, expected1
->records
[1].printed
,
1219 talloc_asprintf(tctx
,
1220 "Failed to have putrr callback run name[%s] for type %s",
1221 expected1
->records
[1].name
,
1222 expected1
->records
[1].type
));
1223 torture_assert_int_equal(tctx
, expected1
->num_rr
, 2,
1224 "Got wrong record count");
1227 torture_assert_int_equal(tctx
, dlz_newversion(lpcfg_dnsdomain(tctx
->lp_ctx
),
1230 "Failed to start transaction");
1231 torture_assert_int_equal_goto(tctx
,
1232 dlz_delrdataset(name
,
1233 expected1
->records
[0].type
,
1235 ISC_R_SUCCESS
, ret
, cancel_version
,
1236 talloc_asprintf(tctx
, "Failed to delete name[%s] type[%s]\n",
1237 name
, expected1
->records
[0].type
));
1238 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), true, dbdata
, &version
);
1241 expected1
->num_rr
= 0;
1242 expected1
->records
[0].printed
= false;
1243 expected1
->records
[1].printed
= false;
1244 torture_assert_int_equal(tctx
, dlz_lookup(lpcfg_dnsdomain(tctx
->lp_ctx
),
1245 expected1
->query_name
, dbdata
,
1246 (dns_sdlzlookup_t
*)expected1
,
1247 methods
, clientinfo
),
1250 torture_assert_int_equal(tctx
, expected1
->num_rr
, 0,
1251 "Got wrong record count");
1253 dlz_destroy(dbdata
);
1258 dlz_closeversion(lpcfg_dnsdomain(tctx
->lp_ctx
), false, dbdata
, &version
);
1263 * Test zone transfer requests restrictions
1265 * 1: test that zone transfer is denied by default
1266 * 2: with an authorized list of IPs set in smb.conf, test that zone transfer
1267 * is accepted only for selected IPs.
1269 static bool test_dlz_bind9_allowzonexfr(struct torture_context
*tctx
)
1272 const char *argv
[] = {
1275 dlz_bind9_binddns_dir(tctx
, "dns/sam.ldb"),
1279 dns_dlzdb_t
*dlzdb
= NULL
;
1283 torture_assert_int_equal(tctx
, dlz_create("samba_dlz", 3, argv
, &dbdata
,
1284 "log", dlz_bind9_log_wrapper
,
1285 "writeable_zone", dlz_bind9_writeable_zone_hook
,
1286 "putrr", dlz_bind9_putrr_hook
,
1287 "putnamedrr", dlz_bind9_putnamedrr_hook
,
1290 "Failed to create samba_dlz");
1292 torture_assert_int_equal(tctx
, dlz_configure((void*)tctx
, dlzdb
, dbdata
),
1294 "Failed to configure samba_dlz");
1296 /* Ask for zone transfer with no specific config => expect denied */
1297 ret
= dlz_allowzonexfr(dbdata
, lpcfg_dnsdomain(tctx
->lp_ctx
), "127.0.0.1");
1298 torture_assert_int_equal(tctx
, ret
, ISC_R_NOPERM
,
1299 "Zone transfer accepted with default settings");
1301 /* Ask for zone transfer with authorizations set */
1302 ok
= lpcfg_set_option(tctx
->lp_ctx
, "dns zone transfer clients allow=127.0.0.1,1234:5678::1,192.168.0.");
1303 torture_assert(tctx
, ok
, "Failed to set dns zone transfer clients allow option.");
1305 ok
= lpcfg_set_option(tctx
->lp_ctx
, "dns zone transfer clients deny=192.168.0.2");
1306 torture_assert(tctx
, ok
, "Failed to set dns zone transfer clients deny option.");
1308 ret
= dlz_allowzonexfr(dbdata
, lpcfg_dnsdomain(tctx
->lp_ctx
), "127.0.0.1");
1309 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
1310 "Zone transfer refused for authorized IPv4 address");
1312 ret
= dlz_allowzonexfr(dbdata
, lpcfg_dnsdomain(tctx
->lp_ctx
), "1234:5678::1");
1313 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
1314 "Zone transfer refused for authorized IPv6 address.");
1316 ret
= dlz_allowzonexfr(dbdata
, lpcfg_dnsdomain(tctx
->lp_ctx
), "10.0.0.1");
1317 torture_assert_int_equal(tctx
, ret
, ISC_R_NOPERM
,
1318 "Zone transfer accepted for unauthorized IP");
1320 ret
= dlz_allowzonexfr(dbdata
, lpcfg_dnsdomain(tctx
->lp_ctx
), "192.168.0.1");
1321 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
1322 "Zone transfer refused for address in authorized IPv4 subnet.");
1324 ret
= dlz_allowzonexfr(dbdata
, lpcfg_dnsdomain(tctx
->lp_ctx
), "192.168.0.2");
1325 torture_assert_int_equal(tctx
, ret
, ISC_R_NOPERM
,
1326 "Zone transfer allowed for denied client.");
1328 dlz_destroy(dbdata
);
1333 static int init_dlz(struct torture_context
*tctx
,
1337 const char *argv
[] = {
1340 dlz_bind9_binddns_dir(tctx
, "dns/sam.ldb"),
1344 ret
= dlz_create("samba_dlz", 3, argv
, dbdata
,
1345 "log", dlz_bind9_log_wrapper
,
1346 "writeable_zone", dlz_bind9_writeable_zone_hook
,
1347 "putrr", dlz_bind9_putrr_hook
,
1348 "putnamedrr", dlz_bind9_putnamedrr_hook
,
1351 torture_assert_int_equal(tctx
,
1354 "Failed to create samba_dlz");
1356 ret
= dlz_configure((void*)tctx
, NULL
, *dbdata
);
1357 torture_assert_int_equal(tctx
,
1360 "Failed to configure samba_dlz");
1366 static int init_gensec(struct torture_context
*tctx
,
1367 struct gensec_security
**gensec_client_context
)
1371 * Prepare session info
1373 status
= gensec_client_start(tctx
, gensec_client_context
,
1374 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
));
1375 torture_assert_ntstatus_ok(tctx
, status
,
1376 "gensec_client_start (client) failed");
1379 * dlz_bind9 use the special dns/host.domain account
1381 status
= gensec_set_target_hostname(*gensec_client_context
,
1382 talloc_asprintf(tctx
,
1384 torture_setting_string(tctx
, "host", NULL
),
1385 lpcfg_dnsdomain(tctx
->lp_ctx
)));
1386 torture_assert_ntstatus_ok(tctx
, status
,
1387 "gensec_set_target_hostname (client) failed");
1389 status
= gensec_set_target_service(*gensec_client_context
, "dns");
1390 torture_assert_ntstatus_ok(tctx
, status
,
1391 "gensec_set_target_service failed");
1393 status
= gensec_set_credentials(*gensec_client_context
,
1394 samba_cmdline_get_creds());
1395 torture_assert_ntstatus_ok(tctx
, status
,
1396 "gensec_set_credentials (client) failed");
1398 status
= gensec_start_mech_by_sasl_name(*gensec_client_context
,
1400 torture_assert_ntstatus_ok(tctx
, status
,
1401 "gensec_start_mech_by_sasl_name (client) failed");
1409 static bool expected_record(TALLOC_CTX
*mem_ctx
,
1410 struct test_expected_record
*r
,
1415 unsigned int ttl
= 3600;
1416 const char *rdata
= talloc_asprintf(
1418 "%s.\t" "%u\t" "in\t" "%s\t" "%s",
1419 name
, ttl
, type
, data
);
1420 if (rdata
== NULL
) {
1424 *r
= (struct test_expected_record
){
1436 struct dlz_test_handle
{
1437 struct dcerpc_pipe
*p
;
1441 static bool set_zone_aging(struct torture_context
*tctx
,
1446 char *cmd
= talloc_asprintf(tctx
,
1447 "bin/samba-tool dns zoneoptions "
1448 "$SERVER %s -U$USERNAME%%$PASSWORD "
1449 "--aging %d", zone
, value
);
1465 static struct ldb_context
* get_samdb(struct torture_context
*tctx
)
1467 struct ldb_context
*samdb
= NULL
;
1469 int ret
= samdb_connect_url(
1473 system_session(tctx
->lp_ctx
),
1475 dlz_bind9_binddns_dir(tctx
, "dns/sam.ldb"),
1479 if (ret
!= LDB_SUCCESS
) {
1486 static void print_node_records(struct torture_context
*tctx
,
1487 struct ldb_context
*samdb
,
1488 struct ldb_dn
*node_dn
,
1492 struct ldb_result
*result
= NULL
;
1493 struct dnsp_DnssrvRpcRecord rec
;
1494 struct ldb_message_element
*el
= NULL
;
1498 torture_comment(tctx
,
1499 "\033[1;32m%s\033[0m\n",
1503 ret
= dsdb_search(samdb
, tctx
, &result
, node_dn
,
1504 LDB_SCOPE_SUBTREE
, NULL
,
1506 if (ret
!= LDB_SUCCESS
) {
1507 torture_comment(tctx
,
1508 "Failed to find node: %s",
1509 ldb_errstring(samdb
));
1512 el
= ldb_msg_find_element(result
->msgs
[0], "dnsRecord");
1514 for (i
= 0; i
< el
->num_values
; i
++) {
1515 ret
= ndr_pull_struct_blob(
1519 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnssrvRpcRecord
);
1520 if (!NDR_ERR_CODE_IS_SUCCESS(ret
)) {
1521 DBG_ERR("Failed to pull dns rec blob [%zu].\n",
1523 TALLOC_FREE(result
);
1525 torture_comment(tctx
, "record[%zu]:\n", i
);
1526 torture_comment(tctx
, "type: %d\n", rec
.wType
);
1527 torture_comment(tctx
, "timestamp: %u\n", rec
.dwTimeStamp
);
1528 torture_comment(tctx
, "%s\n",
1529 NDR_PRINT_STRUCT_STRING(result
,
1530 dnsp_DnssrvRpcRecord
,
1538 * Test some MORE updates, this time focussing on more record types and aging.
1540 static bool test_dlz_bind9_aging(struct torture_context
*tctx
)
1542 struct gensec_security
*gensec_client_context
= NULL
;
1543 DATA_BLOB client_to_server
, server_to_client
;
1545 void *dbdata
= NULL
;
1546 void *version
= NULL
;
1547 struct test_expected_rr
*testdata
= NULL
;
1549 struct ldb_context
*samdb
= NULL
;
1552 const char *domain
= lpcfg_dnsdomain(tctx
->lp_ctx
);
1553 struct ldb_dn
*domain_dn
= NULL
;
1554 struct ldb_dn
*node_dn
= NULL
;
1555 struct ldb_result
*result
= NULL
;
1556 uint32_t dns_timestamp_before
;
1557 uint32_t dns_timestamp_after
;
1558 const char *name
= NULL
;
1559 const char *attrs
[] = {"dnsrecord", NULL
};
1560 const char *node_dn_str
= NULL
;
1561 struct ldb_message_element
*el
= NULL
;
1562 struct ldb_message
*msg
= NULL
;
1566 /* Step 0. set things up */
1568 ok
= init_dlz(tctx
, &dbdata
);
1570 torture_fail(tctx
, "Failed to init_dlz");
1572 ok
= init_gensec(tctx
, &gensec_client_context
);
1574 torture_fail(tctx
, "Failed to init_gensec");
1577 samdb
= get_samdb(tctx
);
1578 if (samdb
== NULL
) {
1579 torture_fail(tctx
, "Failed to connect to samdb");
1582 domain_dn
= ldb_get_default_basedn(samdb
);
1583 testdata
= talloc_zero(tctx
, struct test_expected_rr
);
1584 torture_assert(tctx
, testdata
!= NULL
, "talloc failed");
1585 testdata
->tctx
= tctx
;
1587 testdata
->query_name
= __func__
;
1589 name
= talloc_asprintf(testdata
, "%s.%s",
1590 testdata
->query_name
,
1592 torture_assert(tctx
, name
!= NULL
, "talloc failed");
1594 testdata
->num_records
= 6;
1595 testdata
->records
= talloc_zero_array(testdata
,
1596 struct test_expected_record
,
1597 testdata
->num_records
);
1598 torture_assert(tctx
, testdata
->records
!= NULL
, "talloc failed");
1600 torture_assert(tctx
,
1601 expected_record(testdata
->records
,
1602 &testdata
->records
[0],
1603 testdata
->query_name
,
1606 "failed to add record");
1608 torture_assert(tctx
,
1609 expected_record(testdata
->records
,
1610 &testdata
->records
[1],
1611 testdata
->query_name
,
1614 "failed to add record");
1615 torture_assert(tctx
,
1616 expected_record(testdata
->records
,
1617 &testdata
->records
[2],
1618 testdata
->query_name
,
1621 "failed to add record");
1623 torture_assert(tctx
,
1624 expected_record(testdata
->records
,
1625 &testdata
->records
[3],
1626 testdata
->query_name
,
1628 "samba.example.com"),
1629 "failed to add record");
1632 * NOTE: Here we add the MX record with the priority before the name,
1633 * rather than the other way around which you are more likely to see
1634 * ("samba.example.com 11" e.g. in samba-tool dns), because this is
1635 * how it goes in BIND9 configuration.
1637 torture_assert(tctx
,
1638 expected_record(testdata
->records
,
1639 &testdata
->records
[4],
1640 testdata
->query_name
,
1642 "11 samba.example.com."),
1643 "failed to add record");
1645 torture_assert(tctx
,
1646 expected_record(testdata
->records
,
1647 &testdata
->records
[5],
1648 testdata
->query_name
,
1650 "samba.example.com"),
1651 "failed to add record");
1654 server_to_client
= data_blob(NULL
, 0);
1656 /* Do one step of the client-server update dance */
1657 status
= gensec_update(gensec_client_context
, tctx
, server_to_client
,
1659 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {;
1660 torture_assert_ntstatus_ok(tctx
, status
,
1661 "gensec_update (client) failed");
1664 torture_assert_int_equal(tctx
, dlz_ssumatch(
1665 cli_credentials_get_username(
1666 samba_cmdline_get_creds()),
1669 testdata
->records
[0].type
,
1671 client_to_server
.length
,
1672 client_to_server
.data
,
1675 "Failed to check key for update rights samba_dlz");
1677 /* remember the DN for use below */
1678 node_dn
= ldb_dn_copy(testdata
, domain_dn
);
1679 if (node_dn
== NULL
) {
1680 torture_fail(tctx
, "Failed to make node dn");
1683 ok
= ldb_dn_add_child_fmt(
1685 "DC=%s,DC=%s,CN=MicrosoftDNS,DC=DomainDnsZones",
1686 testdata
->query_name
,
1689 torture_fail(tctx
, "Failed to make node dn");
1691 node_dn_str
= ldb_dn_get_linearized(node_dn
);
1692 if (node_dn_str
== NULL
) {
1693 torture_fail(tctx
, "Failed to linearise node dn");
1696 /* LOOK: we are chopping off the last one (the CNAME) for now */
1697 testdata
->num_records
= 5;
1700 * We test the following:
1702 * Step 1. Ensure we are starting with an empty node.
1703 * Step 2. Add all the records (with aging off).
1704 * Step 3. Check the timestamps are now-ish.
1705 * Step 4. Add all the records AGAIN.
1706 * Step 5: Turn aging on.
1707 * Step 6. Add all the records again.
1708 * Step 7. Check the timestamps are still now-ish.
1709 * Step 8. Wind back the timestamps in the database.
1710 * Step 9. Do another update, changing some timestamps
1711 * Step 10. Check that the timestamps are right.
1712 * Step 11. Set one record to be static.
1713 * Step 12. Do updates on some records, zeroing their timestamps
1714 * Step 13. Check that the record timeouts are *mostly* zero.
1715 * Step 14. Turn aging off
1716 * Step 15. Update, setting timestamps to zero
1717 * Step 16. Check that the timestamps are all zero.
1718 * Step 17. Reset to non-zero via ldb, with aging still off.
1719 * Step 18. Update with aging off. Nothing should change.
1720 * Step 19. Check that the timestamps didn't change.
1721 * Step 20. Delete all the records, 1 by 1.
1726 * Step 1. Ensure we are starting with an empty node.
1728 torture_comment(tctx
, "step 1: %s records are not there\n",
1729 testdata
->query_name
);
1730 testdata
->num_rr
= 0;
1731 torture_assert_int_equal(tctx
, dlz_lookup(domain
,
1732 testdata
->query_name
,
1734 (dns_sdlzlookup_t
*)testdata
,
1738 torture_assert_int_equal(tctx
, testdata
->num_rr
, 0,
1739 "Got records when there should be none");
1742 dns_timestamp_before
= unix_to_dns_timestamp(time(NULL
));
1745 * Step 2. Add all the records (with aging off).
1746 * After adding each one, expect to find it and earlier ones.
1748 torture_comment(tctx
,
1749 "step 2: add %zu records\n",
1750 testdata
->num_records
);
1752 for (i
= 0; i
< testdata
->num_records
; i
++) {
1753 struct test_expected_record r
= testdata
->records
[i
];
1754 ret
= dlz_newversion(domain
, dbdata
, &version
);
1755 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
1756 "Failed to start transaction");
1758 ret
= dlz_addrdataset(name
, r
.rdata
, dbdata
, version
);
1759 torture_assert_int_equal_goto(
1760 tctx
, ret
, ISC_R_SUCCESS
, ok
,
1762 talloc_asprintf(tctx
,
1763 "Failed to add record %zu «%s»\n",
1766 dlz_closeversion(domain
, true, dbdata
, &version
);
1768 testdata
->num_rr
= 0;
1770 ret
= dlz_lookup(domain
, testdata
->query_name
, dbdata
,
1771 (dns_sdlzlookup_t
*)testdata
, NULL
, NULL
);
1773 torture_assert_int_equal(tctx
, ret
,
1775 "Not found hostname");
1776 torture_assert_int_equal(tctx
, testdata
->num_rr
, i
+ 1,
1777 "Got wrong record count");
1779 for (j
= 0; j
< testdata
->num_records
; j
++) {
1780 struct test_expected_record
*r2
= &testdata
->records
[j
];
1785 "putrr callback not run on %s «%s»",
1786 r2
->type
, r2
->name
);
1791 "putrr callback should not see %s «%s»",
1792 r2
->type
, r2
->name
);
1794 r2
->printed
= false;
1798 dns_timestamp_after
= unix_to_dns_timestamp(time(NULL
));
1800 * Step 3. Check the timestamps are now-ish.
1802 * Those records should have DNS timestamps between
1803 * dns_timestamp_before and dns_timestamp_after (the resolution is
1804 * hourly, so probably both are equal).
1806 ret
= dsdb_search(samdb
, tctx
, &result
, node_dn
,
1807 LDB_SCOPE_SUBTREE
, NULL
,
1809 if (ret
!= LDB_SUCCESS
) {
1813 "Failed to find %s node: %s",
1814 name
, ldb_errstring(samdb
)));
1816 torture_assert_int_equal(tctx
, result
->count
, 1,
1817 "Should be one node");
1819 el
= ldb_msg_find_element(result
->msgs
[0], "dnsRecord");
1820 torture_assert_not_null(tctx
, el
, "el");
1821 torture_assert(tctx
, dns_timestamp_before
<= dns_timestamp_after
, "<");
1822 torture_assert_int_equal(tctx
, el
->num_values
, testdata
->num_records
,
1823 "num_values != num_records");
1825 for (i
= 0; i
< el
->num_values
; i
++) {
1826 struct dnsp_DnssrvRpcRecord rec
;
1827 ret
= ndr_pull_struct_blob(
1831 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnssrvRpcRecord
);
1832 if (!NDR_ERR_CODE_IS_SUCCESS(ret
)) {
1833 DBG_ERR("Failed to pull dns rec blob [%zu].\n",
1835 TALLOC_FREE(result
);
1836 torture_fail(tctx
, "Failed to pull dns rec blob");
1838 torture_comment(tctx
, "record[%zu]:\n", i
);
1839 torture_comment(tctx
, "type: %d\n", rec
.wType
);
1840 torture_comment(tctx
, "timestamp: %u\n", rec
.dwTimeStamp
);
1841 torture_comment(tctx
, "%s\n",
1842 NDR_PRINT_STRUCT_STRING(result
,
1843 dnsp_DnssrvRpcRecord
,
1846 torture_assert(tctx
, rec
.dwTimeStamp
>= dns_timestamp_before
,
1847 "timestamp < dns_timestamp_before");
1848 torture_assert(tctx
, rec
.dwTimeStamp
<= dns_timestamp_after
,
1849 "timestamp > dns_timestamp_after");
1852 talloc_free(result
);
1855 * Step 4. Add all the records AGAIN.
1857 * After adding each one, we expect no change in the number or nature
1860 torture_comment(tctx
, "step 4: add the records again\n");
1861 for (i
= 0; i
< testdata
->num_records
; i
++) {
1862 struct test_expected_record r
= testdata
->records
[i
];
1864 ret
= dlz_newversion(domain
, dbdata
, &version
);
1865 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
1866 "Failed to start transaction");
1868 ret
= dlz_addrdataset(name
, r
.rdata
, dbdata
, version
);
1869 torture_assert_int_equal_goto(
1870 tctx
, ret
, ISC_R_SUCCESS
, ok
,
1872 talloc_asprintf(tctx
,
1873 "Failed to add record %zu «%s»\n",
1876 dlz_closeversion(domain
, true, dbdata
, &version
);
1878 testdata
->num_rr
= 0;
1880 ret
= dlz_lookup(domain
, testdata
->query_name
, dbdata
,
1881 (dns_sdlzlookup_t
*)testdata
, NULL
, NULL
);
1883 torture_assert_int_equal(tctx
, ret
,
1885 "Not found hostname");
1886 torture_assert_int_equal(tctx
,
1888 testdata
->num_records
,
1889 "Got wrong record count");
1891 for (j
= 0; j
<= i
; j
++) {
1892 /* these ones are printed again. */
1893 struct test_expected_record
*r2
= &testdata
->records
[j
];
1899 "putrr callback not run on %s «%s»",
1900 r2
->type
, r2
->name
));
1901 r2
->printed
= false;
1905 print_node_records(tctx
, samdb
, node_dn
, "after adding again");
1909 * Step 5: Turn aging on.
1911 torture_comment(tctx
, "step 5: turn aging on\n");
1912 ok
= set_zone_aging(tctx
, domain
, 1);
1913 torture_assert(tctx
, ok
, "failed to enable aging");
1915 print_node_records(tctx
, samdb
, node_dn
, "aging on");
1918 * Step 6. Add all the records again.
1920 * We expect no change in the number or nature of records, even with
1921 * aging on, because the default noRefreshInterval is 7 days (also,
1922 * there should be no change because almost no time has passed).
1924 torture_comment(tctx
, "step 6: add records again\n");
1926 for (i
= 0; i
< testdata
->num_records
; i
++) {
1927 struct test_expected_record r
= testdata
->records
[i
];
1929 ret
= dlz_newversion(domain
, dbdata
, &version
);
1930 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
1931 "Failed to start transaction");
1933 ret
= dlz_addrdataset(domain
, r
.rdata
, dbdata
, version
);
1934 torture_assert_int_equal_goto(
1935 tctx
, ret
, ISC_R_SUCCESS
, ok
,
1937 talloc_asprintf(tctx
,
1938 "Failed to add record %zu «%s»\n",
1941 dlz_closeversion(domain
, true, dbdata
, &version
);
1944 print_node_records(tctx
, samdb
, node_dn
, "add again");
1948 * Step 7. Check the timestamps are still now-ish.
1951 ret
= dsdb_search(samdb
, tctx
, &result
, node_dn
,
1952 LDB_SCOPE_SUBTREE
, NULL
,
1954 if (ret
!= LDB_SUCCESS
) {
1958 "Failed to find %s node: %s",
1959 name
, ldb_errstring(samdb
)));
1961 torture_assert_int_equal(tctx
, result
->count
, 1,
1962 "Should be one node");
1964 el
= ldb_msg_find_element(result
->msgs
[0], "dnsRecord");
1965 torture_assert_not_null(tctx
, el
, "el");
1966 torture_assert(tctx
, dns_timestamp_before
<= dns_timestamp_after
, "<");
1967 torture_assert_int_equal(tctx
, el
->num_values
, testdata
->num_records
,
1968 "num_values != num_records");
1970 for (i
= 0; i
< el
->num_values
; i
++) {
1971 struct dnsp_DnssrvRpcRecord rec
;
1972 ret
= ndr_pull_struct_blob(
1976 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnssrvRpcRecord
);
1977 if (!NDR_ERR_CODE_IS_SUCCESS(ret
)) {
1978 DBG_ERR("Failed to pull dns rec blob [%zu].\n",
1980 TALLOC_FREE(result
);
1981 torture_fail(tctx
, "Failed to pull dns rec blob");
1983 torture_comment(tctx
, "record[%zu]:\n", i
);
1984 torture_comment(tctx
, "type: %d\n", rec
.wType
);
1985 torture_comment(tctx
, "timestamp: %u\n", rec
.dwTimeStamp
);
1986 torture_comment(tctx
, "%s\n",
1987 NDR_PRINT_STRUCT_STRING(result
,
1988 dnsp_DnssrvRpcRecord
,
1991 torture_assert(tctx
, rec
.dwTimeStamp
>= dns_timestamp_before
,
1992 "timestamp < dns_timestamp_before");
1993 torture_assert(tctx
, rec
.dwTimeStamp
<= dns_timestamp_after
,
1994 "timestamp > dns_timestamp_after");
1997 talloc_free(result
);
2000 * Step 8. Wind back the timestamps in the database.
2002 * We use a different number of days for each record, so that some
2003 * should be refreshed, and some shouldn't.
2005 torture_comment(tctx
, "step 8: alter timestamps\n");
2006 ret
= dsdb_search_one(samdb
, tctx
, &msg
, node_dn
,
2007 LDB_SCOPE_BASE
, attrs
,
2009 if (ret
!= LDB_SUCCESS
) {
2013 "Failed to find %s node: %s",
2014 name
, ldb_errstring(samdb
)));
2017 el
= ldb_msg_find_element(msg
, "dnsRecord");
2018 torture_assert_not_null(tctx
, el
, "el");
2019 torture_assert_int_equal(tctx
, el
->num_values
,
2020 testdata
->num_records
,
2021 "num_values != num_records");
2023 for (i
= 0; i
< el
->num_values
; i
++) {
2024 struct dnsp_DnssrvRpcRecord rec
;
2025 ret
= ndr_pull_struct_blob(
2029 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnssrvRpcRecord
);
2030 torture_assert_ndr_success(tctx
, ret
, "failed to pull record");
2032 rec
.dwTimeStamp
= dns_timestamp_after
+ 3 - 24 * (i
+ 5);
2034 ret
= ndr_push_struct_blob(
2038 (ndr_push_flags_fn_t
)ndr_push_dnsp_DnssrvRpcRecord
);
2039 torture_assert_ndr_success(tctx
, ret
, "failed to PUSH record");
2041 el
->flags
= LDB_FLAG_MOD_REPLACE
;
2043 ret
= ldb_modify(samdb
, msg
);
2044 torture_assert_int_equal(tctx
, ret
, 0, "failed to ldb_modify");
2045 print_node_records(tctx
, samdb
, node_dn
, "after ldb_modify");
2049 * Step 9. Do another update, changing some timestamps
2052 for (i
= 0; i
< testdata
->num_records
; i
++) {
2053 struct test_expected_record r
= testdata
->records
[i
];
2055 ret
= dlz_newversion(domain
, dbdata
, &version
);
2056 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
2057 "Failed to start transaction");
2059 ret
= dlz_addrdataset(name
, r
.rdata
, dbdata
, version
);
2060 dlz_closeversion(domain
, ret
== ISC_R_SUCCESS
, dbdata
,
2062 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
2063 "Failed to update record\n");
2065 print_node_records(tctx
, samdb
, node_dn
, "after update");
2068 * Step 10. Check that the timestamps are right.
2071 * (i + 5) days + 3 hours
2072 * so 1 is 6 days + 3 hours, and should not be renewed.
2073 * 2 is 7 days + 3 hours, and should be renewed
2075 * NOTE: the ldb record order is different from the insertion order,
2076 * but it should stay the same between searches.
2078 ret
= dsdb_search_one(samdb
, tctx
, &msg
, node_dn
,
2079 LDB_SCOPE_BASE
, attrs
,
2081 if (ret
!= LDB_SUCCESS
) {
2085 "Failed to find %s node: %s",
2086 name
, ldb_errstring(samdb
)));
2089 el
= ldb_msg_find_element(msg
, "dnsRecord");
2090 torture_assert_not_null(tctx
, el
, "el");
2091 torture_assert_int_equal(tctx
, el
->num_values
,
2092 testdata
->num_records
,
2093 "num_values != num_records");
2095 for (i
= 0; i
< el
->num_values
; i
++) {
2096 struct dnsp_DnssrvRpcRecord rec
;
2097 ret
= ndr_pull_struct_blob(
2101 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnssrvRpcRecord
);
2102 torture_assert_ndr_success(tctx
, ret
, "failed to pull record");
2104 /* records 0 and 1 should not have been renewed */
2105 int old_ts
= dns_timestamp_after
+ 3 - 24 * (i
+ 5);
2108 rec
.dwTimeStamp
== old_ts
,
2109 "record[%zu] timestamp should not be altered."
2111 i
, rec
.dwTimeStamp
- old_ts
);
2113 /* records 3+ should have a now-ish timestamp */
2114 int old_ts
= dns_timestamp_after
+ 3 - 24 * (i
+ 5);
2117 rec
.dwTimeStamp
>= dns_timestamp_before
,
2118 "record[%zu] should have altered timestamp "
2119 "now ~= %d, then ~= %d, has %d, diff %d\n", i
,
2120 dns_timestamp_before
, old_ts
, rec
.dwTimeStamp
,
2121 dns_timestamp_before
- rec
.dwTimeStamp
2127 * Step 11. Set one record to be static.
2129 * This should make the node static, but it won't "know" that until we
2130 * force it with an update.
2132 torture_comment(tctx
, "step 11: alter one timestamp to be 0\n");
2133 ret
= dsdb_search_one(samdb
, tctx
, &msg
, node_dn
,
2134 LDB_SCOPE_BASE
, attrs
,
2136 if (ret
!= LDB_SUCCESS
) {
2140 "Failed to find %s node: %s",
2141 name
, ldb_errstring(samdb
)));
2144 el
= ldb_msg_find_element(msg
, "dnsRecord");
2145 torture_assert_not_null(tctx
, el
, "el");
2146 torture_assert_int_equal(tctx
, el
->num_values
,
2147 testdata
->num_records
,
2148 "num_values != num_records");
2151 /* we're arbitrarily picking on record 3 */
2152 struct dnsp_DnssrvRpcRecord rec
;
2153 ret
= ndr_pull_struct_blob(
2157 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnssrvRpcRecord
);
2158 torture_assert_ndr_success(tctx
, ret
, "failed to pull record");
2160 rec
.dwTimeStamp
= 0;
2162 ret
= ndr_push_struct_blob(
2166 (ndr_push_flags_fn_t
)ndr_push_dnsp_DnssrvRpcRecord
);
2167 torture_assert_ndr_success(tctx
, ret
, "failed to PUSH record");
2169 el
->flags
= LDB_FLAG_MOD_REPLACE
;
2171 ret
= ldb_modify(samdb
, msg
);
2172 torture_assert_int_equal(tctx
, ret
, 0, "failed to ldb_modify");
2173 print_node_records(tctx
, samdb
, node_dn
, "after ldb_modify");
2177 * Step 12. Do updates on some records, zeroing their timestamps
2179 * Zero means static. A single zero timestamp is infectious, so other
2180 * records get it when they are updated.
2183 for (i
= 0; i
< testdata
->num_records
- 2; i
++) {
2184 struct test_expected_record r
= testdata
->records
[i
];
2186 ret
= dlz_newversion(domain
, dbdata
, &version
);
2187 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
2188 "Failed to start transaction");
2190 ret
= dlz_addrdataset(name
, r
.rdata
, dbdata
, version
);
2191 dlz_closeversion(domain
, ret
== ISC_R_SUCCESS
, dbdata
,
2193 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
2194 "Failed to update record\n");
2196 print_node_records(tctx
, samdb
, node_dn
, "after update to static");
2200 * Step 13. Check that the record timeouts are *mostly* zero.
2202 * one or two will be non-zero: we updated all but two, but one of
2203 * excluded ones might be the el->records[3] that we explicitly set to
2206 ret
= dsdb_search_one(samdb
, tctx
, &msg
, node_dn
,
2207 LDB_SCOPE_BASE
, attrs
,
2209 if (ret
!= LDB_SUCCESS
) {
2213 "Failed to find %s node: %s",
2214 name
, ldb_errstring(samdb
)));
2217 el
= ldb_msg_find_element(msg
, "dnsRecord");
2219 unsigned n_zero
= 0;
2220 for (i
= 0; i
< el
->num_values
; i
++) {
2221 struct dnsp_DnssrvRpcRecord rec
;
2222 ret
= ndr_pull_struct_blob(
2226 (ndr_pull_flags_fn_t
)\
2227 ndr_pull_dnsp_DnssrvRpcRecord
);
2228 torture_assert_ndr_success(tctx
, ret
,
2229 "failed to pull record");
2230 if (rec
.dwTimeStamp
== 0) {
2234 if (n_zero
!= el
->num_values
- 1 &&
2235 n_zero
!= el
->num_values
- 2) {
2236 torture_comment(tctx
, "got %u zeros, expected %u or %u",
2239 el
->num_values
- 1);
2241 "static node not setting zero timestamps\n");
2248 * Step 14. Turn aging off.
2250 torture_comment(tctx
, "step 14: turn aging off\n");
2251 ok
= set_zone_aging(tctx
, domain
, 0);
2252 torture_assert(tctx
, ok
, "failed to disable aging");
2253 print_node_records(tctx
, samdb
, node_dn
, "aging off");
2256 * Step 15. Update, setting timestamps to zero.
2258 * Even with aging off, timestamps are still changed to static.
2260 for (i
= 0; i
< testdata
->num_records
; i
++) {
2261 struct test_expected_record r
= testdata
->records
[i
];
2263 ret
= dlz_newversion(domain
, dbdata
, &version
);
2264 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
2265 "Failed to start transaction");
2267 ret
= dlz_addrdataset(name
, r
.rdata
, dbdata
, version
);
2268 dlz_closeversion(domain
, ret
== ISC_R_SUCCESS
, dbdata
,
2270 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
2271 "Failed to update record\n");
2273 print_node_records(tctx
, samdb
, node_dn
, "after update with aging off");
2277 * Step 16. Check that the timestamps are all zero.
2279 ret
= dsdb_search_one(samdb
, tctx
, &msg
, node_dn
,
2280 LDB_SCOPE_BASE
, attrs
,
2282 if (ret
!= LDB_SUCCESS
) {
2286 "Failed to find %s node: %s",
2287 name
, ldb_errstring(samdb
)));
2290 el
= ldb_msg_find_element(msg
, "dnsRecord");
2291 for (i
= 0; i
< el
->num_values
; i
++) {
2292 struct dnsp_DnssrvRpcRecord rec
;
2293 ret
= ndr_pull_struct_blob(
2297 (ndr_pull_flags_fn_t
) ndr_pull_dnsp_DnssrvRpcRecord
);
2298 torture_assert_ndr_success(tctx
, ret
,
2299 "failed to pull record");
2300 torture_assertf(tctx
, rec
.dwTimeStamp
== 0,
2301 "record[%zu].dwTimeStamp is %u, expected 0\n",
2302 i
, rec
.dwTimeStamp
);
2308 * Step 17. Reset to non-zero via ldb, with aging still off.
2310 * We chose timestamps in the distant past that would all be updated
2313 torture_comment(tctx
, "step 17: reset to non-zero timestamps\n");
2314 ret
= dsdb_search_one(samdb
, tctx
, &msg
, node_dn
,
2315 LDB_SCOPE_BASE
, attrs
,
2317 if (ret
!= LDB_SUCCESS
) {
2321 "Failed to find %s node: %s",
2322 name
, ldb_errstring(samdb
)));
2325 el
= ldb_msg_find_element(msg
, "dnsRecord");
2327 for (i
= 0; i
< el
->num_values
; i
++) {
2328 struct dnsp_DnssrvRpcRecord rec
;
2329 ret
= ndr_pull_struct_blob(
2333 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnssrvRpcRecord
);
2334 torture_assert_ndr_success(tctx
, ret
, "failed to pull record");
2336 rec
.dwTimeStamp
= 10000 + i
; /* a long time ago */
2338 ret
= ndr_push_struct_blob(
2342 (ndr_push_flags_fn_t
)ndr_push_dnsp_DnssrvRpcRecord
);
2343 torture_assert_ndr_success(tctx
, ret
, "failed to PUSH record");
2345 el
->flags
= LDB_FLAG_MOD_REPLACE
;
2347 ret
= ldb_modify(samdb
, msg
);
2348 torture_assert_int_equal(tctx
, ret
, 0, "failed to ldb_modify");
2349 print_node_records(tctx
, samdb
, node_dn
, "timestamps no-zero, aging off");
2353 * Step 18. Update with aging off. Nothing should change.
2357 /* now, with another update, some will be updated and some won't */
2358 for (i
= 0; i
< testdata
->num_records
; i
++) {
2359 struct test_expected_record r
= testdata
->records
[i
];
2361 ret
= dlz_newversion(domain
, dbdata
, &version
);
2362 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
2363 "Failed to start transaction");
2365 ret
= dlz_addrdataset(name
, r
.rdata
, dbdata
, version
);
2366 dlz_closeversion(domain
, ret
== ISC_R_SUCCESS
, dbdata
,
2368 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
2369 "Failed to update record\n");
2371 print_node_records(tctx
, samdb
, node_dn
, "after update");
2375 * Step 19. Check that the timestamps didn't change.
2377 el
= ldb_msg_find_element(msg
, "dnsRecord");
2378 torture_assert_not_null(tctx
, el
, "el");
2379 torture_assert_int_equal(tctx
, el
->num_values
,
2380 testdata
->num_records
,
2381 "num_values != num_records");
2383 for (i
= 0; i
< el
->num_values
; i
++) {
2384 struct dnsp_DnssrvRpcRecord rec
;
2385 ret
= ndr_pull_struct_blob(
2389 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnssrvRpcRecord
);
2390 torture_assert_ndr_success(tctx
, ret
, "failed to pull record");
2393 rec
.dwTimeStamp
== 10000 + i
,
2394 "record[%zu] timestamp should not be altered.\n",
2400 * Step 20. Delete all the records, 1 by 1.
2403 torture_comment(tctx
, "step 20: delete the records\n");
2405 for (i
= 0; i
< testdata
->num_records
; i
++) {
2406 struct test_expected_record r
= testdata
->records
[i
];
2408 ret
= dlz_newversion(domain
, dbdata
, &version
);
2409 torture_assert_int_equal(tctx
, ret
, ISC_R_SUCCESS
,
2410 "Failed to start transaction");
2412 ret
= dlz_subrdataset(name
, r
.rdata
, dbdata
, version
);
2413 torture_assert_int_equal_goto(
2414 tctx
, ret
, ISC_R_SUCCESS
, ok
,
2416 talloc_asprintf(tctx
,
2417 "Failed to delete record %zu «%s»\n",
2420 dlz_closeversion(domain
, true, dbdata
, &version
);
2422 testdata
->num_rr
= 0;
2424 ret
= dlz_lookup(domain
, testdata
->query_name
, dbdata
,
2425 (dns_sdlzlookup_t
*)testdata
, NULL
, NULL
);
2427 if (i
== testdata
->num_records
- 1) {
2428 torture_assert_int_equal(tctx
, ret
,
2430 "no records should exist");
2432 torture_assert_int_equal(tctx
, ret
,
2434 "records not found");
2437 torture_assert_int_equal(tctx
,
2439 testdata
->num_records
- 1 - i
,
2440 "Got wrong record count");
2442 for (j
= 0; j
< testdata
->num_records
; j
++) {
2443 struct test_expected_record
*r2
= &testdata
->records
[j
];
2448 talloc_asprintf(tctx
,
2449 "putrr callback not run on %s «%s»",
2450 r2
->type
, r2
->name
));
2455 talloc_asprintf(tctx
,
2456 "putrr callback should not see %s «%s»",
2457 r2
->type
, r2
->name
));
2459 r2
->printed
= false;
2463 dlz_destroy(dbdata
);
2468 DBG_ERR("exiting with %d\n", ret
);
2469 dlz_closeversion(domain
, false, dbdata
, &version
);
2474 static struct torture_suite
*dlz_bind9_suite(TALLOC_CTX
*ctx
)
2476 struct torture_suite
*suite
= torture_suite_create(ctx
, "dlz_bind9");
2478 suite
->description
= talloc_strdup(suite
,
2479 "Tests for the BIND 9 DLZ module");
2480 torture_suite_add_simple_test(suite
, "version", test_dlz_bind9_version
);
2481 torture_suite_add_simple_test(suite
, "create", test_dlz_bind9_create
);
2482 torture_suite_add_simple_test(suite
, "configure", test_dlz_bind9_configure
);
2483 torture_suite_add_simple_test(suite
, "destroyoldestfirst",
2484 test_dlz_bind9_destroy_oldest_first
);
2485 torture_suite_add_simple_test(suite
, "destroynewestfirst",
2486 test_dlz_bind9_destroy_newest_first
);
2487 torture_suite_add_simple_test(suite
, "multipleconfigure",
2488 test_dlz_bind9_multiple_configure
);
2490 torture_suite_add_simple_test(suite
, "gssapi", test_dlz_bind9_gssapi
);
2491 torture_suite_add_simple_test(suite
, "spnego", test_dlz_bind9_spnego
);
2492 torture_suite_add_simple_test(suite
, "lookup", test_dlz_bind9_lookup
);
2493 torture_suite_add_simple_test(suite
, "zonedump", test_dlz_bind9_zonedump
);
2494 torture_suite_add_simple_test(suite
, "update01", test_dlz_bind9_update01
);
2495 torture_suite_add_simple_test(suite
, "aging", test_dlz_bind9_aging
);
2496 torture_suite_add_simple_test(suite
, "allowzonexfr", test_dlz_bind9_allowzonexfr
);
2501 * DNS torture module initialization
2503 NTSTATUS
torture_bind_dns_init(TALLOC_CTX
*);
2504 NTSTATUS
torture_bind_dns_init(TALLOC_CTX
*ctx
)
2506 struct torture_suite
*suite
;
2508 /* register DNS related test cases */
2509 suite
= dlz_bind9_suite(ctx
);
2510 if (!suite
) return NT_STATUS_NO_MEMORY
;
2511 torture_register_suite(ctx
, suite
);
2513 return NT_STATUS_OK
;