From 80416846b27f426d8b7f4482acdc45f08a3cde78 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Aug 2014 13:48:21 +0200 Subject: [PATCH 01/21] s4:torture:dlz_bind9: fix spnego tests The dlz_bind9 module uses the special dns-${NETBIOSNAME} account, and this is only available under the dns/hostname.domain SPN, not host/hostname. Also the dlz_ssumatch() function returns isc_boolean_t instead of isc_result_t. As ISC_R_SUCCESS and ISC_FALSE have the same value we didn't notice this problem. Change-Id: I48539c3f48f5dde9eaa2fff6da0f3be2f9f66311 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 76943bf0ac259fb8855bd123fe4bc85a103ba418) --- source4/torture/dns/dlz_bind9.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source4/torture/dns/dlz_bind9.c b/source4/torture/dns/dlz_bind9.c index 88ca27c..0c5b153 100644 --- a/source4/torture/dns/dlz_bind9.c +++ b/source4/torture/dns/dlz_bind9.c @@ -158,9 +158,19 @@ static bool test_dlz_bind9_gensec(struct torture_context *tctx, const char *mech lpcfg_gensec_settings(tctx, tctx->lp_ctx)); torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed"); - status = gensec_set_target_hostname(gensec_client_context, torture_setting_string(tctx, "host", NULL)); + /* + * dlz_bind9 use the special dns/host.domain account + */ + status = gensec_set_target_hostname(gensec_client_context, + talloc_asprintf(tctx, + "%s.%s", + torture_setting_string(tctx, "host", NULL), + lpcfg_dnsdomain(tctx->lp_ctx))); torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed"); + status = gensec_set_target_service(gensec_client_context, "dns"); + torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_service failed"); + status = gensec_set_credentials(gensec_client_context, cmdline_credentials); torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed"); @@ -181,7 +191,7 @@ static bool test_dlz_bind9_gensec(struct torture_context *tctx, const char *mech client_to_server.length, client_to_server.data, dbdata), - ISC_R_SUCCESS, + ISC_TRUE, "Failed to check key for update rights samba_dlz"); dlz_destroy(dbdata); -- 1.9.1 From 2f50d70caae59ec440b2113530ad64383a2cc9d1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 26 Aug 2014 10:24:27 +1200 Subject: [PATCH 02/21] torture-dns: Add test for dlz_bind9 lookups Change-Id: I3b9d1b56e3aa873fb8540b98e196b713b82332ca Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Andrew Bartlett Signed-off-by: Stefan Metzmacher (cherry picked from commit 2189470c2f55afe29e9e8dad1d2659a7eb2d06f9) --- source4/torture/dns/dlz_bind9.c | 224 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) diff --git a/source4/torture/dns/dlz_bind9.c b/source4/torture/dns/dlz_bind9.c index 0c5b153..327eb84 100644 --- a/source4/torture/dns/dlz_bind9.c +++ b/source4/torture/dns/dlz_bind9.c @@ -209,6 +209,229 @@ static bool test_dlz_bind9_spnego(struct torture_context *tctx) return test_dlz_bind9_gensec(tctx, "GSS-SPNEGO"); } +struct test_expected_record { + const char *name; + const char *type; + const char *data; + int ttl; + bool printed; +}; + +struct test_expected_rr { + struct torture_context *tctx; + const char *query_name; + size_t num_records; + struct test_expected_record *records; + size_t num_rr; +}; + +static bool dlz_bind9_putnamedrr_torture_hook(struct test_expected_rr *expected, + const char *name, + const char *type, + dns_ttl_t ttl, + const char *data) +{ + size_t i; + + torture_assert(expected->tctx, name != NULL, + talloc_asprintf(expected->tctx, + "Got unnamed record type[%s] data[%s]\n", + type, data)); + + expected->num_rr++; + torture_comment(expected->tctx, "%u: name[%s] type[%s] ttl[%u] data[%s]\n", + (unsigned)expected->num_rr, name, type, (unsigned)ttl, data); + + for (i = 0; i < expected->num_records; i++) { + if (expected->records[i].name != NULL) { + if (strcmp(name, expected->records[i].name) != 0) { + continue; + } + } + + if (strcmp(type, expected->records[i].type) != 0) { + continue; + } + + if (expected->records[i].data != NULL) { + if (strcmp(data, expected->records[i].data) != 0) { + continue; + } + } + + torture_assert_int_equal(expected->tctx, ttl, + expected->records[i].ttl, + talloc_asprintf(expected->tctx, + "TTL did not match expectations for type %s", + type)); + + expected->records[i].printed = true; + } + + return true; +} + +static isc_result_t dlz_bind9_putrr_hook(dns_sdlzlookup_t *lookup, + const char *type, + dns_ttl_t ttl, + const char *data) +{ + struct test_expected_rr *expected = + talloc_get_type_abort(lookup, struct test_expected_rr); + bool ok; + + ok = dlz_bind9_putnamedrr_torture_hook(expected, expected->query_name, + type, ttl, data); + if (!ok) { + return ISC_R_FAILURE; + } + + return ISC_R_SUCCESS; +} + +static isc_result_t dlz_bind9_putnamedrr_hook(dns_sdlzallnodes_t *allnodes, + const char *name, + const char *type, + dns_ttl_t ttl, + const char *data) +{ + struct test_expected_rr *expected = + talloc_get_type_abort(allnodes, struct test_expected_rr); + bool ok; + + ok = dlz_bind9_putnamedrr_torture_hook(expected, name, type, ttl, data); + if (!ok) { + return ISC_R_FAILURE; + } + + return ISC_R_SUCCESS; +} + +/* + * Tests some lookups + */ +static bool test_dlz_bind9_lookup(struct torture_context *tctx) +{ + size_t i; + void *dbdata; + const char *argv[] = { + "samba_dlz", + "-H", + lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"), + NULL + }; + struct test_expected_rr *expected1 = NULL; + struct test_expected_rr *expected2 = NULL; + + tctx_static = tctx; + torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata, + "log", dlz_bind9_log_wrapper, + "writeable_zone", dlz_bind9_writeable_zone_hook, + "putrr", dlz_bind9_putrr_hook, + "putnamedrr", dlz_bind9_putnamedrr_hook, + NULL), + ISC_R_SUCCESS, + "Failed to create samba_dlz"); + + torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata), + ISC_R_SUCCESS, + "Failed to configure samba_dlz"); + + expected1 = talloc_zero(tctx, struct test_expected_rr); + torture_assert(tctx, expected1 != NULL, "talloc failed"); + expected1->tctx = tctx; + + expected1->query_name = "@"; + + expected1->num_records = 4; + expected1->records = talloc_zero_array(expected1, + struct test_expected_record, + expected1->num_records); + torture_assert(tctx, expected1->records != NULL, "talloc failed"); + + expected1->records[0].name = expected1->query_name; + expected1->records[0].type = "soa"; + expected1->records[0].ttl = 3600; + expected1->records[0].data = talloc_asprintf(expected1->records, + "%s.%s hostmaster.%s 1 900 600 86400 3600", + torture_setting_string(tctx, "host", NULL), + lpcfg_dnsdomain(tctx->lp_ctx), + lpcfg_dnsdomain(tctx->lp_ctx)); + torture_assert(tctx, expected1->records[0].data != NULL, "talloc failed"); + + expected1->records[1].name = expected1->query_name; + expected1->records[1].type = "ns"; + expected1->records[1].ttl = 900; + expected1->records[1].data = talloc_asprintf(expected1->records, "%s.%s", + torture_setting_string(tctx, "host", NULL), + lpcfg_dnsdomain(tctx->lp_ctx)); + torture_assert(tctx, expected1->records[1].data != NULL, "talloc failed"); + + expected1->records[2].name = expected1->query_name; + expected1->records[2].type = "aaaa"; + expected1->records[2].ttl = 900; + + expected1->records[3].name = expected1->query_name; + expected1->records[3].type = "a"; + expected1->records[3].ttl = 900; + + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_SUCCESS, + "Failed to lookup @"); + for (i = 0; i < expected1->num_records; i++) { + torture_assert(tctx, expected1->records[i].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run for type %s", + expected1->records[i].type)); + } + torture_assert_int_equal(tctx, expected1->num_rr, + expected1->num_records, + "Got too much data"); + + expected2 = talloc_zero(tctx, struct test_expected_rr); + torture_assert(tctx, expected2 != NULL, "talloc failed"); + expected2->tctx = tctx; + + expected2->query_name = torture_setting_string(tctx, "host", NULL); + torture_assert(tctx, expected2->query_name != NULL, "unknown host"); + + expected2->num_records = 2; + expected2->records = talloc_zero_array(expected2, + struct test_expected_record, + expected2->num_records); + torture_assert(tctx, expected2->records != NULL, "talloc failed"); + + expected2->records[0].name = expected2->query_name; + expected2->records[0].type = "aaaa"; + expected2->records[0].ttl = 900; + + expected2->records[1].name = expected2->query_name; + expected2->records[1].type = "a"; + expected2->records[1].ttl = 900; + + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected2->query_name, dbdata, + (dns_sdlzlookup_t *)expected2), + ISC_R_SUCCESS, + "Failed to lookup hostname"); + for (i = 0; i < expected2->num_records; i++) { + torture_assert(tctx, expected2->records[i].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected2->records[i].name, + expected2->records[i].type)); + } + torture_assert_int_equal(tctx, expected2->num_rr, + expected2->num_records, + "Got too much data"); + + dlz_destroy(dbdata); + + return true; +} + static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) { struct torture_suite *suite = torture_suite_create(ctx, "dlz_bind9"); @@ -220,6 +443,7 @@ static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) torture_suite_add_simple_test(suite, "configure", test_dlz_bind9_configure); torture_suite_add_simple_test(suite, "gssapi", test_dlz_bind9_gssapi); torture_suite_add_simple_test(suite, "spnego", test_dlz_bind9_spnego); + torture_suite_add_simple_test(suite, "lookup", test_dlz_bind9_lookup); return suite; } -- 1.9.1 From 5d3763adba2103478acbd1a01509079cac852b07 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Aug 2014 10:34:17 +0200 Subject: [PATCH 03/21] torture-dns: Add test for dlz_bind9 zonedumps Change-Id: I074b3e4cdad1a0b69c085dcaa44d6f48e68e863b Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit e23621e9dab67c8997d24b2ac7e4fd181fc5907c) --- source4/torture/dns/dlz_bind9.c | 106 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/source4/torture/dns/dlz_bind9.c b/source4/torture/dns/dlz_bind9.c index 327eb84..e98db44 100644 --- a/source4/torture/dns/dlz_bind9.c +++ b/source4/torture/dns/dlz_bind9.c @@ -432,6 +432,111 @@ static bool test_dlz_bind9_lookup(struct torture_context *tctx) return true; } +/* + * Test some zone dumps + */ +static bool test_dlz_bind9_zonedump(struct torture_context *tctx) +{ + size_t i; + void *dbdata; + const char *argv[] = { + "samba_dlz", + "-H", + lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"), + NULL + }; + struct test_expected_rr *expected1 = NULL; + + tctx_static = tctx; + torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata, + "log", dlz_bind9_log_wrapper, + "writeable_zone", dlz_bind9_writeable_zone_hook, + "putrr", dlz_bind9_putrr_hook, + "putnamedrr", dlz_bind9_putnamedrr_hook, + NULL), + ISC_R_SUCCESS, + "Failed to create samba_dlz"); + + torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata), + ISC_R_SUCCESS, + "Failed to configure samba_dlz"); + + expected1 = talloc_zero(tctx, struct test_expected_rr); + torture_assert(tctx, expected1 != NULL, "talloc failed"); + expected1->tctx = tctx; + + expected1->num_records = 7; + expected1->records = talloc_zero_array(expected1, + struct test_expected_record, + expected1->num_records); + torture_assert(tctx, expected1->records != NULL, "talloc failed"); + + expected1->records[0].name = lpcfg_dnsdomain(tctx->lp_ctx); + expected1->records[0].type = "soa"; + expected1->records[0].ttl = 3600; + expected1->records[0].data = talloc_asprintf(expected1->records, + "%s.%s hostmaster.%s 1 900 600 86400 3600", + torture_setting_string(tctx, "host", NULL), + lpcfg_dnsdomain(tctx->lp_ctx), + lpcfg_dnsdomain(tctx->lp_ctx)); + torture_assert(tctx, expected1->records[0].data != NULL, "talloc failed"); + + expected1->records[1].name = lpcfg_dnsdomain(tctx->lp_ctx); + expected1->records[1].type = "ns"; + expected1->records[1].ttl = 900; + expected1->records[1].data = talloc_asprintf(expected1->records, "%s.%s", + torture_setting_string(tctx, "host", NULL), + lpcfg_dnsdomain(tctx->lp_ctx)); + torture_assert(tctx, expected1->records[1].data != NULL, "talloc failed"); + + expected1->records[2].name = lpcfg_dnsdomain(tctx->lp_ctx); + expected1->records[2].type = "aaaa"; + expected1->records[2].ttl = 900; + + expected1->records[3].name = lpcfg_dnsdomain(tctx->lp_ctx); + expected1->records[3].type = "a"; + expected1->records[3].ttl = 900; + + expected1->records[4].name = talloc_asprintf(expected1->records, "%s.%s", + torture_setting_string(tctx, "host", NULL), + lpcfg_dnsdomain(tctx->lp_ctx)); + torture_assert(tctx, expected1->records[4].name != NULL, "unknown host"); + expected1->records[4].type = "aaaa"; + expected1->records[4].ttl = 900; + + expected1->records[5].name = talloc_asprintf(expected1->records, "%s.%s", + torture_setting_string(tctx, "host", NULL), + lpcfg_dnsdomain(tctx->lp_ctx)); + torture_assert(tctx, expected1->records[5].name != NULL, "unknown host"); + expected1->records[5].type = "a"; + expected1->records[5].ttl = 900; + + /* + * We expect multiple srv records + */ + expected1->records[6].name = NULL; + expected1->records[6].type = "srv"; + expected1->records[6].ttl = 900; + + torture_assert_int_equal(tctx, dlz_allnodes(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, (dns_sdlzallnodes_t *)expected1), + ISC_R_SUCCESS, + "Failed to configure samba_dlz"); + for (i = 0; i < expected1->num_records; i++) { + torture_assert(tctx, expected1->records[i].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[i].name, + expected1->records[i].type)); + } + torture_assert_int_equal(tctx, expected1->num_rr, 24, + "Got wrong record count"); + + dlz_destroy(dbdata); + + return true; +} + static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) { struct torture_suite *suite = torture_suite_create(ctx, "dlz_bind9"); @@ -444,6 +549,7 @@ static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) torture_suite_add_simple_test(suite, "gssapi", test_dlz_bind9_gssapi); torture_suite_add_simple_test(suite, "spnego", test_dlz_bind9_spnego); torture_suite_add_simple_test(suite, "lookup", test_dlz_bind9_lookup); + torture_suite_add_simple_test(suite, "zonedump", test_dlz_bind9_zonedump); return suite; } -- 1.9.1 From 81375301b92467f05c02b4cdca02f1e1bbc26c3a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Aug 2014 12:04:59 +0200 Subject: [PATCH 04/21] torture-dns: Add test for dlz_bind9 updates Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 914a3667471ced3199f51db8bc1d4a6d3fbc4e8f) --- source4/torture/dns/dlz_bind9.c | 517 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 517 insertions(+) diff --git a/source4/torture/dns/dlz_bind9.c b/source4/torture/dns/dlz_bind9.c index e98db44..1021f2c 100644 --- a/source4/torture/dns/dlz_bind9.c +++ b/source4/torture/dns/dlz_bind9.c @@ -537,6 +537,522 @@ static bool test_dlz_bind9_zonedump(struct torture_context *tctx) return true; } +/* + * Test some updates + */ +static bool test_dlz_bind9_update01(struct torture_context *tctx) +{ + NTSTATUS status; + struct gensec_security *gensec_client_context; + DATA_BLOB client_to_server, server_to_client; + void *dbdata; + void *version = NULL; + const char *argv[] = { + "samba_dlz", + "-H", + lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"), + NULL + }; + struct test_expected_rr *expected1 = NULL; + char *name = NULL; + char *data0 = NULL; + char *data1 = NULL; + char *data2 = NULL; + bool ret = false; + + tctx_static = tctx; + torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata, + "log", dlz_bind9_log_wrapper, + "writeable_zone", dlz_bind9_writeable_zone_hook, + "putrr", dlz_bind9_putrr_hook, + "putnamedrr", dlz_bind9_putnamedrr_hook, + NULL), + ISC_R_SUCCESS, + "Failed to create samba_dlz"); + + torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata), + ISC_R_SUCCESS, + "Failed to configure samba_dlz"); + + expected1 = talloc_zero(tctx, struct test_expected_rr); + torture_assert(tctx, expected1 != NULL, "talloc failed"); + expected1->tctx = tctx; + + expected1->query_name = __func__; + + name = talloc_asprintf(expected1, "%s.%s", + expected1->query_name, + lpcfg_dnsdomain(tctx->lp_ctx)); + torture_assert(tctx, name != NULL, "talloc failed"); + + expected1->num_records = 2; + expected1->records = talloc_zero_array(expected1, + struct test_expected_record, + expected1->num_records); + torture_assert(tctx, expected1->records != NULL, "talloc failed"); + + expected1->records[0].name = expected1->query_name; + expected1->records[0].type = "a"; + expected1->records[0].ttl = 3600; + expected1->records[0].data = "127.1.2.3"; + expected1->records[0].printed = false; + + data0 = talloc_asprintf(expected1, + "%s.\t" "%u\t" "%s\t" "%s\t" "%s", + name, + (unsigned)expected1->records[0].ttl, + "in", + expected1->records[0].type, + expected1->records[0].data); + torture_assert(tctx, data0 != NULL, "talloc failed"); + + expected1->records[1].name = expected1->query_name; + expected1->records[1].type = "a"; + expected1->records[1].ttl = 3600; + expected1->records[1].data = "127.3.2.1"; + expected1->records[1].printed = false; + + data1 = talloc_asprintf(expected1, + "%s.\t" "%u\t" "%s\t" "%s\t" "%s", + name, + (unsigned)expected1->records[1].ttl, + "in", + expected1->records[1].type, + expected1->records[1].data); + torture_assert(tctx, data1 != NULL, "talloc failed"); + + data2 = talloc_asprintf(expected1, + "%s.\t" "0\t" "in\t" "a\t" "127.3.3.3", + name); + torture_assert(tctx, data2 != NULL, "talloc failed"); + + /* + * Prepare session info + */ + status = gensec_client_start(tctx, &gensec_client_context, + lpcfg_gensec_settings(tctx, tctx->lp_ctx)); + torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed"); + + /* + * dlz_bind9 use the special dns/host.domain account + */ + status = gensec_set_target_hostname(gensec_client_context, + talloc_asprintf(tctx, + "%s.%s", + torture_setting_string(tctx, "host", NULL), + lpcfg_dnsdomain(tctx->lp_ctx))); + torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed"); + + status = gensec_set_target_service(gensec_client_context, "dns"); + torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_service failed"); + + status = gensec_set_credentials(gensec_client_context, cmdline_credentials); + torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed"); + + status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSS-SPNEGO"); + torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed"); + + server_to_client = data_blob(NULL, 0); + + /* Do one step of the client-server update dance */ + status = gensec_update(gensec_client_context, tctx, server_to_client, &client_to_server); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {; + torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed"); + } + + torture_assert_int_equal(tctx, dlz_ssumatch(cli_credentials_get_username(cmdline_credentials), + name, + "127.0.0.1", + expected1->records[0].type, + "key", + client_to_server.length, + client_to_server.data, + dbdata), + ISC_TRUE, + "Failed to check key for update rights samba_dlz"); + + /* + * We test the following: + * + * 1. lookup the records => NOT_FOUND + * 2. delete all records => NOT_FOUND + * 3. delete 1st record => NOT_FOUND + * 4. create 1st record => SUCCESS + * 5. lookup the records => found 1st + * 6. create 2nd record => SUCCESS + * 7. lookup the records => found 1st and 2nd + * 8. delete unknown record => NOT_FOUND + * 9. lookup the records => found 1st and 2nd + * 10. delete 1st record => SUCCESS + * 11. lookup the records => found 2nd + * 12. delete 2nd record => SUCCESS + * 13. lookup the records => NOT_FOUND + * 14. create 1st record => SUCCESS + * 15. lookup the records => found 1st + * 16. create 2nd record => SUCCESS + * 17. lookup the records => found 1st and 2nd + * 18. update 1st record => SUCCESS + * 19. lookup the records => found 1st and 2nd + * 20. delete all unknown type records => NOT_FOUND + * 21. lookup the records => found 1st and 2nd + * 22. delete all records => SUCCESS + * 23. lookup the records => NOT_FOUND + */ + + /* Step 1. */ + expected1->num_rr = 0; + expected1->records[0].printed = false; + expected1->records[1].printed = false; + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_NOTFOUND, + "Found hostname"); + torture_assert_int_equal(tctx, expected1->num_rr, 0, + "Got wrong record count"); + + /* Step 2. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_delrdataset(name, + expected1->records[0].type, + dbdata, version), + ISC_R_NOTFOUND, ret, cancel_version, + talloc_asprintf(tctx, "Deleted name[%s] type[%s]\n", + name, expected1->records[0].type)); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version); + + /* Step 3. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_subrdataset(name, data0, dbdata, version), + ISC_R_NOTFOUND, ret, cancel_version, + talloc_asprintf(tctx, "Deleted name[%s] data[%s]\n", + name, data0)); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version); + + /* Step 4. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_addrdataset(name, data0, dbdata, version), + ISC_R_SUCCESS, ret, cancel_version, + talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n", + name, data0)); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); + + /* Step 5. */ + expected1->num_rr = 0; + expected1->records[0].printed = false; + expected1->records[1].printed = false; + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_SUCCESS, + "Not found hostname"); + torture_assert(tctx, expected1->records[0].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[0].name, + expected1->records[0].type)); + torture_assert_int_equal(tctx, expected1->num_rr, 1, + "Got wrong record count"); + + /* Step 6. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_addrdataset(name, data1, dbdata, version), + ISC_R_SUCCESS, ret, cancel_version, + talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n", + name, data1)); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); + + /* Step 7. */ + expected1->num_rr = 0; + expected1->records[0].printed = false; + expected1->records[1].printed = false; + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_SUCCESS, + "Not found hostname"); + torture_assert(tctx, expected1->records[0].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[0].name, + expected1->records[0].type)); + torture_assert(tctx, expected1->records[1].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[1].name, + expected1->records[1].type)); + torture_assert_int_equal(tctx, expected1->num_rr, 2, + "Got wrong record count"); + + /* Step 8. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_subrdataset(name, data2, dbdata, version), + ISC_R_NOTFOUND, ret, cancel_version, + talloc_asprintf(tctx, "Deleted name[%s] data[%s]\n", + name, data2)); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); + + /* Step 9. */ + expected1->num_rr = 0; + expected1->records[0].printed = false; + expected1->records[1].printed = false; + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_SUCCESS, + "Not found hostname"); + torture_assert(tctx, expected1->records[0].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[0].name, + expected1->records[0].type)); + torture_assert(tctx, expected1->records[1].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[1].name, + expected1->records[1].type)); + torture_assert_int_equal(tctx, expected1->num_rr, 2, + "Got wrong record count"); + + /* Step 10. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_subrdataset(name, data0, dbdata, version), + ISC_R_SUCCESS, ret, cancel_version, + talloc_asprintf(tctx, "Failed to delete name[%s] data[%s]\n", + name, data0)); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); + + /* Step 11. */ + expected1->num_rr = 0; + expected1->records[0].printed = false; + expected1->records[1].printed = false; + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_SUCCESS, + "Not found hostname"); + torture_assert(tctx, expected1->records[1].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[1].name, + expected1->records[1].type)); + torture_assert_int_equal(tctx, expected1->num_rr, 1, + "Got wrong record count"); + + /* Step 12. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_subrdataset(name, data1, dbdata, version), + ISC_R_SUCCESS, ret, cancel_version, + talloc_asprintf(tctx, "Failed to delete name[%s] data[%s]\n", + name, data1)); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); + + /* Step 13. */ + expected1->num_rr = 0; + expected1->records[0].printed = false; + expected1->records[1].printed = false; + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_NOTFOUND, + "Found hostname"); + torture_assert_int_equal(tctx, expected1->num_rr, 0, + "Got wrong record count"); + + /* Step 14. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_addrdataset(name, data0, dbdata, version), + ISC_R_SUCCESS, ret, cancel_version, + talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n", + name, data0)); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); + + /* Step 15. */ + expected1->num_rr = 0; + expected1->records[0].printed = false; + expected1->records[1].printed = false; + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_SUCCESS, + "Not found hostname"); + torture_assert(tctx, expected1->records[0].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[0].name, + expected1->records[0].type)); + torture_assert_int_equal(tctx, expected1->num_rr, 1, + "Got wrong record count"); + + /* Step 16. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_addrdataset(name, data1, dbdata, version), + ISC_R_SUCCESS, ret, cancel_version, + talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n", + name, data1)); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); + + /* Step 17. */ + expected1->num_rr = 0; + expected1->records[0].printed = false; + expected1->records[1].printed = false; + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_SUCCESS, + "Not found hostname"); + torture_assert(tctx, expected1->records[0].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[0].name, + expected1->records[0].type)); + torture_assert(tctx, expected1->records[1].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[1].name, + expected1->records[1].type)); + torture_assert_int_equal(tctx, expected1->num_rr, 2, + "Got wrong record count"); + + /* Step 18. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_addrdataset(name, data0, dbdata, version), + ISC_R_SUCCESS, ret, cancel_version, + talloc_asprintf(tctx, "Failed to update name[%s] data[%s]\n", + name, data0)); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); + + /* Step 19. */ + expected1->num_rr = 0; + expected1->records[0].printed = false; + expected1->records[1].printed = false; + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_SUCCESS, + "Not found hostname"); + torture_assert(tctx, expected1->records[0].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[0].name, + expected1->records[0].type)); + torture_assert(tctx, expected1->records[1].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[1].name, + expected1->records[1].type)); + torture_assert_int_equal(tctx, expected1->num_rr, 2, + "Got wrong record count"); + + /* Step 20. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_delrdataset(name, "txt", dbdata, version), + ISC_R_FAILURE, ret, cancel_version, + talloc_asprintf(tctx, "Deleted name[%s] type[%s]\n", + name, "txt")); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version); + + /* Step 21. */ + expected1->num_rr = 0; + expected1->records[0].printed = false; + expected1->records[1].printed = false; + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_SUCCESS, + "Not found hostname"); + torture_assert(tctx, expected1->records[0].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[0].name, + expected1->records[0].type)); + torture_assert(tctx, expected1->records[1].printed, + talloc_asprintf(tctx, + "Failed to have putrr callback run name[%s] for type %s", + expected1->records[1].name, + expected1->records[1].type)); + torture_assert_int_equal(tctx, expected1->num_rr, 2, + "Got wrong record count"); + + /* Step 22. */ + torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), + dbdata, &version), + ISC_R_SUCCESS, + "Failed to start transaction"); + torture_assert_int_equal_goto(tctx, + dlz_delrdataset(name, + expected1->records[0].type, + dbdata, version), + ISC_R_SUCCESS, ret, cancel_version, + talloc_asprintf(tctx, "Failed to delete name[%s] type[%s]\n", + name, expected1->records[0].type)); + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); + + /* Step 23. */ + expected1->num_rr = 0; + expected1->records[0].printed = false; + expected1->records[1].printed = false; + torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), + expected1->query_name, dbdata, + (dns_sdlzlookup_t *)expected1), + ISC_R_NOTFOUND, + "Found hostname"); + torture_assert_int_equal(tctx, expected1->num_rr, 0, + "Got wrong record count"); + + dlz_destroy(dbdata); + + return true; + +cancel_version: + dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version); + return ret; +} + static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) { struct torture_suite *suite = torture_suite_create(ctx, "dlz_bind9"); @@ -550,6 +1066,7 @@ static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) torture_suite_add_simple_test(suite, "spnego", test_dlz_bind9_spnego); torture_suite_add_simple_test(suite, "lookup", test_dlz_bind9_lookup); torture_suite_add_simple_test(suite, "zonedump", test_dlz_bind9_zonedump); + torture_suite_add_simple_test(suite, "update01", test_dlz_bind9_update01); return suite; } -- 1.9.1 From aabc52657877b6f08245bd59f79f45366d14b817 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 08:40:32 +0200 Subject: [PATCH 05/21] s4:dlz_bind9: let dlz_bind9 use dns_common_lookup() for name lookup Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Change-Id: I2632fa0ce120a978f6f400fa5cbf18a7fbbd64a3 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 96dcebe8c20b9aa954a96a4deabe16957576be2c) --- source4/dns_server/dlz_bind9.c | 68 +++++++++++----------------------------- source4/dns_server/wscript_build | 6 ++-- 2 files changed, 21 insertions(+), 53 deletions(-) diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c index 01700a5..5cb9428 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -37,7 +37,7 @@ #include "messaging/messaging.h" #include "lib/cmdline/popt_common.h" #include "dlz_minimal.h" - +#include "dns_server/dnsserver_common.h" struct b9_options { const char *url; @@ -801,11 +801,10 @@ static isc_result_t dlz_lookup_types(struct dlz_bind9_data *state, const char **types) { TALLOC_CTX *tmp_ctx = talloc_new(state); - const char *attrs[] = { "dnsRecord", NULL }; - int ret = LDB_SUCCESS, i; - struct ldb_result *res; - struct ldb_message_element *el; struct ldb_dn *dn; + WERROR werr = WERR_DNS_ERROR_NAME_DOES_NOT_EXIST; + struct dnsp_DnssrvRpcRecord *records = NULL; + uint16_t num_records = 0, i; for (i=0; zone_prefixes[i]; i++) { dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(state->samdb)); @@ -819,38 +818,21 @@ static isc_result_t dlz_lookup_types(struct dlz_bind9_data *state, return ISC_R_NOMEMORY; } - ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, - attrs, "objectClass=dnsNode"); - if (ret == LDB_SUCCESS) { + werr = dns_common_lookup(state->samdb, tmp_ctx, dn, + &records, &num_records, NULL); + if (W_ERROR_IS_OK(werr)) { break; } } - if (ret != LDB_SUCCESS || res->count == 0) { + if (!W_ERROR_IS_OK(werr)) { talloc_free(tmp_ctx); return ISC_R_NOTFOUND; } - el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); - if (el == NULL || el->num_values == 0) { - talloc_free(tmp_ctx); - return ISC_R_NOTFOUND; - } - - for (i=0; inum_values; i++) { - struct dnsp_DnssrvRpcRecord rec; - enum ndr_err_code ndr_err; + for (i=0; i < num_records; i++) { isc_result_t result; - ndr_err = ndr_pull_struct_blob(&el->values[i], tmp_ctx, &rec, - (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s", - ldb_dn_get_linearized(dn)); - talloc_free(tmp_ctx); - return ISC_R_FAILURE; - } - - result = b9_putrr(state, lookup, &rec, types); + result = b9_putrr(state, lookup, &records[i], types); if (result != ISC_R_SUCCESS) { talloc_free(tmp_ctx); return result; @@ -1059,39 +1041,25 @@ _PUBLIC_ void dlz_closeversion(const char *zone, isc_boolean_t commit, */ static bool b9_has_soa(struct dlz_bind9_data *state, struct ldb_dn *dn, const char *zone) { - const char *attrs[] = { "dnsRecord", NULL }; - struct ldb_result *res; - struct ldb_message_element *el; TALLOC_CTX *tmp_ctx = talloc_new(state); - int ret, i; + WERROR werr; + struct dnsp_DnssrvRpcRecord *records = NULL; + uint16_t num_records = 0, i; if (!ldb_dn_add_child_fmt(dn, "DC=@,DC=%s", zone)) { talloc_free(tmp_ctx); return false; } - ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, - attrs, "objectClass=dnsNode"); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return false; - } - - el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); - if (el == NULL) { + werr = dns_common_lookup(state->samdb, tmp_ctx, dn, + &records, &num_records, NULL); + if (!W_ERROR_IS_OK(werr)) { talloc_free(tmp_ctx); return false; } - for (i=0; inum_values; i++) { - struct dnsp_DnssrvRpcRecord rec; - enum ndr_err_code ndr_err; - ndr_err = ndr_pull_struct_blob(&el->values[i], tmp_ctx, &rec, - (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - continue; - } - if (rec.wType == DNS_TYPE_SOA) { + for (i=0; i < num_records; i++) { + if (records[i].wType == DNS_TYPE_SOA) { talloc_free(tmp_ctx); return true; } diff --git a/source4/dns_server/wscript_build b/source4/dns_server/wscript_build index 66e6b72..a92ab67 100644 --- a/source4/dns_server/wscript_build +++ b/source4/dns_server/wscript_build @@ -24,7 +24,7 @@ bld.SAMBA_LIBRARY('dlz_bind9', link_name='modules/bind9/dlz_bind9.so', realname='dlz_bind9.so', install_path='${MODULESDIR}/bind9', - deps='samba-hostconfig samdb-common gensec popt', + deps='samba-hostconfig samdb-common gensec popt dnsserver_common', enabled=bld.AD_DC_BUILD_IS_ENABLED()) bld.SAMBA_LIBRARY('dlz_bind9_9', @@ -34,12 +34,12 @@ bld.SAMBA_LIBRARY('dlz_bind9_9', link_name='modules/bind9/dlz_bind9_9.so', realname='dlz_bind9_9.so', install_path='${MODULESDIR}/bind9', - deps='samba-hostconfig samdb-common gensec popt', + deps='samba-hostconfig samdb-common gensec popt dnsserver_common', enabled=bld.AD_DC_BUILD_IS_ENABLED()) bld.SAMBA_LIBRARY('dlz_bind9_for_torture', source='dlz_bind9.c', cflags='-DBIND_VERSION_9_8', private_library=True, - deps='samba-hostconfig samdb-common gensec popt', + deps='samba-hostconfig samdb-common gensec popt dnsserver_common', enabled=bld.AD_DC_BUILD_IS_ENABLED()) -- 1.9.1 From fce69fd0848a57e9bdb15a777bfd6b27fc0235fa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 17:59:08 +0200 Subject: [PATCH 06/21] s4:dlz_bind9: let dlz_bind9 use dns_common_extract() Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Change-Id: I7c661964a3da1a1981f022a06b9bef25bbd33479 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit dedcf30fd12821c272002e3b4cbfda4ca38650fd) --- source4/dns_server/dlz_bind9.c | 118 +++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 57 deletions(-) diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c index 5cb9428..a433acc 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -911,6 +911,9 @@ _PUBLIC_ isc_result_t dlz_allnodes(const char *zone, void *dbdata, TALLOC_CTX *el_ctx = talloc_new(tmp_ctx); const char *rdn, *name; const struct ldb_val *v; + WERROR werr; + struct dnsp_DnssrvRpcRecord *recs = NULL; + uint16_t num_recs = 0; el = ldb_msg_find_element(res->msgs[i], "dnsRecord"); if (el == NULL || el->num_values == 0) { @@ -944,20 +947,18 @@ _PUBLIC_ isc_result_t dlz_allnodes(const char *zone, void *dbdata, return ISC_R_NOMEMORY; } - for (j=0; jnum_values; j++) { - struct dnsp_DnssrvRpcRecord rec; - enum ndr_err_code ndr_err; - isc_result_t result; + werr = dns_common_extract(el, el_ctx, &recs, &num_recs); + if (!W_ERROR_IS_OK(werr)) { + state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", + ldb_dn_get_linearized(dn), win_errstr(werr)); + talloc_free(el_ctx); + continue; + } - ndr_err = ndr_pull_struct_blob(&el->values[j], el_ctx, &rec, - (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s", - ldb_dn_get_linearized(dn)); - continue; - } + for (j=0; j < num_recs; j++) { + isc_result_t result; - result = b9_putnamedrr(state, allnodes, name, &rec); + result = b9_putnamedrr(state, allnodes, name, &recs[j]); if (result != ISC_R_SUCCESS) { continue; } @@ -1462,8 +1463,11 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo const char *attrs[] = { "dnsRecord", NULL }; int ret, i; struct ldb_message_element *el; + struct dnsp_DnssrvRpcRecord *recs = NULL; + uint16_t num_recs = 0; enum ndr_err_code ndr_err; NTTIME t; + WERROR werr; if (state->transaction_token != (void*)version) { state->log(ISC_LOG_INFO, "samba_dlz: bad transaction version"); @@ -1523,22 +1527,19 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo } } + werr = dns_common_extract(el, rec, &recs, &num_recs); + if (!W_ERROR_IS_OK(werr)) { + state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", + ldb_dn_get_linearized(dn), win_errstr(werr)); + talloc_free(rec); + return ISC_R_FAILURE; + } + /* there are existing records. We need to see if this will * replace a record or add to it */ - for (i=0; inum_values; i++) { - struct dnsp_DnssrvRpcRecord rec2; - - ndr_err = ndr_pull_struct_blob(&el->values[i], rec, &rec2, - (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s", - ldb_dn_get_linearized(dn)); - talloc_free(rec); - return ISC_R_FAILURE; - } - - if (b9_record_match(state, rec, &rec2)) { + for (i=0; i < num_recs; i++) { + if (b9_record_match(state, rec, &recs[i])) { break; } } @@ -1597,7 +1598,9 @@ _PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, vo const char *attrs[] = { "dnsRecord", NULL }; int ret, i; struct ldb_message_element *el; - enum ndr_err_code ndr_err; + struct dnsp_DnssrvRpcRecord *recs = NULL; + uint16_t num_recs = 0; + WERROR werr; if (state->transaction_token != (void*)version) { state->log(ISC_LOG_ERROR, "samba_dlz: bad transaction version"); @@ -1639,19 +1642,16 @@ _PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, vo return ISC_R_FAILURE; } - for (i=0; inum_values; i++) { - struct dnsp_DnssrvRpcRecord rec2; - - ndr_err = ndr_pull_struct_blob(&el->values[i], rec, &rec2, - (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s", - ldb_dn_get_linearized(dn)); - talloc_free(rec); - return ISC_R_FAILURE; - } + werr = dns_common_extract(el, rec, &recs, &num_recs); + if (!W_ERROR_IS_OK(werr)) { + state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", + ldb_dn_get_linearized(dn), win_errstr(werr)); + talloc_free(rec); + return ISC_R_FAILURE; + } - if (b9_record_match(state, rec, &rec2)) { + for (i=0; i < num_recs; i++) { + if (b9_record_match(state, rec, &recs[i])) { break; } } @@ -1703,11 +1703,15 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * isc_result_t result; struct ldb_result *res; const char *attrs[] = { "dnsRecord", NULL }; - int ret, i; + int ret; struct ldb_message_element *el; - enum ndr_err_code ndr_err; + int vi = 0; enum dns_record_type dns_type; bool found = false; + struct dnsp_DnssrvRpcRecord *recs = NULL; + uint16_t num_recs = 0; + uint16_t ri = 0; + WERROR werr; if (state->transaction_token != (void*)version) { state->log(ISC_LOG_ERROR, "samba_dlz: bad transaction version"); @@ -1743,27 +1747,27 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * return ISC_R_NOTFOUND; } - for (i=0; inum_values; i++) { - struct dnsp_DnssrvRpcRecord rec2; + werr = dns_common_extract(el, tmp_ctx, &recs, &num_recs); + if (!W_ERROR_IS_OK(werr)) { + state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", + ldb_dn_get_linearized(dn), win_errstr(werr)); + talloc_free(tmp_ctx); + return ISC_R_FAILURE; + } - ndr_err = ndr_pull_struct_blob(&el->values[i], tmp_ctx, &rec2, - (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s", - ldb_dn_get_linearized(dn)); - talloc_free(tmp_ctx); - return ISC_R_FAILURE; + for (ri=0; ri < num_recs; ri++) { + if (dns_type != recs[ri].wType) { + vi += 1; + continue; } - if (dns_type == rec2.wType) { - if (i < el->num_values-1) { - memmove(&el->values[i], &el->values[i+1], - sizeof(el->values[0])*((el->num_values-1)-i)); - } - el->num_values--; - i--; - found = true; + found = true; + + if (vi < el->num_values-1) { + memmove(&el->values[vi], &el->values[vi+1], + sizeof(el->values[0])*((el->num_values-1)-vi)); } + el->num_values--; } if (!found) { -- 1.9.1 From df8810d7fc4814f6fb301cdbf27cd506e6913905 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 18:51:39 +0200 Subject: [PATCH 07/21] s4:dlz_bind9: let dlz_bind9 use dns_common_replace() Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Change-Id: I2fd2503230cbf89445594e49f39ac321769ff06e Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit fd952bf814835c4860ab10794225fbd583ee3ad5) --- source4/dns_server/dlz_bind9.c | 127 ++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 77 deletions(-) diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c index a433acc..b65545c 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -1300,32 +1300,15 @@ static isc_result_t b9_add_record(struct dlz_bind9_data *state, const char *name struct ldb_dn *dn, struct dnsp_DnssrvRpcRecord *rec) { - struct ldb_message *msg; - enum ndr_err_code ndr_err; - struct ldb_val v; - int ret; - - msg = ldb_msg_new(rec); - if (msg == NULL) { - return ISC_R_NOMEMORY; - } - msg->dn = dn; - ret = ldb_msg_add_string(msg, "objectClass", "dnsNode"); - if (ret != LDB_SUCCESS) { - return ISC_R_FAILURE; - } - - ndr_err = ndr_push_struct_blob(&v, rec, rec, (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ISC_R_FAILURE; - } - ret = ldb_msg_add_value(msg, "dnsRecord", &v, NULL); - if (ret != LDB_SUCCESS) { - return ISC_R_FAILURE; - } + WERROR werr; - ret = ldb_add(state->samdb, msg); - if (ret != LDB_SUCCESS) { + werr = dns_common_replace(state->samdb, rec, dn, + true,/* needs_add */ + state->soa_serial, + rec, 1); + if (!W_ERROR_IS_OK(werr)) { + state->log(ISC_LOG_ERROR, "samba_dlz: failed to add %s - %s", + ldb_dn_get_linearized(dn), win_errstr(werr)); return ISC_R_FAILURE; } @@ -1465,7 +1448,6 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo struct ldb_message_element *el; struct dnsp_DnssrvRpcRecord *recs = NULL; uint16_t num_recs = 0; - enum ndr_err_code ndr_err; NTTIME t; WERROR werr; @@ -1484,7 +1466,6 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo t /= 3600; /* convert to hours */ rec->rank = DNS_RANK_ZONE; - rec->dwSerial = state->soa_serial; rec->dwTimeStamp = (uint32_t)t; if (!b9_parse(state, rdatastr, rec)) { @@ -1543,25 +1524,26 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo break; } } - if (i == el->num_values) { + if (i == UINT16_MAX) { + state->log(ISC_LOG_ERROR, "samba_dlz: failed to already %u dnsRecord values for %s", + i, ldb_dn_get_linearized(dn)); + talloc_free(rec); + return ISC_R_FAILURE; + } + + if (i == num_recs) { /* adding a new value */ - el->values = talloc_realloc(el, el->values, struct ldb_val, el->num_values+1); - if (el->values == NULL) { + recs = talloc_realloc(rec, recs, + struct dnsp_DnssrvRpcRecord, + num_recs + 1); + if (recs == NULL) { talloc_free(rec); return ISC_R_NOMEMORY; } - el->num_values++; - } - - ndr_err = ndr_push_struct_blob(&el->values[i], rec, rec, - (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to push dnsRecord for %s", - ldb_dn_get_linearized(dn)); - talloc_free(rec); - return ISC_R_FAILURE; + num_recs++; } + recs[i] = *rec; if (!b9_set_session_info(state, name)) { talloc_free(rec); @@ -1569,12 +1551,14 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo } /* modify the record */ - el->flags = LDB_FLAG_MOD_REPLACE; - ret = ldb_modify(state->samdb, res->msgs[0]); + werr = dns_common_replace(state->samdb, rec, dn, + false,/* needs_add */ + state->soa_serial, + recs, num_recs); b9_reset_session_info(state); - if (ret != LDB_SUCCESS) { + if (!W_ERROR_IS_OK(werr)) { state->log(ISC_LOG_ERROR, "samba_dlz: failed to modify %s - %s", - ldb_dn_get_linearized(dn), ldb_errstring(state->samdb)); + ldb_dn_get_linearized(dn), win_errstr(werr)); talloc_free(rec); return ISC_R_FAILURE; } @@ -1652,35 +1636,31 @@ _PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, vo for (i=0; i < num_recs; i++) { if (b9_record_match(state, rec, &recs[i])) { + recs[i] = (struct dnsp_DnssrvRpcRecord) { + .wType = DNS_TYPE_TOMBSTONE, + }; break; } } - if (i == el->num_values) { + if (i == num_recs) { talloc_free(rec); return ISC_R_NOTFOUND; } - if (i < el->num_values-1) { - memmove(&el->values[i], &el->values[i+1], sizeof(el->values[0])*((el->num_values-1)-i)); - } - el->num_values--; - if (!b9_set_session_info(state, name)) { talloc_free(rec); return ISC_R_FAILURE; } - if (el->num_values == 0) { - el->flags = LDB_FLAG_MOD_DELETE; - } else { - el->flags = LDB_FLAG_MOD_REPLACE; - } - ret = ldb_modify(state->samdb, res->msgs[0]); - + /* modify the record */ + werr = dns_common_replace(state->samdb, rec, dn, + false,/* needs_add */ + state->soa_serial, + recs, num_recs); b9_reset_session_info(state); - if (ret != LDB_SUCCESS) { + if (!W_ERROR_IS_OK(werr)) { state->log(ISC_LOG_ERROR, "samba_dlz: failed to modify %s - %s", - ldb_dn_get_linearized(dn), ldb_errstring(state->samdb)); + ldb_dn_get_linearized(dn), win_errstr(werr)); talloc_free(rec); return ISC_R_FAILURE; } @@ -1705,7 +1685,6 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * const char *attrs[] = { "dnsRecord", NULL }; int ret; struct ldb_message_element *el; - int vi = 0; enum dns_record_type dns_type; bool found = false; struct dnsp_DnssrvRpcRecord *recs = NULL; @@ -1757,17 +1736,13 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * for (ri=0; ri < num_recs; ri++) { if (dns_type != recs[ri].wType) { - vi += 1; continue; } found = true; - - if (vi < el->num_values-1) { - memmove(&el->values[vi], &el->values[vi+1], - sizeof(el->values[0])*((el->num_values-1)-vi)); - } - el->num_values--; + recs[ri] = (struct dnsp_DnssrvRpcRecord) { + .wType = DNS_TYPE_TOMBSTONE, + }; } if (!found) { @@ -1780,17 +1755,15 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * return ISC_R_FAILURE; } - if (el->num_values == 0) { - el->flags = LDB_FLAG_MOD_DELETE; - } else { - el->flags = LDB_FLAG_MOD_REPLACE; - } - ret = ldb_modify(state->samdb, res->msgs[0]); - + /* modify the record */ + werr = dns_common_replace(state->samdb, tmp_ctx, dn, + false,/* needs_add */ + state->soa_serial, + recs, num_recs); b9_reset_session_info(state); - if (ret != LDB_SUCCESS) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to delete type %s in %s - %s", - type, ldb_dn_get_linearized(dn), ldb_errstring(state->samdb)); + if (!W_ERROR_IS_OK(werr)) { + state->log(ISC_LOG_ERROR, "samba_dlz: failed to modify %s - %s", + ldb_dn_get_linearized(dn), win_errstr(werr)); talloc_free(tmp_ctx); return ISC_R_FAILURE; } -- 1.9.1 From 1fe31cfae8c3a32868a0fd7566276022213e6e5b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 20:12:08 +0200 Subject: [PATCH 08/21] s4:dlz_bind9: let dlz_bind9 use dns_common_lookup() before removing records Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 11bbfd932c113b3222bc93d59702271a3777b6f3) --- source4/dns_server/dlz_bind9.c | 53 ++++++------------------------------------ 1 file changed, 7 insertions(+), 46 deletions(-) diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c index b65545c..460976e 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -1578,12 +1578,9 @@ _PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, vo struct dnsp_DnssrvRpcRecord *rec; struct ldb_dn *dn; isc_result_t result; - struct ldb_result *res; - const char *attrs[] = { "dnsRecord", NULL }; - int ret, i; - struct ldb_message_element *el; struct dnsp_DnssrvRpcRecord *recs = NULL; uint16_t num_recs = 0; + uint16_t i; WERROR werr; if (state->transaction_token != (void*)version) { @@ -1610,28 +1607,11 @@ _PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, vo } /* get the existing records */ - ret = ldb_search(state->samdb, rec, &res, dn, LDB_SCOPE_BASE, attrs, "objectClass=dnsNode"); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - talloc_free(rec); - return ISC_R_NOTFOUND; - } - - /* there are existing records. We need to see if any match - */ - el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); - if (el == NULL || el->num_values == 0) { - state->log(ISC_LOG_ERROR, "samba_dlz: no dnsRecord attribute for %s", - ldb_dn_get_linearized(dn)); - talloc_free(rec); - return ISC_R_FAILURE; - } - - werr = dns_common_extract(el, rec, &recs, &num_recs); + werr = dns_common_lookup(state->samdb, rec, dn, + &recs, &num_recs, NULL); if (!W_ERROR_IS_OK(werr)) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", - ldb_dn_get_linearized(dn), win_errstr(werr)); talloc_free(rec); - return ISC_R_FAILURE; + return ISC_R_NOTFOUND; } for (i=0; i < num_recs; i++) { @@ -1681,10 +1661,6 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; isc_result_t result; - struct ldb_result *res; - const char *attrs[] = { "dnsRecord", NULL }; - int ret; - struct ldb_message_element *el; enum dns_record_type dns_type; bool found = false; struct dnsp_DnssrvRpcRecord *recs = NULL; @@ -1712,26 +1688,11 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * } /* get the existing records */ - ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, "objectClass=dnsNode"); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - talloc_free(tmp_ctx); - return ISC_R_NOTFOUND; - } - - /* there are existing records. We need to see if any match the type - */ - el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); - if (el == NULL || el->num_values == 0) { - talloc_free(tmp_ctx); - return ISC_R_NOTFOUND; - } - - werr = dns_common_extract(el, tmp_ctx, &recs, &num_recs); + werr = dns_common_lookup(state->samdb, tmp_ctx, dn, + &recs, &num_recs, NULL); if (!W_ERROR_IS_OK(werr)) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", - ldb_dn_get_linearized(dn), win_errstr(werr)); talloc_free(tmp_ctx); - return ISC_R_FAILURE; + return ISC_R_NOTFOUND; } for (ri=0; ri < num_recs; ri++) { -- 1.9.1 From 1b338845869fe817830682c952d9899140a302fc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 31 Jul 2014 09:30:16 +0200 Subject: [PATCH 09/21] s4:dlz_bind9: let dlz_bind9 use dns_common_lookup() before add/modify Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Wed Aug 27 15:21:19 CEST 2014 on sn-devel-104 (cherry picked from commit d68a2ebecd244181b1238635ee54dadd05835525) --- source4/dns_server/dlz_bind9.c | 77 ++++++++++++------------------------------ 1 file changed, 21 insertions(+), 56 deletions(-) diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c index 460976e..38b765a 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -1292,29 +1292,6 @@ _PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const return ISC_TRUE; } - -/* - add a new record - */ -static isc_result_t b9_add_record(struct dlz_bind9_data *state, const char *name, - struct ldb_dn *dn, - struct dnsp_DnssrvRpcRecord *rec) -{ - WERROR werr; - - werr = dns_common_replace(state->samdb, rec, dn, - true,/* needs_add */ - state->soa_serial, - rec, 1); - if (!W_ERROR_IS_OK(werr)) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to add %s - %s", - ldb_dn_get_linearized(dn), win_errstr(werr)); - return ISC_R_FAILURE; - } - - return ISC_R_SUCCESS; -} - /* see if two DNS names are the same */ @@ -1442,12 +1419,12 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo struct dnsp_DnssrvRpcRecord *rec; struct ldb_dn *dn; isc_result_t result; - struct ldb_result *res; - const char *attrs[] = { "dnsRecord", NULL }; - int ret, i; - struct ldb_message_element *el; + bool tombstoned = false; + bool needs_add = false; struct dnsp_DnssrvRpcRecord *recs = NULL; uint16_t num_recs = 0; + uint16_t first = 0; + uint16_t i; NTTIME t; WERROR werr; @@ -1482,33 +1459,12 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo } /* get any existing records */ - ret = ldb_search(state->samdb, rec, &res, dn, LDB_SCOPE_BASE, attrs, "objectClass=dnsNode"); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - if (!b9_set_session_info(state, name)) { - talloc_free(rec); - return ISC_R_FAILURE; - } - result = b9_add_record(state, name, dn, rec); - b9_reset_session_info(state); - talloc_free(rec); - if (result == ISC_R_SUCCESS) { - state->log(ISC_LOG_INFO, "samba_dlz: added %s %s", name, rdatastr); - } - return result; - } - - el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); - if (el == NULL) { - ret = ldb_msg_add_empty(res->msgs[0], "dnsRecord", LDB_FLAG_MOD_ADD, &el); - if (ret != LDB_SUCCESS) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to add dnsRecord for %s", - ldb_dn_get_linearized(dn)); - talloc_free(rec); - return ISC_R_FAILURE; - } + werr = dns_common_lookup(state->samdb, rec, dn, + &recs, &num_recs, &tombstoned); + if (W_ERROR_EQUAL(werr, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) { + needs_add = true; + werr = WERR_OK; } - - werr = dns_common_extract(el, rec, &recs, &num_recs); if (!W_ERROR_IS_OK(werr)) { state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", ldb_dn_get_linearized(dn), win_errstr(werr)); @@ -1516,10 +1472,18 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo return ISC_R_FAILURE; } + if (tombstoned) { + /* + * we need to keep the existing tombstone record + * and ignore it + */ + first = num_recs; + } + /* there are existing records. We need to see if this will * replace a record or add to it */ - for (i=0; i < num_recs; i++) { + for (i=first; i < num_recs; i++) { if (b9_record_match(state, rec, &recs[i])) { break; } @@ -1552,12 +1516,13 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo /* modify the record */ werr = dns_common_replace(state->samdb, rec, dn, - false,/* needs_add */ + needs_add, state->soa_serial, recs, num_recs); b9_reset_session_info(state); if (!W_ERROR_IS_OK(werr)) { - state->log(ISC_LOG_ERROR, "samba_dlz: failed to modify %s - %s", + state->log(ISC_LOG_ERROR, "samba_dlz: failed to %s %s - %s", + needs_add ? "add" : "modify", ldb_dn_get_linearized(dn), win_errstr(werr)); talloc_free(rec); return ISC_R_FAILURE; -- 1.9.1 From 04228e354104135439d2e8286a2f8d95a6a8abc9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Jul 2014 07:25:08 +0200 Subject: [PATCH 10/21] libcli/dns: add AAAA support to dns_hosts_file.c Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 7f18a3b58e7146e421653b85f509bb8503bd7402) --- libcli/dns/dns_hosts_file.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/libcli/dns/dns_hosts_file.c b/libcli/dns/dns_hosts_file.c index 94d1d97..5be5fca 100644 --- a/libcli/dns/dns_hosts_file.c +++ b/libcli/dns/dns_hosts_file.c @@ -88,9 +88,14 @@ static bool getdns_hosts_fileent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, cha if (next_token_talloc(ctx, &ptr, &name_type, NULL)) ++count; + if (count == 0) { + continue; + } if (next_token_talloc(ctx, &ptr, &name, NULL)) ++count; - if (name_type && strcasecmp(name_type, "A") == 0) { + if ((strcasecmp(name_type, "A") == 0) || + (strcasecmp(name_type, "AAAA") == 0)) + { if (next_token_talloc(ctx, &ptr, &ip, NULL)) ++count; } else if (name_type && strcasecmp(name_type, "SRV") == 0) { @@ -105,9 +110,11 @@ static bool getdns_hosts_fileent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, cha if (count <= 0) continue; - if (strcasecmp(name_type, "A") == 0) { + if ((strcasecmp(name_type, "A") == 0) || + (strcasecmp(name_type, "AAAA") == 0)) + { if (count != 3) { - DEBUG(0,("getdns_hosts_fileent: Ill formed hosts A record [%s]\n", + DEBUG(0,("getdns_hosts_fileent: Ill formed hosts A[AAA] record [%s]\n", line)); continue; } @@ -215,7 +222,7 @@ static NTSTATUS resolve_dns_hosts_file_as_dns_rr_recurse(const char *dns_hosts_f DEBUG(3,("resolve_dns_hosts: (%d) " "Attempting %s dns_hosts lookup for name %s\n", - level, srv_lookup ? "SRV" : "A", name)); + level, srv_lookup ? "SRV" : "A[AAA]", name)); fp = startdns_hosts_file(dns_hosts_file); @@ -278,7 +285,9 @@ static NTSTATUS resolve_dns_hosts_file_as_dns_rr_recurse(const char *dns_hosts_f mem_ctx, return_rr, return_count); talloc_free(ip_list_ctx); return status; - } else if (strcasecmp(name_type, "A") == 0) { + } else if ((strcasecmp(name_type, "A") == 0) || + (strcasecmp(name_type, "AAAA") == 0)) + { if (*return_count == 0) { /* We are happy to keep looking for other possible A record matches */ rr = talloc_zero(ip_list_ctx, @@ -405,11 +414,11 @@ NTSTATUS resolve_dns_hosts_file_as_dns_rr(const char *dns_hosts_file, if (NT_STATUS_IS_OK(status)) { DEBUG(3,("resolve_dns_hosts (dns_rr): " "Found %d %s result records for for name %s\n", - *return_count, srv_lookup ? "SRV" : "A", name)); + *return_count, srv_lookup ? "SRV" : "A[AAA]", name)); } else { DEBUG(3,("resolve_dns_hosts (dns_rr): " "failed to obtain %s result records for for name %s: %s\n", - srv_lookup ? "SRV" : "A", name, nt_errstr(status))); + srv_lookup ? "SRV" : "A[AAA]", name, nt_errstr(status))); } return status; } -- 1.9.1 From bf45bfc8fd94213c05670f8219b9ceb6bf697c8e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Jul 2014 07:25:08 +0200 Subject: [PATCH 11/21] libcli/dns: ignore NS entries in dns_hosts_file.c at a higher log level for now Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 3fcc4a545e936c2c0cf3f9f9a19646e1512f74d2) --- libcli/dns/dns_hosts_file.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libcli/dns/dns_hosts_file.c b/libcli/dns/dns_hosts_file.c index 5be5fca..4b1bc53 100644 --- a/libcli/dns/dns_hosts_file.c +++ b/libcli/dns/dns_hosts_file.c @@ -106,6 +106,9 @@ static bool getdns_hosts_fileent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, cha } else if (name_type && strcasecmp(name_type, "CNAME") == 0) { if (next_token_talloc(ctx, &ptr, &next_name, NULL)) ++count; + } else if (name_type && strcasecmp(name_type, "NS") == 0) { + if (next_token_talloc(ctx, &ptr, &next_name, NULL)) + ++count; } if (count <= 0) continue; @@ -155,6 +158,15 @@ static bool getdns_hosts_fileent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, cha if (!*pp_next_name) { return false; } + } else if (strcasecmp(name_type, "NS") == 0) { + if (count != 3) { + DEBUG(0,("getdns_hosts_fileent: Ill formed hosts NS record [%s]\n", + line)); + continue; + } + DEBUG(4, ("getdns_hosts_fileent: NS entry: %s %s %s\n", + name_type, name, next_name)); + continue; } else { DEBUG(0,("getdns_hosts_fileent: unknown type %s\n", name_type)); continue; -- 1.9.1 From 432f819a64fb1a86f82203f2d3719f62808ae794 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Jun 2014 17:21:16 +0200 Subject: [PATCH 12/21] selftest: export _IPV6 environment variables Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 0e7abb398dd826c082bbddb333b9faac361be064) --- selftest/README | 1 + selftest/selftest.pl | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/selftest/README b/selftest/README index c23d730..d9ad020 100644 --- a/selftest/README +++ b/selftest/README @@ -89,6 +89,7 @@ The environments are currently available include * REALM: Realm name * SERVER: DC host name * SERVER_IP: DC IPv4 address + * SERVER_IPV6: DC IPv6 address * NETBIOSNAME: DC NetBIOS name * NETIOSALIAS: DC NetBIOS alias diff --git a/selftest/selftest.pl b/selftest/selftest.pl index 2b1e3ce..25e0f93 100755 --- a/selftest/selftest.pl +++ b/selftest/selftest.pl @@ -663,35 +663,41 @@ my @exported_envvars = ( # domain controller stuff "DC_SERVER", "DC_SERVER_IP", + "DC_SERVER_IPV6", "DC_NETBIOSNAME", "DC_NETBIOSALIAS", # domain member "MEMBER_SERVER", "MEMBER_SERVER_IP", + "MEMBER_SERVER_IPV6", "MEMBER_NETBIOSNAME", "MEMBER_NETBIOSALIAS", # rpc proxy controller stuff "RPC_PROXY_SERVER", "RPC_PROXY_SERVER_IP", + "RPC_PROXY_SERVER_IPV6", "RPC_PROXY_NETBIOSNAME", "RPC_PROXY_NETBIOSALIAS", # domain controller stuff for Vampired DC "VAMPIRE_DC_SERVER", "VAMPIRE_DC_SERVER_IP", + "VAMPIRE_DC_SERVER_IPV6", "VAMPIRE_DC_NETBIOSNAME", "VAMPIRE_DC_NETBIOSALIAS", "PROMOTED_DC_SERVER", "PROMOTED_DC_SERVER_IP", + "PROMOTED_DC_SERVER_IPV6", "PROMOTED_DC_NETBIOSNAME", "PROMOTED_DC_NETBIOSALIAS", # server stuff "SERVER", "SERVER_IP", + "SERVER_IPV6", "NETBIOSNAME", "NETBIOSALIAS", -- 1.9.1 From 6750133060c5aefb95061634d4a1348b6487faf9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Jun 2014 17:21:16 +0200 Subject: [PATCH 13/21] selftest/Samba4: also bind to ipv6 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (similar to commit 5d4b36d1fec981e850d869edd2c98a6541b37114) --- selftest/target/Samba4.pm | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 8a3f51d..ac2fdd9 100644 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -516,7 +516,8 @@ sub provision_raw_prepare($$$$$$$$$$) $ctx->{tlsdir} = "$ctx->{privatedir}/tls"; $ctx->{ipv4} = "127.0.0.$swiface"; - $ctx->{interfaces} = "$ctx->{ipv4}/8"; + $ctx->{ipv6} = sprintf("fd00:0000:0000:0000:0000:0000:5357:5f%02x", $swiface); + $ctx->{interfaces} = "$ctx->{ipv4}/8 $ctx->{ipv6}/64"; push(@{$ctx->{directories}}, $ctx->{privatedir}); push(@{$ctx->{directories}}, $ctx->{etcdir}); @@ -691,6 +692,7 @@ nogroup:x:65534:nobody PIDDIR => $ctx->{piddir}, SERVER => $ctx->{hostname}, SERVER_IP => $ctx->{ipv4}, + SERVER_IPV6 => $ctx->{ipv6}, NETBIOSNAME => $ctx->{netbiosname}, DOMAIN => $ctx->{domain}, USERNAME => $ctx->{username}, @@ -914,12 +916,14 @@ sub provision_member($$$) $ret->{MEMBER_SERVER} = $ret->{SERVER}; $ret->{MEMBER_SERVER_IP} = $ret->{SERVER_IP}; + $ret->{MEMBER_SERVER_IPV6} = $ret->{SERVER_IPV6}; $ret->{MEMBER_NETBIOSNAME} = $ret->{NETBIOSNAME}; $ret->{MEMBER_USERNAME} = $ret->{USERNAME}; $ret->{MEMBER_PASSWORD} = $ret->{PASSWORD}; $ret->{DC_SERVER} = $dcvars->{DC_SERVER}; $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME}; $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME}; $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD}; @@ -1006,12 +1010,14 @@ sub provision_rpc_proxy($$$) $ret->{RPC_PROXY_SERVER} = $ret->{SERVER}; $ret->{RPC_PROXY_SERVER_IP} = $ret->{SERVER_IP}; + $ret->{RPC_PROXY_SERVER_IPV6} = $ret->{SERVER_IPV6}; $ret->{RPC_PROXY_NETBIOSNAME} = $ret->{NETBIOSNAME}; $ret->{RPC_PROXY_USERNAME} = $ret->{USERNAME}; $ret->{RPC_PROXY_PASSWORD} = $ret->{PASSWORD}; $ret->{DC_SERVER} = $dcvars->{DC_SERVER}; $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME}; $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME}; $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD}; @@ -1082,10 +1088,12 @@ sub provision_promoted_dc($$$) $ret->{PROMOTED_DC_SERVER} = $ret->{SERVER}; $ret->{PROMOTED_DC_SERVER_IP} = $ret->{SERVER_IP}; + $ret->{PROMOTED_DC_SERVER_IPV6} = $ret->{SERVER_IPV6}; $ret->{PROMOTED_DC_NETBIOSNAME} = $ret->{NETBIOSNAME}; $ret->{DC_SERVER} = $dcvars->{DC_SERVER}; $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME}; $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME}; $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD}; @@ -1143,10 +1151,12 @@ sub provision_vampire_dc($$$) $ret->{VAMPIRE_DC_SERVER} = $ret->{SERVER}; $ret->{VAMPIRE_DC_SERVER_IP} = $ret->{SERVER_IP}; + $ret->{VAMPIRE_DC_SERVER_IPV6} = $ret->{SERVER_IPV6}; $ret->{VAMPIRE_DC_NETBIOSNAME} = $ret->{NETBIOSNAME}; $ret->{DC_SERVER} = $dcvars->{DC_SERVER}; $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME}; $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME}; $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD}; @@ -1208,10 +1218,12 @@ sub provision_subdom_dc($$$) $ret->{SUBDOM_DC_SERVER} = $ret->{SERVER}; $ret->{SUBDOM_DC_SERVER_IP} = $ret->{SERVER_IP}; + $ret->{SUBDOM_DC_SERVER_IPV6} = $ret->{SERVER_IPV6}; $ret->{SUBDOM_DC_NETBIOSNAME} = $ret->{NETBIOSNAME}; $ret->{DC_SERVER} = $dcvars->{DC_SERVER}; $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME}; $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME}; $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD}; @@ -1242,6 +1254,7 @@ sub provision_dc($$) $ret->{NETBIOSALIAS} = "localdc1-a"; $ret->{DC_SERVER} = $ret->{SERVER}; $ret->{DC_SERVER_IP} = $ret->{SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME}; $ret->{DC_USERNAME} = $ret->{USERNAME}; $ret->{DC_PASSWORD} = $ret->{PASSWORD}; @@ -1385,10 +1398,12 @@ sub provision_rodc($$$) $ret->{RODC_DC_SERVER} = $ret->{SERVER}; $ret->{RODC_DC_SERVER_IP} = $ret->{SERVER_IP}; + $ret->{RODC_DC_SERVER_IPV6} = $ret->{SERVER_IPV6}; $ret->{RODC_DC_NETBIOSNAME} = $ret->{NETBIOSNAME}; $ret->{DC_SERVER} = $dcvars->{DC_SERVER}; $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME}; $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME}; $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD}; @@ -1503,6 +1518,7 @@ sub provision_plugin_s4_dc($$) $ret->{DC_SERVER} = $ret->{SERVER}; $ret->{DC_SERVER_IP} = $ret->{SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME}; $ret->{DC_USERNAME} = $ret->{USERNAME}; $ret->{DC_PASSWORD} = $ret->{PASSWORD}; @@ -1542,6 +1558,7 @@ sub provision_chgdcpass($$) $ret->{DC_SERVER} = $ret->{SERVER}; $ret->{DC_SERVER_IP} = $ret->{SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME}; $ret->{DC_USERNAME} = $ret->{USERNAME}; $ret->{DC_PASSWORD} = $ret->{PASSWORD}; -- 1.9.1 From 502e2baef4a07deede420141a3c343e91058a472 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Jun 2014 17:21:16 +0200 Subject: [PATCH 14/21] selftest/Samba3: also bind to ipv6 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (similar to commit a9545f3de7aaa0346735191953f78242017bd346) --- selftest/target/Samba3.pm | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index bc07403..91a4a2a 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -207,6 +207,7 @@ sub setup_s3dc($$) $vars->{DC_SERVER} = $vars->{SERVER}; $vars->{DC_SERVER_IP} = $vars->{SERVER_IP}; + $vars->{DC_SERVER_IPV6} = $vars->{SERVER_IPV6}; $vars->{DC_NETBIOSNAME} = $vars->{NETBIOSNAME}; $vars->{DC_USERNAME} = $vars->{USERNAME}; $vars->{DC_PASSWORD} = $vars->{PASSWORD}; @@ -250,6 +251,7 @@ sub setup_member($$$) $ret->{DC_SERVER} = $s3dcvars->{SERVER}; $ret->{DC_SERVER_IP} = $s3dcvars->{SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $s3dcvars->{SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $s3dcvars->{NETBIOSNAME}; $ret->{DC_USERNAME} = $s3dcvars->{USERNAME}; $ret->{DC_PASSWORD} = $s3dcvars->{PASSWORD}; @@ -321,6 +323,7 @@ sub setup_admember($$$$) $ret->{DC_SERVER} = $dcvars->{SERVER}; $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $dcvars->{SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $dcvars->{NETBIOSNAME}; $ret->{DC_USERNAME} = $dcvars->{USERNAME}; $ret->{DC_PASSWORD} = $dcvars->{PASSWORD}; @@ -400,6 +403,7 @@ sub setup_admember_rfc2307($$$$) $ret->{DC_SERVER} = $dcvars->{SERVER}; $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP}; + $ret->{DC_SERVER_IPV6} = $dcvars->{SERVER_IPV6}; $ret->{DC_NETBIOSNAME} = $dcvars->{NETBIOSNAME}; $ret->{DC_USERNAME} = $dcvars->{USERNAME}; $ret->{DC_PASSWORD} = $dcvars->{PASSWORD}; @@ -770,6 +774,7 @@ sub provision($$$$$$) my $swiface = Samba::get_interface($server); my %ret = (); my $server_ip = "127.0.0.$swiface"; + my $server_ipv6 = sprintf("fd00:0000:0000:0000:0000:0000:5357:5f%02x", $swiface); my $domain = "SAMBA-TEST"; my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `PATH=/usr/ucb:$ENV{PATH} whoami`); @@ -872,7 +877,7 @@ sub provision($$$$$$) close(MSDFS_TARGET); chmod 0666, $msdfs_target; symlink "msdfs:$server_ip\\ro-tmp", "$msdfs_shrdir/msdfs-src1"; - symlink "msdfs:$server_ip\\ro-tmp", "$msdfs_shrdir/deeppath/msdfs-src2"; + symlink "msdfs:$server_ipv6\\ro-tmp", "$msdfs_shrdir/deeppath/msdfs-src2"; my $conffile="$libdir/server.conf"; @@ -925,7 +930,7 @@ sub provision($$$$$$) print CONF " [global] netbios name = $server - interfaces = $server_ip/8 + interfaces = $server_ip/8 $server_ipv6/64 bind interfaces only = yes panic action = $self->{srcdir}/selftest/gdb_backtrace %d %\$(MAKE_TEST_BINARY) smbd:suicide mode = yes @@ -1176,7 +1181,8 @@ domadmins:X:$gid_domadmins: print "DONE\n"; open(DNS_UPDATE_LIST, ">$prefix/dns_update_list") or die("Unable to open $$prefix/dns_update_list"); - print DNS_UPDATE_LIST "A $server. $server_ip"; + print DNS_UPDATE_LIST "A $server. $server_ip\n"; + print DNS_UPDATE_LIST "AAAA $server. $server_ipv6\n"; close(DNS_UPDATE_LIST); if (system("$ENV{SRCDIR_ABS}/source4/scripting/bin/samba_dnsupdate --all-interfaces --use-file=$dns_host_file -s $conffile --update-list=$prefix/dns_update_list --no-substiutions --no-credentials") != 0) { @@ -1184,6 +1190,7 @@ domadmins:X:$gid_domadmins: } $ret{SERVER_IP} = $server_ip; + $ret{SERVER_IPV6} = $server_ipv6; $ret{NMBD_TEST_LOG} = "$prefix/nmbd_test.log"; $ret{NMBD_TEST_LOG_POS} = 0; $ret{WINBINDD_TEST_LOG} = "$prefix/winbindd_test.log"; -- 1.9.1 From 68679b9f51556ec63a6418d49b1935b99e82ffaa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 19 Aug 2014 10:33:11 +0200 Subject: [PATCH 15/21] python/join: use lowercase for the dnshostname. Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 5533d9c3db31ac86769288527ec20ad4e57f703c) --- python/samba/join.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/samba/join.py b/python/samba/join.py index 7d2f913..ee973a1 100644 --- a/python/samba/join.py +++ b/python/samba/join.py @@ -133,7 +133,7 @@ class dc_join(object): else: ctx.dns_backend = dns_backend - ctx.dnshostname = "%s.%s" % (ctx.myname, ctx.dnsdomain) + ctx.dnshostname = "%s.%s" % (ctx.myname.lower(), ctx.dnsdomain) ctx.realm = ctx.dnsdomain @@ -1198,7 +1198,7 @@ def join_subdomain(server=None, creds=None, lp=None, site=None, ctx.base_dn = samba.dn_from_dns_name(dnsdomain) ctx.domsid = str(security.random_sid()) ctx.acct_dn = None - ctx.dnshostname = "%s.%s" % (ctx.myname, ctx.dnsdomain) + ctx.dnshostname = "%s.%s" % (ctx.myname.lower(), ctx.dnsdomain) ctx.trustdom_pass = samba.generate_random_password(128, 128) ctx.userAccountControl = samba.dsdb.UF_SERVER_TRUST_ACCOUNT | samba.dsdb.UF_TRUSTED_FOR_DELEGATION -- 1.9.1 From 2b6ebfe809720e2a124097019c35380d6b8ca95f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Apr 2014 17:26:51 +0200 Subject: [PATCH 16/21] s4:samba_dnsupdate: don't lower case the registered names This matches Windows... Bug: https://bugzilla.samba.org/show_bug.cgi?id=9831 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit c5088f338a38850674399ec8fec9f8f146b5880f) --- source4/scripting/bin/samba_dnsupdate | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source4/scripting/bin/samba_dnsupdate b/source4/scripting/bin/samba_dnsupdate index 68b0f72..0384dd9 100755 --- a/source4/scripting/bin/samba_dnsupdate +++ b/source4/scripting/bin/samba_dnsupdate @@ -136,20 +136,20 @@ class dnsobj(object): self.existing_port = None self.existing_weight = None self.type = list[0] - self.name = list[1].lower() + self.name = list[1] if self.type == 'SRV': if len(list) < 4: raise Exception("Invalid DNS entry %r" % string_form) - self.dest = list[2].lower() + self.dest = list[2] self.port = list[3] elif self.type in ['A', 'AAAA']: self.ip = list[2] # usually $IP, which gets replaced elif self.type == 'CNAME': - self.dest = list[2].lower() + self.dest = list[2] elif self.type == 'NS': - self.dest = list[2].lower() + self.dest = list[2] else: - raise Exception("Received unexpected DNS reply of type %s" % self.type) + raise Exception("Received unexpected DNS reply of type %s: %s" % (self.type, string_form)) def __str__(self): if d.type == "A": -- 1.9.1 From e1c83027632c5c323188eac340b0b3447e42488e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Apr 2014 08:27:26 +0200 Subject: [PATCH 17/21] s4:samba_dnsupdate: fix dnsobj.__str__() We should not implicitly use the global variable 'd'. Bug: https://bugzilla.samba.org/show_bug.cgi?id=9831 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 6e853708def98545eeb6913b8a2dd59d439323e6) --- source4/scripting/bin/samba_dnsupdate | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source4/scripting/bin/samba_dnsupdate b/source4/scripting/bin/samba_dnsupdate index 0384dd9..1b21216 100755 --- a/source4/scripting/bin/samba_dnsupdate +++ b/source4/scripting/bin/samba_dnsupdate @@ -152,15 +152,15 @@ class dnsobj(object): raise Exception("Received unexpected DNS reply of type %s: %s" % (self.type, string_form)) def __str__(self): - if d.type == "A": + if self.type == "A": return "%s %s %s" % (self.type, self.name, self.ip) - if d.type == "AAAA": + if self.type == "AAAA": return "%s %s %s" % (self.type, self.name, self.ip) - if d.type == "SRV": + if self.type == "SRV": return "%s %s %s %s" % (self.type, self.name, self.dest, self.port) - if d.type == "CNAME": + if self.type == "CNAME": return "%s %s %s" % (self.type, self.name, self.dest) - if d.type == "NS": + if self.type == "NS": return "%s %s %s" % (self.type, self.name, self.dest) -- 1.9.1 From 675800fe6fefd5ea05072cf2b7ee5f4e698cf9fc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Apr 2014 08:29:40 +0200 Subject: [PATCH 18/21] s4:samba_dnsupdate: cache the already registered records This way we can delete records which are not used anymore. E.g. if the ip address changed. Bug: https://bugzilla.samba.org/show_bug.cgi?id=9831 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 25ec8e8656f66fe51a0d48718cdcfd8b209f6ca0) --- selftest/target/Samba3.pm | 2 +- source4/dsdb/dns/dns_update.c | 13 ++++ source4/scripting/bin/samba_dnsupdate | 117 +++++++++++++++++++++++++++++----- 3 files changed, 115 insertions(+), 17 deletions(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 91a4a2a..ba01154 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1185,7 +1185,7 @@ domadmins:X:$gid_domadmins: print DNS_UPDATE_LIST "AAAA $server. $server_ipv6\n"; close(DNS_UPDATE_LIST); - if (system("$ENV{SRCDIR_ABS}/source4/scripting/bin/samba_dnsupdate --all-interfaces --use-file=$dns_host_file -s $conffile --update-list=$prefix/dns_update_list --no-substiutions --no-credentials") != 0) { + if (system("$ENV{SRCDIR_ABS}/source4/scripting/bin/samba_dnsupdate --all-interfaces --use-file=$dns_host_file -s $conffile --update-list=$prefix/dns_update_list --update-cache=$prefix/dns_update_cache --no-substiutions --no-credentials") != 0) { die "Unable to update hostname into $dns_host_file"; } diff --git a/source4/dsdb/dns/dns_update.c b/source4/dsdb/dns/dns_update.c index 3e10447..aa617c6 100644 --- a/source4/dsdb/dns/dns_update.c +++ b/source4/dsdb/dns/dns_update.c @@ -397,6 +397,7 @@ struct dnsupdate_RODC_state { struct irpc_message *msg; struct dnsupdate_RODC *r; char *tmp_path; + char *tmp_path2; int fd; }; @@ -406,6 +407,9 @@ static int dnsupdate_RODC_destructor(struct dnsupdate_RODC_state *st) close(st->fd); } unlink(st->tmp_path); + if (st->tmp_path2 != NULL) { + unlink(st->tmp_path2); + } return 0; } @@ -483,6 +487,13 @@ static NTSTATUS dnsupdate_dnsupdate_RODC(struct irpc_message *msg, talloc_set_destructor(st, dnsupdate_RODC_destructor); + st->tmp_path2 = talloc_asprintf(st, "%s.cache", st->tmp_path); + if (!st->tmp_path2) { + talloc_free(st); + r->out.result = NT_STATUS_NO_MEMORY; + return NT_STATUS_OK; + } + sid_dn = ldb_dn_new_fmt(st, s->samdb, "", dom_sid_string(st, r->in.dom_sid)); if (!sid_dn) { talloc_free(st); @@ -575,6 +586,8 @@ static NTSTATUS dnsupdate_dnsupdate_RODC(struct irpc_message *msg, dns_update_command, "--update-list", st->tmp_path, + "--update-cache", + st->tmp_path2, NULL); NT_STATUS_HAVE_NO_MEMORY(req); diff --git a/source4/scripting/bin/samba_dnsupdate b/source4/scripting/bin/samba_dnsupdate index 1b21216..9c7c5e2 100755 --- a/source4/scripting/bin/samba_dnsupdate +++ b/source4/scripting/bin/samba_dnsupdate @@ -63,6 +63,7 @@ parser.add_option("--all-names", action="store_true") parser.add_option("--all-interfaces", action="store_true") parser.add_option("--use-file", type="string", help="Use a file, rather than real DNS calls") parser.add_option("--update-list", type="string", help="Add DNS names from the given file") +parser.add_option("--update-cache", type="string", help="Cache database of already registered records") parser.add_option("--fail-immediately", action='store_true', help="Exit on first failure") parser.add_option("--no-credentials", dest='nocreds', action='store_true', help="don't try and get credentials") parser.add_option("--no-substiutions", dest='nosubs', action='store_true', help="don't try and expands variables in file specified by --update-list") @@ -278,12 +279,14 @@ def get_subst_vars(samdb): return vars -def call_nsupdate(d): +def call_nsupdate(d, op="add"): """call nsupdate for an entry.""" global ccachename, nsupdate_cmd, krb5conf + assert(op in ["add", "delete"]) + if opts.verbose: - print "Calling nsupdate for %s" % d + print "Calling nsupdate for %s (%s)" % (d, op) if opts.use_file is not None: try: @@ -299,8 +302,13 @@ def call_nsupdate(d): wfile = os.fdopen(tmp_fd, 'a') rfile.seek(0) for line in rfile: + if op == "delete": + l = parse_dns_line(line, {}) + if str(l).lower() == str(d).lower(): + continue wfile.write(line) - wfile.write(str(d)+"\n") + if op == "add": + wfile.write(str(d)+"\n") os.rename(tmpfile, opts.use_file) fcntl.lockf(rfile, fcntl.LOCK_UN) return @@ -312,18 +320,18 @@ def call_nsupdate(d): if getattr(d, 'nameservers', None): f.write('server %s\n' % d.nameservers[0]) if d.type == "A": - f.write("update add %s %u A %s\n" % (normalised_name, default_ttl, d.ip)) + f.write("update %s %s %u A %s\n" % (op, normalised_name, default_ttl, d.ip)) if d.type == "AAAA": - f.write("update add %s %u AAAA %s\n" % (normalised_name, default_ttl, d.ip)) + f.write("update %s %s %u AAAA %s\n" % (op, normalised_name, default_ttl, d.ip)) if d.type == "SRV": - if d.existing_port is not None: + if op == "add" and d.existing_port is not None: f.write("update delete %s SRV 0 %s %s %s\n" % (normalised_name, d.existing_weight, d.existing_port, d.dest)) - f.write("update add %s %u SRV 0 100 %s %s\n" % (normalised_name, default_ttl, d.port, d.dest)) + f.write("update %s %s %u SRV 0 100 %s %s\n" % (op, normalised_name, default_ttl, d.port, d.dest)) if d.type == "CNAME": - f.write("update add %s %u CNAME %s\n" % (normalised_name, default_ttl, d.dest)) + f.write("update %s %s %u CNAME %s\n" % (op, normalised_name, default_ttl, d.dest)) if d.type == "NS": - f.write("update add %s %u NS %s\n" % (normalised_name, default_ttl, d.dest)) + f.write("update %s %s %u NS %s\n" % (op, normalised_name, default_ttl, d.dest)) if opts.verbose: f.write("show\n") f.write("send\n") @@ -359,10 +367,12 @@ def call_nsupdate(d): -def rodc_dns_update(d, t): +def rodc_dns_update(d, t, op): '''a single DNS update via the RODC netlogon call''' global sub_vars + assert(op in ["add", "delete"]) + if opts.verbose: print "Calling netlogon RODC update for %s" % d @@ -386,7 +396,10 @@ def rodc_dns_update(d, t): name.weight = 0 if d.port is not None: name.port = int(d.port) - name.dns_register = True + if op == "add": + name.dns_register = True + else: + name.dns_register = False dns_names.names = [ name ] site_name = sub_vars['SITE'].decode('utf-8') @@ -405,10 +418,12 @@ def rodc_dns_update(d, t): sys.exit(1) -def call_rodc_update(d): +def call_rodc_update(d, op="add"): '''RODCs need to use the netlogon API for nsupdate''' global lp, sub_vars + assert(op in ["add", "delete"]) + # we expect failure for 3268 if we aren't a GC if d.port is not None and int(d.port) == 3268: return @@ -428,7 +443,7 @@ def call_rodc_update(d): subname = samba.substitute_var(map[t], sub_vars) if subname.lower() == d.name.lower(): # found a match - do the update - rodc_dns_update(d, t) + rodc_dns_update(d, t, op) return if opts.verbose: print("Unable to map to netlogon DNS update: %s" % d) @@ -440,6 +455,11 @@ if opts.update_list: else: dns_update_list = lp.private_path('dns_update_list') +if opts.update_cache: + dns_update_cache = opts.update_cache +else: + dns_update_cache = lp.private_path('dns_update_cache') + # use our private krb5.conf to avoid problems with the wrong domain # bind9 nsupdate wants the default domain set krb5conf = lp.private_path('krb5.conf') @@ -458,8 +478,31 @@ else: # build up a list of update commands to pass to nsupdate update_list = [] dns_list = [] +cache_list = [] +delete_list = [] dup_set = set() +cache_set = set() + +rebuild_cache = False +try: + cfile = open(dns_update_cache, 'r+') +except IOError: + # Perhaps create it + cfile = open(dns_update_cache, 'w+') + # Open it for reading again, in case someone else got to it first + cfile = open(dns_update_cache, 'r+') +fcntl.lockf(cfile, fcntl.LOCK_EX) +for line in cfile: + line = line.strip() + if line == '' or line[0] == "#": + continue + c = parse_dns_line(line, {}) + if c is None: + continue + if str(c) not in cache_set: + cache_list.append(c) + cache_set.add(str(c)) # read each line, and check that the DNS name exists for line in file: @@ -497,17 +540,50 @@ for d in dns_list: # now check if the entries already exist on the DNS server for d in dns_list: + found = False + for c in cache_list: + if str(c).lower() == str(d).lower(): + found = True + break + if not found: + rebuild_cache = True if opts.all_names or not check_dns_name(d): update_list.append(d) -if len(update_list) == 0: +for c in cache_list: + found = False + for d in dns_list: + if str(c).lower() == str(d).lower(): + found = True + break + if found: + continue + rebuild_cache = True + if not opts.all_names and not check_dns_name(c): + continue + delete_list.append(c) + +if len(delete_list) == 0 and len(update_list) == 0 and not rebuild_cache: if opts.verbose: print "No DNS updates needed" sys.exit(0) # get our krb5 creds -if not opts.nocreds: - get_credentials(lp) +if len(delete_list) != 0 or len(update_list) != 0: + if not opts.nocreds: + get_credentials(lp) + +# ask nsupdate to delete entries as needed +for d in delete_list: + if am_rodc: + if d.name.lower() == domain.lower(): + continue + if not d.type in [ 'A', 'AAAA' ]: + call_rodc_update(d, op="delete") + else: + call_nsupdate(d, op="delete") + else: + call_nsupdate(d, op="delete") # ask nsupdate to add entries as needed for d in update_list: @@ -521,6 +597,15 @@ for d in update_list: else: call_nsupdate(d) +if rebuild_cache: + (file_dir, file_name) = os.path.split(dns_update_cache) + (tmp_fd, tmpfile) = tempfile.mkstemp(dir=file_dir, prefix=file_name, suffix="XXXXXX") + wfile = os.fdopen(tmp_fd, 'a') + for d in dns_list: + wfile.write(str(d)+"\n") + os.rename(tmpfile, dns_update_cache) +fcntl.lockf(cfile, fcntl.LOCK_UN) + # delete the ccache if we created it if ccachename is not None: os.unlink(ccachename) -- 1.9.1 From 0de06e5359b57f10261c98b34ad8b4b9f46534d5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Jul 2014 00:05:03 +0200 Subject: [PATCH 19/21] s4:samba_dnsupdate: don't try to be smart when verifying NS records We can't rely on the DNS delegation to be correct in the parent domain. What we really want is to check if we already have registered ourself as a NS record in our own domain. Bug: https://bugzilla.samba.org/show_bug.cgi?id=9831 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit b13974048b74c60028d8387eb7fe4fc7734f0a91) --- source4/scripting/bin/samba_dnsupdate | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/source4/scripting/bin/samba_dnsupdate b/source4/scripting/bin/samba_dnsupdate index 9c7c5e2..0d001ac 100755 --- a/source4/scripting/bin/samba_dnsupdate +++ b/source4/scripting/bin/samba_dnsupdate @@ -203,25 +203,6 @@ def check_dns_name(d): return False resolver = dns.resolver.Resolver() - if d.type == "NS": - # we need to lookup the nameserver for the parent domain, - # and use that to check the NS record - parent_domain = '.'.join(normalised_name.split('.')[1:]) - try: - ans = resolver.query(parent_domain, 'NS') - except dns.exception.DNSException: - if opts.verbose: - print "Failed to find parent NS for %s" % d - return False - nameservers = set() - for i in range(len(ans)): - try: - ns = resolver.query(str(ans[i]), 'A') - except dns.exception.DNSException: - continue - for j in range(len(ns)): - nameservers.add(str(ns[j])) - d.nameservers = list(nameservers) try: if getattr(d, 'nameservers', None): -- 1.9.1 From 28c9c9cd722fdf8cdbd58b84a9f65c51993c0787 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Apr 2014 17:33:50 +0200 Subject: [PATCH 20/21] s4:samba_dnsupdate: provide more substitution variables e.g. IF_RODC This will make the dns_update_list more flexible. Bug: https://bugzilla.samba.org/show_bug.cgi?id=9831 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit f1544e8d1de995aa304d63352d313ace8fea6ca5) --- source4/scripting/bin/samba_dnsupdate | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/source4/scripting/bin/samba_dnsupdate b/source4/scripting/bin/samba_dnsupdate index 0d001ac..30d5608 100755 --- a/source4/scripting/bin/samba_dnsupdate +++ b/source4/scripting/bin/samba_dnsupdate @@ -42,6 +42,7 @@ import samba import optparse from samba import getopt as options from ldb import SCOPE_BASE +from samba import dsdb from samba.auth import system_session from samba.samdb import SamDB from samba.dcerpc import netlogon, winbind @@ -168,10 +169,13 @@ class dnsobj(object): def parse_dns_line(line, sub_vars): """parse a DNS line from.""" if line.startswith("SRV _ldap._tcp.pdc._msdcs.") and not samdb.am_pdc(): + # We keep this as compat to the dns_update_list of 4.0/4.1 if opts.verbose: print "Skipping PDC entry (%s) as we are not a PDC" % line return None subline = samba.substitute_var(line, sub_vars) + if subline == '' or subline[0] == "#": + return None return dnsobj(subline) @@ -255,7 +259,60 @@ def get_subst_vars(samdb): res = samdb.search(base=samdb.get_default_basedn(), scope=SCOPE_BASE, attrs=["objectGUID"]) guid = samdb.schema_format_value("objectGUID", res[0]['objectGUID'][0]) vars['DOMAINGUID'] = guid + + vars['IF_DC'] = "" + vars['IF_RWDC'] = "# " + vars['IF_RODC'] = "# " + vars['IF_PDC'] = "# " + vars['IF_GC'] = "# " + vars['IF_RWGC'] = "# " + vars['IF_ROGC'] = "# " + vars['IF_DNS_DOMAIN'] = "# " + vars['IF_RWDNS_DOMAIN'] = "# " + vars['IF_RODNS_DOMAIN'] = "# " + vars['IF_DNS_FOREST'] = "# " + vars['IF_RWDNS_FOREST'] = "# " + vars['IF_R0DNS_FOREST'] = "# " + am_rodc = samdb.am_rodc() + if am_rodc: + vars['IF_RODC'] = "" + else: + vars['IF_RWDC'] = "" + + if samdb.am_pdc(): + vars['IF_PDC'] = "" + + # check if we "are DNS server" + res = samdb.search(base=samdb.get_config_basedn(), + expression='(objectguid=%s)' % vars['NTDSGUID'], + attrs=["options", "msDS-hasMasterNCs"]) + + if len(res) == 1: + if "options" in res[0]: + options = int(res[0]["options"][0]) + if (options & dsdb.DS_NTDSDSA_OPT_IS_GC) != 0: + vars['IF_GC'] = "" + if am_rodc: + vars['IF_ROGC'] = "" + else: + vars['IF_RWGC'] = "" + + basedn = str(samdb.get_default_basedn()) + if "msDS-hasMasterNCs" in res[0]: + for e in res[0]["msDS-hasMasterNCs"]: + if str(e) == "DC=DomainDnsZones,%s" % basedn: + vars['IF_DNS_DOMAIN'] = "" + if am_rodc: + vars['IF_RODNS_DOMAIN'] = "" + else: + vars['IF_RWDNS_DOMAIN'] = "" + if str(e) == "DC=ForestDnsZones,%s" % basedn: + vars['IF_DNS_FOREST'] = "" + if am_rodc: + vars['IF_RODNS_FOREST'] = "" + else: + vars['IF_RWDNS_FOREST'] = "" return vars -- 1.9.1 From 466d9d3c50aec644de7ca451310215581b754abd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Apr 2014 18:54:13 +0200 Subject: [PATCH 21/21] s4:setup/dns_update_list: make use of the new substitution variables This let us register the same names as Windows Servers. We only exception are the NS records. In future we could add them by using something like this: samba-tool dns add ${HOSTNAME} ${DNSDOMAIN} @ NS ${HOSTNAME} samba-tool dns add ${HOSTNAME} _msdcs.${DNSFOREST} @ NS ${HOSTNAME} samba-tool dns add ${HOSTNAME} ${DNSFOREST} _msdcs NS ${HOSTNAME} Bug: https://bugzilla.samba.org/show_bug.cgi?id=9831 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Tue Aug 26 11:38:54 CEST 2014 on sn-devel-104 (cherry picked from commit 4383ec5b83d12bd19749582217f082cbaa31a128) --- source4/setup/dns_update_list | 82 ++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/source4/setup/dns_update_list b/source4/setup/dns_update_list index 4da0398..deac459 100644 --- a/source4/setup/dns_update_list +++ b/source4/setup/dns_update_list @@ -1,39 +1,49 @@ # this is a list of DNS entries which will be put into DNS using # dynamic DNS update. It is processed by the samba_dnsupdate script -A ${DNSDOMAIN} $IP -A ${HOSTNAME} $IP -AAAA ${DNSDOMAIN} $IP -AAAA ${HOSTNAME} $IP +A ${HOSTNAME} $IP +AAAA ${HOSTNAME} $IP + +# RW domain controller +${IF_RWDC}A ${DNSDOMAIN} $IP +${IF_RWDC}AAAA ${DNSDOMAIN} $IP +${IF_RWDC}SRV _ldap._tcp.${DNSDOMAIN} ${HOSTNAME} 389 +${IF_RWDC}SRV _ldap._tcp.dc._msdcs.${DNSDOMAIN} ${HOSTNAME} 389 +${IF_RWDC}SRV _ldap._tcp.${DOMAINGUID}.domains._msdcs.${DNSFOREST} ${HOSTNAME} 389 +${IF_RWDC}SRV _kerberos._tcp.${DNSDOMAIN} ${HOSTNAME} 88 +${IF_RWDC}SRV _kerberos._udp.${DNSDOMAIN} ${HOSTNAME} 88 +${IF_RWDC}SRV _kerberos._tcp.dc._msdcs.${DNSDOMAIN} ${HOSTNAME} 88 +${IF_RWDC}SRV _kpasswd._tcp.${DNSDOMAIN} ${HOSTNAME} 464 +${IF_RWDC}SRV _kpasswd._udp.${DNSDOMAIN} ${HOSTNAME} 464 +# RW and RO domain controller +${IF_DC}CNAME ${NTDSGUID}._msdcs.${DNSFOREST} ${HOSTNAME} +${IF_DC}SRV _ldap._tcp.${SITE}._sites.${DNSDOMAIN} ${HOSTNAME} 389 +${IF_DC}SRV _ldap._tcp.${SITE}._sites.dc._msdcs.${DNSDOMAIN} ${HOSTNAME} 389 +${IF_DC}SRV _kerberos._tcp.${SITE}._sites.${DNSDOMAIN} ${HOSTNAME} 88 +${IF_DC}SRV _kerberos._tcp.${SITE}._sites.dc._msdcs.${DNSDOMAIN} ${HOSTNAME} 88 + +# The PDC emulator +${IF_PDC}SRV _ldap._tcp.pdc._msdcs.${DNSDOMAIN} ${HOSTNAME} 389 + +# RW GC servers +${IF_RWGC}A gc._msdcs.${DNSFOREST} $IP +${IF_RWGC}AAAA gc._msdcs.${DNSFOREST} $IP +${IF_RWGC}SRV _gc._tcp.${DNSFOREST} ${HOSTNAME} 3268 +${IF_RWGC}SRV _ldap._tcp.gc._msdcs.${DNSFOREST} ${HOSTNAME} 3268 +# RW and RO GC servers +${IF_GC}SRV _gc._tcp.${SITE}._sites.${DNSFOREST} ${HOSTNAME} 3268 +${IF_GC}SRV _ldap._tcp.${SITE}._sites.gc._msdcs.${DNSFOREST} ${HOSTNAME} 3268 + +# RW DNS servers +${IF_RWDNS_DOMAIN}A DomainDnsZones.${DNSDOMAIN} $IP +${IF_RWDNS_DOMAIN}AAAA DomainDnsZones.${DNSDOMAIN} $IP +${IF_RWDNS_DOMAIN}SRV _ldap._tcp.DomainDnsZones.${DNSDOMAIN} ${HOSTNAME} 389 +# RW and RO DNS servers +${IF_DNS_DOMAIN}SRV _ldap._tcp.${SITE}._sites.DomainDnsZones.${DNSDOMAIN} ${HOSTNAME} 389 + +# RW DNS servers +${IF_RWDNS_FOREST}A ForestDnsZones.${DNSFOREST} $IP +${IF_RWDNS_FOREST}AAAA ForestDnsZones.${DNSFOREST} $IP +${IF_RWDNS_FOREST}SRV _ldap._tcp.ForestDnsZones.${DNSFOREST} ${HOSTNAME} 389 +# RW and RO DNS servers +${IF_DNS_FOREST}SRV _ldap._tcp.${SITE}._sites.ForestDnsZones.${DNSFOREST} ${HOSTNAME} 389 -A gc._msdcs.${DNSFOREST} $IP -AAAA gc._msdcs.${DNSFOREST} $IP - -CNAME ${NTDSGUID}._msdcs.${DNSFOREST} ${HOSTNAME} - -SRV _kpasswd._tcp.${DNSDOMAIN} ${HOSTNAME} 464 -SRV _kpasswd._udp.${DNSDOMAIN} ${HOSTNAME} 464 - -SRV _kerberos._tcp.${DNSDOMAIN} ${HOSTNAME} 88 -SRV _kerberos._tcp.dc._msdcs.${DNSDOMAIN} ${HOSTNAME} 88 -SRV _kerberos._tcp.dc._msdcs.${DNSFOREST} ${HOSTNAME} 88 -SRV _kerberos._tcp.${SITE}._sites.${DNSDOMAIN} ${HOSTNAME} 88 -SRV _kerberos._tcp.${SITE}._sites.dc._msdcs.${DNSDOMAIN} ${HOSTNAME} 88 -SRV _kerberos._tcp.${SITE}._sites.dc._msdcs.${DNSFOREST} ${HOSTNAME} 88 - -SRV _kerberos._udp.${DNSDOMAIN} ${HOSTNAME} 88 - -SRV _ldap._tcp.${DNSDOMAIN} ${HOSTNAME} 389 -SRV _ldap._tcp.dc._msdcs.${DNSDOMAIN} ${HOSTNAME} 389 -SRV _ldap._tcp.dc._msdcs.${DNSFOREST} ${HOSTNAME} 389 -SRV _ldap._tcp.gc._msdcs.${DNSFOREST} ${HOSTNAME} 3268 -SRV _ldap._tcp.pdc._msdcs.${DNSDOMAIN} ${HOSTNAME} 389 -SRV _ldap._tcp.pdc._msdcs.${DNSFOREST} ${HOSTNAME} 389 -SRV _ldap._tcp.${SITE}._sites.${DNSDOMAIN} ${HOSTNAME} 389 -SRV _ldap._tcp.${SITE}._sites.dc._msdcs.${DNSDOMAIN} ${HOSTNAME} 389 -SRV _ldap._tcp.${SITE}._sites.dc._msdcs.${DNSFOREST} ${HOSTNAME} 389 -SRV _ldap._tcp.${SITE}._sites.gc._msdcs.${DNSFOREST} ${HOSTNAME} 3268 -SRV _ldap._tcp.${DOMAINGUID}.domains._msdcs.${DNSFOREST} ${HOSTNAME} 389 - - -SRV _gc._tcp.${DNSFOREST} ${HOSTNAME} 3268 -SRV _gc._tcp.${SITE}._sites.${DNSFOREST} ${HOSTNAME} 3268 -- 1.9.1