LCOV - code coverage report
Current view: top level - source4/torture/dns - dlz_bind9.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 814 922 88.3 %
Date: 2024-02-28 12:06:22 Functions: 29 29 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB torture tester
       4             :    Copyright (C) Andrew Bartlett 2012
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "torture/smbtorture.h"
      22             : #include "system/network.h"
      23             : #include "dns_server/dlz_minimal.h"
      24             : #include <talloc.h>
      25             : #include <ldb.h>
      26             : #include "lib/param/param.h"
      27             : #include "dsdb/samdb/samdb.h"
      28             : #include "dsdb/common/util.h"
      29             : #include "auth/session.h"
      30             : #include "auth/gensec/gensec.h"
      31             : #include "auth/credentials/credentials.h"
      32             : #include "lib/cmdline/cmdline.h"
      33             : #include "system/network.h"
      34             : #include "dns_server/dnsserver_common.h"
      35             : #include "librpc/gen_ndr/ndr_dnsserver.h"
      36             : #include "librpc/gen_ndr/ndr_dnsserver_c.h"
      37             : #include "torture/rpc/torture_rpc.h"
      38             : #include "librpc/gen_ndr/ndr_dnsp.h"
      39             : 
      40             : #include "librpc/rpc/dcerpc.h"
      41             : #include "librpc/rpc/dcerpc_proto.h"
      42             : 
      43             : /* Tests that configure multiple DLZs will use this. Increase to add stress. */
      44             : #define NUM_DLZS_TO_CONFIGURE 4
      45             : 
      46             : struct torture_context *tctx_static;
      47             : 
      48             : static void dlz_bind9_log_wrapper(int level, const char *fmt, ...)
      49             :                                   PRINTF_ATTRIBUTE(2,3);
      50             : 
      51         255 : static void dlz_bind9_log_wrapper(int level, const char *fmt, ...)
      52             : {
      53           0 :         va_list ap;
      54           0 :         char *msg;
      55         255 :         va_start(ap, fmt);
      56         255 :         msg = talloc_vasprintf(NULL, fmt, ap);
      57         255 :         torture_comment(tctx_static, "%s\n", msg);
      58         255 :         TALLOC_FREE(msg);
      59         255 :         va_end(ap);
      60         255 : }
      61             : 
      62           1 : static bool test_dlz_bind9_version(struct torture_context *tctx)
      63             : {
      64           1 :         unsigned int flags = 0;
      65           1 :         torture_assert_int_equal(tctx, dlz_version(&flags),
      66             :                                  DLZ_DLOPEN_VERSION, "got wrong DLZ version");
      67           1 :         return true;
      68             : }
      69             : 
      70          44 : static char *dlz_bind9_binddns_dir(struct torture_context *tctx,
      71             :                                    const char *file)
      72             : {
      73          44 :         return talloc_asprintf(tctx,
      74             :                                "ldb://%s/%s",
      75             :                                lpcfg_binddns_dir(tctx->lp_ctx),
      76             :                                file);
      77             : }
      78             : 
      79           1 : static bool test_dlz_bind9_create(struct torture_context *tctx)
      80             : {
      81           0 :         void *dbdata;
      82           2 :         const char *argv[] = {
      83             :                 "samba_dlz",
      84             :                 "-H",
      85           1 :                 dlz_bind9_binddns_dir(tctx, "dns/sam.ldb"),
      86             :                 NULL
      87             :         };
      88           1 :         tctx_static = tctx;
      89           1 :         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
      90             :                                                   "log", dlz_bind9_log_wrapper, NULL), ISC_R_SUCCESS,
      91             :                 "Failed to create samba_dlz");
      92             : 
      93           1 :         dlz_destroy(dbdata);
      94             : 
      95           1 :         return true;
      96             : }
      97             : 
      98             : static bool calls_zone_hook = false;
      99             : 
     100          28 : static isc_result_t dlz_bind9_writeable_zone_hook(dns_view_t *view,
     101             :                                                   dns_dlzdb_t *dlzdb,
     102             :                                                   const char *zone_name)
     103             : {
     104          28 :         struct torture_context *tctx = talloc_get_type((void *)view, struct torture_context);
     105          28 :         struct ldb_context *samdb = NULL;
     106          28 :         char *errstring = NULL;
     107          28 :         int ret = samdb_connect_url(
     108             :                         tctx,
     109             :                         NULL,
     110             :                         tctx->lp_ctx,
     111             :                         system_session(tctx->lp_ctx),
     112             :                         0,
     113          28 :                         dlz_bind9_binddns_dir(tctx, "dns/sam.ldb"),
     114             :                         NULL,
     115             :                         &samdb,
     116             :                         &errstring);
     117           0 :         struct ldb_message *msg;
     118          28 :         const char *attrs[] = {
     119             :                 NULL
     120             :         };
     121          28 :         if (ret != LDB_SUCCESS) {
     122           0 :                 torture_comment(tctx, "Failed to connect to samdb");
     123           0 :                 return ISC_R_FAILURE;
     124             :         }
     125             : 
     126          28 :         ret = dsdb_search_one(samdb, tctx, &msg, NULL,
     127             :                               LDB_SCOPE_SUBTREE, attrs, DSDB_SEARCH_SEARCH_ALL_PARTITIONS,
     128             :                               "(&(objectClass=dnsZone)(name=%s))", zone_name);
     129          28 :         if (ret != LDB_SUCCESS) {
     130           0 :                 torture_comment(tctx,
     131             :                                 "Failed to search for %s: %s",
     132             :                                 zone_name,
     133             :                                 ldb_errstring(samdb));
     134           0 :                 return ISC_R_FAILURE;
     135             :         }
     136          28 :         talloc_free(msg);
     137             : 
     138          28 :         calls_zone_hook = true;
     139             : 
     140          28 :         return ISC_R_SUCCESS;
     141             : }
     142             : 
     143           5 : static bool test_dlz_bind9_configure(struct torture_context *tctx)
     144             : {
     145           5 :         void *dbdata = NULL;
     146           5 :         dns_dlzdb_t *dlzdb = NULL;
     147           0 :         int ret;
     148          10 :         const char *argv[] = {
     149             :                 "samba_dlz",
     150             :                 "-H",
     151           5 :                 dlz_bind9_binddns_dir(tctx, "dns/sam.ldb"),
     152             :                 NULL
     153             :         };
     154           5 :         tctx_static = tctx;
     155           5 :         ret = dlz_create("samba_dlz", 3, argv, &dbdata,
     156             :                          "log", dlz_bind9_log_wrapper,
     157             :                          "writeable_zone", dlz_bind9_writeable_zone_hook,
     158             :                          NULL);
     159           5 :         torture_assert_int_equal(tctx,
     160             :                                  ret,
     161             :                                  ISC_R_SUCCESS,
     162             :                                  "Failed to create samba_dlz");
     163             : 
     164           5 :         calls_zone_hook = false;
     165           5 :         torture_assert_int_equal(tctx, dlz_configure((void*)tctx,
     166             :                                                      dlzdb,
     167             :                                                      dbdata),
     168             :                                                      ISC_R_SUCCESS,
     169             :                                  "Failed to configure samba_dlz");
     170             : 
     171           5 :         dlz_destroy(dbdata);
     172             : 
     173           5 :         torture_assert_int_equal(tctx, calls_zone_hook, 1, "Hasn't called zone hook");
     174             : 
     175           5 :         return true;
     176             : }
     177             : 
     178           1 : static bool test_dlz_bind9_multiple_configure(struct torture_context *tctx)
     179             : {
     180           0 :         int i;
     181           5 :         for(i = 0; i < NUM_DLZS_TO_CONFIGURE; i++){
     182           4 :                 test_dlz_bind9_configure(tctx);
     183             :         }
     184           1 :         return true;
     185             : }
     186             : 
     187           2 : static bool configure_multiple_dlzs(struct torture_context *tctx,
     188             :                                     void **dbdata, int count)
     189             : {
     190           0 :         int i, res;
     191           2 :         dns_dlzdb_t *dlzdb = NULL;
     192           4 :         const char *argv[] = {
     193             :                 "samba_dlz",
     194             :                 "-H",
     195           2 :                 dlz_bind9_binddns_dir(tctx, "dns/sam.ldb"),
     196             :                 NULL
     197             :         };
     198             : 
     199           2 :         tctx_static = tctx;
     200          10 :         for(i = 0; i < count; i++){
     201           8 :                 res = dlz_create("samba_dlz", 3, argv, &(dbdata[i]),
     202             :                                  "log", dlz_bind9_log_wrapper,
     203             :                                  "writeable_zone",
     204             :                                  dlz_bind9_writeable_zone_hook, NULL);
     205           8 :                 torture_assert_int_equal(tctx, res, ISC_R_SUCCESS,
     206             :                                          "Failed to create samba_dlz");
     207             : 
     208           8 :                 res = dlz_configure((void*)tctx, dlzdb, dbdata[i]);
     209           8 :                 torture_assert_int_equal(tctx, res, ISC_R_SUCCESS,
     210             :                                          "Failed to configure samba_dlz");
     211             :         }
     212             : 
     213           2 :         return true;
     214             : }
     215             : 
     216           1 : static bool test_dlz_bind9_destroy_oldest_first(struct torture_context *tctx)
     217             : {
     218           0 :         void *dbdata[NUM_DLZS_TO_CONFIGURE];
     219           0 :         int i;
     220           1 :         bool ret = configure_multiple_dlzs(tctx,
     221             :                                            dbdata,
     222             :                                            NUM_DLZS_TO_CONFIGURE);
     223           1 :         if (ret == false) {
     224             :                 /* failure: has already been printed */
     225           0 :                 return false;
     226             :         }
     227             : 
     228             :         /* Reload faults are reported to happen on the first destroy */
     229           1 :         dlz_destroy(dbdata[0]);
     230             : 
     231           4 :         for(i = 1; i < NUM_DLZS_TO_CONFIGURE; i++){
     232           3 :                 dlz_destroy(dbdata[i]);
     233             :         }
     234             : 
     235           1 :         return true;
     236             : }
     237             : 
     238           1 : static bool test_dlz_bind9_destroy_newest_first(struct torture_context *tctx)
     239             : {
     240           0 :         void *dbdata[NUM_DLZS_TO_CONFIGURE];
     241           0 :         int i;
     242           1 :         bool ret = configure_multiple_dlzs(tctx,
     243             :                                            dbdata,
     244             :                                            NUM_DLZS_TO_CONFIGURE);
     245           1 :         if (ret == false) {
     246             :                 /* failure: has already been printed */
     247           0 :                 return false;
     248             :         }
     249             : 
     250           5 :         for(i = NUM_DLZS_TO_CONFIGURE - 1; i >= 0; i--) {
     251           4 :                 dlz_destroy(dbdata[i]);
     252             :         }
     253             : 
     254           1 :         return true;
     255             : }
     256             : 
     257             : /*
     258             :  * Test that a ticket obtained for the DNS service will be accepted on the Samba DLZ side
     259             :  *
     260             :  */
     261           2 : static bool test_dlz_bind9_gensec(struct torture_context *tctx, const char *mech)
     262             : {
     263           0 :         NTSTATUS status;
     264           2 :         dns_dlzdb_t *dlzdb = NULL;
     265             : 
     266           0 :         struct gensec_security *gensec_client_context;
     267             : 
     268           0 :         DATA_BLOB client_to_server, server_to_client;
     269             : 
     270           0 :         void *dbdata;
     271           4 :         const char *argv[] = {
     272             :                 "samba_dlz",
     273             :                 "-H",
     274           2 :                 dlz_bind9_binddns_dir(tctx, "dns/sam.ldb"),
     275             :                 NULL
     276             :         };
     277           2 :         tctx_static = tctx;
     278           2 :         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
     279             :                                                   "log", dlz_bind9_log_wrapper,
     280             :                                                   "writeable_zone", dlz_bind9_writeable_zone_hook, NULL),
     281             :                                  ISC_R_SUCCESS,
     282             :                                  "Failed to create samba_dlz");
     283             : 
     284           2 :         torture_assert_int_equal(tctx, dlz_configure((void*)tctx,
     285             :                                                      dlzdb, dbdata),
     286             :                                                      ISC_R_SUCCESS,
     287             :                                  "Failed to configure samba_dlz");
     288             : 
     289           2 :         status = gensec_client_start(tctx, &gensec_client_context,
     290             :                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx));
     291           2 :         torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");
     292             : 
     293             :         /*
     294             :          * dlz_bind9 use the special dns/host.domain account
     295             :          */
     296           2 :         status = gensec_set_target_hostname(gensec_client_context,
     297           2 :                                             talloc_asprintf(tctx,
     298             :                                 "%s.%s",
     299             :                                 torture_setting_string(tctx, "host", NULL),
     300             :                                 lpcfg_dnsdomain(tctx->lp_ctx)));
     301           2 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed");
     302             : 
     303           2 :         status = gensec_set_target_service(gensec_client_context, "dns");
     304           2 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_service failed");
     305             : 
     306           2 :         status = gensec_set_credentials(gensec_client_context,
     307             :                         samba_cmdline_get_creds());
     308           2 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");
     309             : 
     310           2 :         status = gensec_start_mech_by_sasl_name(gensec_client_context, mech);
     311           2 :         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");
     312             : 
     313           2 :         server_to_client = data_blob(NULL, 0);
     314             : 
     315             :         /* Do one step of the client-server update dance */
     316           2 :         status = gensec_update(gensec_client_context, tctx, server_to_client, &client_to_server);
     317           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
     318           0 :                 torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
     319             :         }
     320             : 
     321           2 :         torture_assert_int_equal(tctx, dlz_ssumatch(
     322             :                                         cli_credentials_get_username(
     323             :                                                 samba_cmdline_get_creds()),
     324             :                                         lpcfg_dnsdomain(tctx->lp_ctx),
     325             :                                         "127.0.0.1", "type", "key",
     326             :                                         client_to_server.length,
     327             :                                         client_to_server.data,
     328             :                                         dbdata),
     329             :                                         ISC_TRUE,
     330             :                          "Failed to check key for update rights samba_dlz");
     331             : 
     332           2 :         dlz_destroy(dbdata);
     333             : 
     334           2 :         return true;
     335             : }
     336             : 
     337           1 : static bool test_dlz_bind9_gssapi(struct torture_context *tctx)
     338             : {
     339           1 :         return test_dlz_bind9_gensec(tctx, "GSSAPI");
     340             : }
     341             : 
     342           1 : static bool test_dlz_bind9_spnego(struct torture_context *tctx)
     343             : {
     344           1 :         return test_dlz_bind9_gensec(tctx, "GSS-SPNEGO");
     345             : }
     346             : 
     347             : struct test_expected_record {
     348             :         const char *name;
     349             :         const char *type;
     350             :         const char *data;
     351             :         int ttl;
     352             :         bool printed;
     353             :         const char *rdata;
     354             : };
     355             : 
     356             : struct test_expected_rr {
     357             :         struct torture_context *tctx;
     358             :         const char *query_name;
     359             :         size_t num_records;
     360             :         struct test_expected_record *records;
     361             :         size_t num_rr;
     362             : };
     363             : 
     364          93 : static bool dlz_bind9_putnamedrr_torture_hook(struct test_expected_rr *expected,
     365             :                                               const char *name,
     366             :                                               const char *type,
     367             :                                               dns_ttl_t ttl,
     368             :                                               const char *data)
     369             : {
     370           0 :         size_t i;
     371             : 
     372          93 :         torture_assert(expected->tctx, name != NULL,
     373             :                        talloc_asprintf(expected->tctx,
     374             :                        "Got unnamed record type[%s] data[%s]\n",
     375             :                        type, data));
     376             : 
     377          93 :         expected->num_rr++;
     378          93 :         torture_comment(expected->tctx, "%u: name[%s] type[%s] ttl[%u] data[%s]\n",
     379          93 :                         (unsigned)expected->num_rr, name, type, (unsigned)ttl, data);
     380             : 
     381         557 :         for (i = 0; i < expected->num_records; i++) {
     382         464 :                 if (expected->records[i].name != NULL) {
     383         440 :                         if (strcmp(name, expected->records[i].name) != 0) {
     384         124 :                                 continue;
     385             :                         }
     386             :                 }
     387             : 
     388         340 :                 if (strcmp(type, expected->records[i].type) != 0) {
     389         219 :                         continue;
     390             :                 }
     391             : 
     392         121 :                 if (expected->records[i].data != NULL) {
     393             :                         /*
     394             :                          * For most types the data will have been reformatted
     395             :                          * or normalised, so we need to do approximately the
     396             :                          * same to compare.
     397             :                          */
     398         100 :                         const char *data2 = expected->records[i].data;
     399         100 :                         if (strcmp(type, "aaaa") == 0) {
     400           0 :                                 struct in6_addr adr1;
     401           0 :                                 struct in6_addr adr2;
     402           0 :                                 int ret;
     403          10 :                                 ret = inet_pton(AF_INET6, data, &adr1);
     404          10 :                                 if (ret != 1) {
     405           0 :                                         continue;
     406             :                                 }
     407          10 :                                 ret = inet_pton(AF_INET6, data2, &adr2);
     408          10 :                                 if (ret != 1) {
     409           0 :                                         continue;
     410             :                                 }
     411          10 :                                 if (memcmp(&adr1, &adr2, sizeof(adr1)) != 0) {
     412           0 :                                         continue;
     413             :                                 }
     414          90 :                         } else if (strcmp(type, "cname") == 0 ||
     415          90 :                                  strcmp(type, "ptr") == 0   ||
     416          80 :                                  strcmp(type, "ns") == 0) {
     417          12 :                                 if (!samba_dns_name_equal(data, data2)) {
     418           0 :                                         continue;
     419             :                                 }
     420          78 :                         } else if (strcmp(type, "mx") == 0) {
     421             :                                 /*
     422             :                                  * samba_dns_name_equal works for MX records
     423             :                                  * because the space in "10 example.com." is
     424             :                                  * theoretically OK as a DNS character. And we
     425             :                                  * need it because dlz will add the trailing
     426             :                                  * dot.
     427             :                                  */
     428          10 :                                 if (!samba_dns_name_equal(data, data2)) {
     429           0 :                                         continue;
     430             :                                 }
     431          68 :                         } else if (strcmp(data, data2) != 0) {
     432             :                                 /* default, works for A records */
     433          33 :                                 continue;
     434             :                         }
     435             :                 }
     436             : 
     437          88 :                 torture_assert_int_equal(expected->tctx, ttl,
     438             :                                          expected->records[i].ttl,
     439             :                                          talloc_asprintf(expected->tctx,
     440             :                                          "TTL did not match expectations for type %s",
     441             :                                          type));
     442             : 
     443          88 :                 expected->records[i].printed = true;
     444             :         }
     445             : 
     446          93 :         return true;
     447             : }
     448             : 
     449             : /*
     450             :  * Lookups in these tests end up coming round to run this function.
     451             :  */
     452          69 : static isc_result_t dlz_bind9_putrr_hook(dns_sdlzlookup_t *lookup,
     453             :                                          const char *type,
     454             :                                          dns_ttl_t ttl,
     455             :                                          const char *data)
     456             : {
     457           0 :         struct test_expected_rr *expected =
     458          69 :                 talloc_get_type_abort(lookup, struct test_expected_rr);
     459           0 :         bool ok;
     460             : 
     461          69 :         ok = dlz_bind9_putnamedrr_torture_hook(expected, expected->query_name,
     462             :                                                type, ttl, data);
     463          69 :         if (!ok) {
     464           0 :                 return ISC_R_FAILURE;
     465             :         }
     466             : 
     467          69 :         return ISC_R_SUCCESS;
     468             : }
     469             : 
     470          24 : static isc_result_t dlz_bind9_putnamedrr_hook(dns_sdlzallnodes_t *allnodes,
     471             :                                               const char *name,
     472             :                                               const char *type,
     473             :                                               dns_ttl_t ttl,
     474             :                                               const char *data)
     475             : {
     476           0 :         struct test_expected_rr *expected =
     477          24 :                 talloc_get_type_abort(allnodes, struct test_expected_rr);
     478           0 :         bool ok;
     479             : 
     480          24 :         ok = dlz_bind9_putnamedrr_torture_hook(expected, name, type, ttl, data);
     481          24 :         if (!ok) {
     482           0 :                 return ISC_R_FAILURE;
     483             :         }
     484             : 
     485          24 :         return ISC_R_SUCCESS;
     486             : }
     487             : 
     488             : /*
     489             :  * Tests some lookups
     490             :  */
     491           1 : static bool test_dlz_bind9_lookup(struct torture_context *tctx)
     492             : {
     493           0 :         size_t i;
     494           1 :         void *dbdata = NULL;
     495           1 :         dns_clientinfomethods_t *methods = NULL;
     496           1 :         dns_clientinfo_t *clientinfo = NULL;
     497           1 :         dns_dlzdb_t *dlzdb = NULL;
     498           2 :         const char *argv[] = {
     499             :                 "samba_dlz",
     500             :                 "-H",
     501           1 :                 dlz_bind9_binddns_dir(tctx, "dns/sam.ldb"),
     502             :                 NULL
     503             :         };
     504           1 :         struct test_expected_rr *expected1 = NULL;
     505           1 :         struct test_expected_rr *expected2 = NULL;
     506             : 
     507           1 :         tctx_static = tctx;
     508           1 :         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
     509             :                                                   "log", dlz_bind9_log_wrapper,
     510             :                                                   "writeable_zone", dlz_bind9_writeable_zone_hook,
     511             :                                                   "putrr", dlz_bind9_putrr_hook,
     512             :                                                   "putnamedrr", dlz_bind9_putnamedrr_hook,
     513             :                                                   NULL),
     514             :                                  ISC_R_SUCCESS,
     515             :                                  "Failed to create samba_dlz");
     516             : 
     517           1 :         torture_assert_int_equal(tctx,
     518             :                                  dlz_configure((void*)tctx, dlzdb, dbdata),
     519             :                                  ISC_R_SUCCESS,
     520             :                                  "Failed to configure samba_dlz");
     521             : 
     522           1 :         expected1 = talloc_zero(tctx, struct test_expected_rr);
     523           1 :         torture_assert(tctx, expected1 != NULL, "talloc failed");
     524           1 :         expected1->tctx = tctx;
     525             : 
     526           1 :         expected1->query_name = "@";
     527             : 
     528           1 :         expected1->num_records = 4;
     529           1 :         expected1->records = talloc_zero_array(expected1,
     530             :                                                struct test_expected_record,
     531             :                                                expected1->num_records);
     532           1 :         torture_assert(tctx, expected1->records != NULL, "talloc failed");
     533             : 
     534           1 :         expected1->records[0].name = expected1->query_name;
     535           1 :         expected1->records[0].type = "soa";
     536           1 :         expected1->records[0].ttl = 3600;
     537           1 :         expected1->records[0].data = talloc_asprintf(expected1->records,
     538             :                                 "%s.%s. hostmaster.%s. 1 900 600 86400 3600",
     539             :                                 torture_setting_string(tctx, "host", NULL),
     540             :                                 lpcfg_dnsdomain(tctx->lp_ctx),
     541             :                                 lpcfg_dnsdomain(tctx->lp_ctx));
     542           1 :         torture_assert(tctx, expected1->records[0].data != NULL, "talloc failed");
     543             : 
     544           1 :         expected1->records[1].name = expected1->query_name;
     545           1 :         expected1->records[1].type = "ns";
     546           1 :         expected1->records[1].ttl = 900;
     547           1 :         expected1->records[1].data = talloc_asprintf(expected1->records, "%s.%s.",
     548             :                                 torture_setting_string(tctx, "host", NULL),
     549             :                                 lpcfg_dnsdomain(tctx->lp_ctx));
     550           1 :         torture_assert(tctx, expected1->records[1].data != NULL, "talloc failed");
     551             : 
     552           1 :         expected1->records[2].name = expected1->query_name;
     553           1 :         expected1->records[2].type = "aaaa";
     554           1 :         expected1->records[2].ttl = 900;
     555             : 
     556           1 :         expected1->records[3].name = expected1->query_name;
     557           1 :         expected1->records[3].type = "a";
     558           1 :         expected1->records[3].ttl = 900;
     559             : 
     560           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
     561             :                                                   expected1->query_name, dbdata,
     562             :                                                   (dns_sdlzlookup_t *)expected1,
     563             :                                                   methods, clientinfo),
     564             :                                  ISC_R_SUCCESS,
     565             :                                  "Failed to lookup @");
     566           5 :         for (i = 0; i < expected1->num_records; i++) {
     567           4 :                 torture_assert(tctx, expected1->records[i].printed,
     568             :                                talloc_asprintf(tctx,
     569             :                                "Failed to have putrr callback run for type %s",
     570             :                                expected1->records[i].type));
     571             :         }
     572           1 :         torture_assert_int_equal(tctx, expected1->num_rr,
     573             :                                  expected1->num_records,
     574             :                                  "Got too much data");
     575             : 
     576           1 :         expected2 = talloc_zero(tctx, struct test_expected_rr);
     577           1 :         torture_assert(tctx, expected2 != NULL, "talloc failed");
     578           1 :         expected2->tctx = tctx;
     579             : 
     580           1 :         expected2->query_name = torture_setting_string(tctx, "host", NULL);
     581           1 :         torture_assert(tctx, expected2->query_name != NULL, "unknown host");
     582             : 
     583           1 :         expected2->num_records = 2;
     584           1 :         expected2->records = talloc_zero_array(expected2,
     585             :                                                struct test_expected_record,
     586             :                                                expected2->num_records);
     587           1 :         torture_assert(tctx, expected2->records != NULL, "talloc failed");
     588             : 
     589           1 :         expected2->records[0].name = expected2->query_name;
     590           1 :         expected2->records[0].type = "aaaa";
     591           1 :         expected2->records[0].ttl = 900;
     592             : 
     593           1 :         expected2->records[1].name = expected2->query_name;
     594           1 :         expected2->records[1].type = "a";
     595           1 :         expected2->records[1].ttl = 900;
     596             : 
     597           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
     598             :                                                   expected2->query_name, dbdata,
     599             :                                                   (dns_sdlzlookup_t *)expected2,
     600             :                                                   methods, clientinfo),
     601             :                                  ISC_R_SUCCESS,
     602             :                                  "Failed to lookup hostname");
     603           3 :         for (i = 0; i < expected2->num_records; i++) {
     604           2 :                 torture_assert(tctx, expected2->records[i].printed,
     605             :                                talloc_asprintf(tctx,
     606             :                                "Failed to have putrr callback run name[%s] for type %s",
     607             :                                expected2->records[i].name,
     608             :                                expected2->records[i].type));
     609             :         }
     610           1 :         torture_assert_int_equal(tctx, expected2->num_rr,
     611             :                                  expected2->num_records,
     612             :                                  "Got too much data");
     613             : 
     614           1 :         dlz_destroy(dbdata);
     615             : 
     616           1 :         return true;
     617             : }
     618             : 
     619             : /*
     620             :  * Test some zone dumps
     621             :  */
     622           1 : static bool test_dlz_bind9_zonedump(struct torture_context *tctx)
     623             : {
     624           0 :         size_t i;
     625           1 :         void *dbdata = NULL;
     626           1 :         dns_dlzdb_t *dlzdb = NULL;
     627           2 :         const char *argv[] = {
     628             :                 "samba_dlz",
     629             :                 "-H",
     630           1 :                 dlz_bind9_binddns_dir(tctx, "dns/sam.ldb"),
     631             :                 NULL
     632             :         };
     633           1 :         struct test_expected_rr *expected1 = NULL;
     634             : 
     635           1 :         tctx_static = tctx;
     636           1 :         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
     637             :                                                   "log", dlz_bind9_log_wrapper,
     638             :                                                   "writeable_zone", dlz_bind9_writeable_zone_hook,
     639             :                                                   "putrr", dlz_bind9_putrr_hook,
     640             :                                                   "putnamedrr", dlz_bind9_putnamedrr_hook,
     641             :                                                   NULL),
     642             :                                  ISC_R_SUCCESS,
     643             :                                  "Failed to create samba_dlz");
     644             : 
     645           1 :         torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dlzdb, dbdata),
     646             :                                                      ISC_R_SUCCESS,
     647             :                                  "Failed to configure samba_dlz");
     648             : 
     649           1 :         expected1 = talloc_zero(tctx, struct test_expected_rr);
     650           1 :         torture_assert(tctx, expected1 != NULL, "talloc failed");
     651           1 :         expected1->tctx = tctx;
     652             : 
     653           1 :         expected1->num_records = 7;
     654           1 :         expected1->records = talloc_zero_array(expected1,
     655             :                                                struct test_expected_record,
     656             :                                                expected1->num_records);
     657           1 :         torture_assert(tctx, expected1->records != NULL, "talloc failed");
     658             : 
     659           1 :         expected1->records[0].name = talloc_asprintf(expected1->records,
     660             :                                 "%s.", lpcfg_dnsdomain(tctx->lp_ctx));
     661           1 :         expected1->records[0].type = "soa";
     662           1 :         expected1->records[0].ttl = 3600;
     663           1 :         expected1->records[0].data = talloc_asprintf(expected1->records,
     664             :                                 "%s.%s. hostmaster.%s. 1 900 600 86400 3600",
     665             :                                 torture_setting_string(tctx, "host", NULL),
     666             :                                 lpcfg_dnsdomain(tctx->lp_ctx),
     667             :                                 lpcfg_dnsdomain(tctx->lp_ctx));
     668           1 :         torture_assert(tctx, expected1->records[0].data != NULL, "talloc failed");
     669             : 
     670           1 :         expected1->records[1].name = talloc_asprintf(expected1->records,
     671             :                                 "%s.", lpcfg_dnsdomain(tctx->lp_ctx));
     672           1 :         expected1->records[1].type = "ns";
     673           1 :         expected1->records[1].ttl = 900;
     674           1 :         expected1->records[1].data = talloc_asprintf(expected1->records, "%s.%s.",
     675             :                                 torture_setting_string(tctx, "host", NULL),
     676             :                                 lpcfg_dnsdomain(tctx->lp_ctx));
     677           1 :         torture_assert(tctx, expected1->records[1].data != NULL, "talloc failed");
     678             : 
     679           1 :         expected1->records[2].name = talloc_asprintf(expected1->records,
     680             :                                 "%s.", lpcfg_dnsdomain(tctx->lp_ctx));
     681           1 :         expected1->records[2].type = "aaaa";
     682           1 :         expected1->records[2].ttl = 900;
     683             : 
     684           1 :         expected1->records[3].name = talloc_asprintf(expected1->records,
     685             :                                 "%s.", lpcfg_dnsdomain(tctx->lp_ctx));
     686           1 :         expected1->records[3].type = "a";
     687           1 :         expected1->records[3].ttl = 900;
     688             : 
     689           1 :         expected1->records[4].name = talloc_asprintf(expected1->records, "%s.%s.",
     690             :                                 torture_setting_string(tctx, "host", NULL),
     691             :                                 lpcfg_dnsdomain(tctx->lp_ctx));
     692           1 :         torture_assert(tctx, expected1->records[4].name != NULL, "unknown host");
     693           1 :         expected1->records[4].type = "aaaa";
     694           1 :         expected1->records[4].ttl = 900;
     695             : 
     696           1 :         expected1->records[5].name = talloc_asprintf(expected1->records, "%s.%s.",
     697             :                                 torture_setting_string(tctx, "host", NULL),
     698             :                                 lpcfg_dnsdomain(tctx->lp_ctx));
     699           1 :         torture_assert(tctx, expected1->records[5].name != NULL, "unknown host");
     700           1 :         expected1->records[5].type = "a";
     701           1 :         expected1->records[5].ttl = 900;
     702             : 
     703             :         /*
     704             :          * We expect multiple srv records
     705             :          */
     706           1 :         expected1->records[6].name = NULL;
     707           1 :         expected1->records[6].type = "srv";
     708           1 :         expected1->records[6].ttl = 900;
     709             : 
     710           1 :         torture_assert_int_equal(tctx, dlz_allnodes(lpcfg_dnsdomain(tctx->lp_ctx),
     711             :                                                     dbdata, (dns_sdlzallnodes_t *)expected1),
     712             :                                  ISC_R_SUCCESS,
     713             :                                  "Failed to configure samba_dlz");
     714           8 :         for (i = 0; i < expected1->num_records; i++) {
     715           7 :                 torture_assert(tctx, expected1->records[i].printed,
     716             :                                talloc_asprintf(tctx,
     717             :                                "Failed to have putrr callback run name[%s] for type %s",
     718             :                                expected1->records[i].name,
     719             :                                expected1->records[i].type));
     720             :         }
     721           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 24,
     722             :                                  "Got wrong record count");
     723             : 
     724           1 :         dlz_destroy(dbdata);
     725             : 
     726           1 :         return true;
     727             : }
     728             : 
     729             : /*
     730             :  * Test some updates
     731             :  */
     732           1 : static bool test_dlz_bind9_update01(struct torture_context *tctx)
     733             : {
     734           0 :         NTSTATUS status;
     735           0 :         struct gensec_security *gensec_client_context;
     736           0 :         DATA_BLOB client_to_server, server_to_client;
     737           1 :         void *dbdata = NULL;
     738           1 :         dns_dlzdb_t *dlzdb = NULL;
     739           1 :         void *version = NULL;
     740           2 :         const char *argv[] = {
     741             :                 "samba_dlz",
     742             :                 "-H",
     743           1 :                 dlz_bind9_binddns_dir(tctx, "dns/sam.ldb"),
     744             :                 NULL
     745             :         };
     746           1 :         struct test_expected_rr *expected1 = NULL;
     747           1 :         char *name = NULL;
     748           1 :         char *data0 = NULL;
     749           1 :         char *data1 = NULL;
     750           1 :         char *data2 = NULL;
     751           1 :         bool ret = false;
     752           1 :         dns_clientinfomethods_t *methods = NULL;
     753           1 :         dns_clientinfo_t *clientinfo = NULL;
     754             : 
     755           1 :         tctx_static = tctx;
     756           1 :         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
     757             :                                                   "log", dlz_bind9_log_wrapper,
     758             :                                                   "writeable_zone", dlz_bind9_writeable_zone_hook,
     759             :                                                   "putrr", dlz_bind9_putrr_hook,
     760             :                                                   "putnamedrr", dlz_bind9_putnamedrr_hook,
     761             :                                                   NULL),
     762             :                                  ISC_R_SUCCESS,
     763             :                                  "Failed to create samba_dlz");
     764             : 
     765           1 :         torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dlzdb, dbdata),
     766             :                                                      ISC_R_SUCCESS,
     767             :                                  "Failed to configure samba_dlz");
     768             : 
     769           1 :         expected1 = talloc_zero(tctx, struct test_expected_rr);
     770           1 :         torture_assert(tctx, expected1 != NULL, "talloc failed");
     771           1 :         expected1->tctx = tctx;
     772             : 
     773           1 :         expected1->query_name = __func__;
     774             : 
     775           1 :         name = talloc_asprintf(expected1, "%s.%s",
     776             :                                 expected1->query_name,
     777             :                                 lpcfg_dnsdomain(tctx->lp_ctx));
     778           1 :         torture_assert(tctx, name != NULL, "talloc failed");
     779             : 
     780           1 :         expected1->num_records = 2;
     781           1 :         expected1->records = talloc_zero_array(expected1,
     782             :                                                struct test_expected_record,
     783             :                                                expected1->num_records);
     784           1 :         torture_assert(tctx, expected1->records != NULL, "talloc failed");
     785             : 
     786           1 :         expected1->records[0].name = expected1->query_name;
     787           1 :         expected1->records[0].type = "a";
     788           1 :         expected1->records[0].ttl = 3600;
     789           1 :         expected1->records[0].data = "127.1.2.3";
     790           1 :         expected1->records[0].printed = false;
     791             : 
     792           1 :         data0 = talloc_asprintf(expected1,
     793             :                                 "%s.\t" "%u\t" "%s\t" "%s\t" "%s",
     794             :                                 name,
     795           1 :                                 (unsigned)expected1->records[0].ttl,
     796             :                                 "in",
     797           1 :                                 expected1->records[0].type,
     798           1 :                                 expected1->records[0].data);
     799           1 :         torture_assert(tctx, data0 != NULL, "talloc failed");
     800             : 
     801           1 :         expected1->records[1].name = expected1->query_name;
     802           1 :         expected1->records[1].type = "a";
     803           1 :         expected1->records[1].ttl = 3600;
     804           1 :         expected1->records[1].data = "127.3.2.1";
     805           1 :         expected1->records[1].printed = false;
     806             : 
     807           1 :         data1 = talloc_asprintf(expected1,
     808             :                                 "%s.\t" "%u\t" "%s\t" "%s\t" "%s",
     809             :                                 name,
     810           1 :                                 (unsigned)expected1->records[1].ttl,
     811             :                                 "in",
     812           1 :                                 expected1->records[1].type,
     813           1 :                                 expected1->records[1].data);
     814           1 :         torture_assert(tctx, data1 != NULL, "talloc failed");
     815             : 
     816           1 :         data2 = talloc_asprintf(expected1,
     817             :                                 "%s.\t" "0\t" "in\t" "a\t" "127.3.3.3",
     818             :                                 name);
     819           1 :         torture_assert(tctx, data2 != NULL, "talloc failed");
     820             : 
     821             :         /*
     822             :          * Prepare session info
     823             :          */
     824           1 :         status = gensec_client_start(tctx, &gensec_client_context,
     825             :                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx));
     826           1 :         torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");
     827             : 
     828             :         /*
     829             :          * dlz_bind9 use the special dns/host.domain account
     830             :          */
     831           1 :         status = gensec_set_target_hostname(gensec_client_context,
     832           1 :                                             talloc_asprintf(tctx,
     833             :                                 "%s.%s",
     834             :                                 torture_setting_string(tctx, "host", NULL),
     835             :                                 lpcfg_dnsdomain(tctx->lp_ctx)));
     836           1 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed");
     837             : 
     838           1 :         status = gensec_set_target_service(gensec_client_context, "dns");
     839           1 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_service failed");
     840             : 
     841           1 :         status = gensec_set_credentials(gensec_client_context,
     842             :                         samba_cmdline_get_creds());
     843           1 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");
     844             : 
     845           1 :         status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSS-SPNEGO");
     846           1 :         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");
     847             : 
     848           1 :         server_to_client = data_blob(NULL, 0);
     849             : 
     850             :         /* Do one step of the client-server update dance */
     851           1 :         status = gensec_update(gensec_client_context, tctx, server_to_client, &client_to_server);
     852           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
     853           0 :                 torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
     854             :         }
     855             : 
     856           1 :         torture_assert_int_equal(tctx, dlz_ssumatch(
     857             :                                 cli_credentials_get_username(
     858             :                                         samba_cmdline_get_creds()),
     859             :                                 name,
     860             :                                 "127.0.0.1",
     861             :                                 expected1->records[0].type,
     862             :                                 "key",
     863             :                                 client_to_server.length,
     864             :                                 client_to_server.data,
     865             :                                 dbdata),
     866             :                                 ISC_TRUE,
     867             :                          "Failed to check key for update rights samba_dlz");
     868             : 
     869             :         /*
     870             :          * We test the following:
     871             :          *
     872             :          *  1. lookup the records => NOT_FOUND
     873             :          *  2. delete all records => NOT_FOUND
     874             :          *  3. delete 1st record => NOT_FOUND
     875             :          *  4. create 1st record => SUCCESS
     876             :          *  5. lookup the records => found 1st
     877             :          *  6. create 2nd record => SUCCESS
     878             :          *  7. lookup the records => found 1st and 2nd
     879             :          *  8. delete unknown record => NOT_FOUND
     880             :          *  9. lookup the records => found 1st and 2nd
     881             :          * 10. delete 1st record => SUCCESS
     882             :          * 11. lookup the records => found 2nd
     883             :          * 12. delete 2nd record => SUCCESS
     884             :          * 13. lookup the records => NOT_FOUND
     885             :          * 14. create 1st record => SUCCESS
     886             :          * 15. lookup the records => found 1st
     887             :          * 16. create 2nd record => SUCCESS
     888             :          * 17. lookup the records => found 1st and 2nd
     889             :          * 18. update 1st record => SUCCESS
     890             :          * 19. lookup the records => found 1st and 2nd
     891             :          * 20. delete all unknown type records => NOT_FOUND
     892             :          * 21. lookup the records => found 1st and 2nd
     893             :          * 22. delete all records => SUCCESS
     894             :          * 23. lookup the records => NOT_FOUND
     895             :          */
     896             : 
     897             :         /* Step 1. */
     898           1 :         expected1->num_rr = 0;
     899           1 :         expected1->records[0].printed = false;
     900           1 :         expected1->records[1].printed = false;
     901           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
     902             :                                                   expected1->query_name, dbdata,
     903             :                                                   (dns_sdlzlookup_t *)expected1,
     904             :                                                   methods, clientinfo),
     905             :                                  ISC_R_NOTFOUND,
     906             :                                  "Found hostname");
     907           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 0,
     908             :                                  "Got wrong record count");
     909             : 
     910             :         /* Step 2. */
     911           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
     912             :                                                       dbdata, &version),
     913             :                                  ISC_R_SUCCESS,
     914             :                                  "Failed to start transaction");
     915           1 :         torture_assert_int_equal_goto(tctx,
     916             :                         dlz_delrdataset(name,
     917             :                                         expected1->records[0].type,
     918             :                                         dbdata, version),
     919             :                         ISC_R_NOTFOUND, ret, cancel_version,
     920             :                         talloc_asprintf(tctx, "Deleted name[%s] type[%s]\n",
     921             :                         name, expected1->records[0].type));
     922           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);
     923             : 
     924             :         /* Step 3. */
     925           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
     926             :                                                       dbdata, &version),
     927             :                                  ISC_R_SUCCESS,
     928             :                                  "Failed to start transaction");
     929           1 :         torture_assert_int_equal_goto(tctx,
     930             :                         dlz_subrdataset(name, data0, dbdata, version),
     931             :                         ISC_R_NOTFOUND, ret, cancel_version,
     932             :                         talloc_asprintf(tctx, "Deleted name[%s] data[%s]\n",
     933             :                         name, data0));
     934           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);
     935             : 
     936             :         /* Step 4. */
     937           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
     938             :                                                       dbdata, &version),
     939             :                                  ISC_R_SUCCESS,
     940             :                                  "Failed to start transaction");
     941           1 :         torture_assert_int_equal_goto(tctx,
     942             :                         dlz_addrdataset(name, data0, dbdata, version),
     943             :                         ISC_R_SUCCESS, ret, cancel_version,
     944             :                         talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
     945             :                         name, data0));
     946           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
     947             : 
     948             :         /* Step 5. */
     949           1 :         expected1->num_rr = 0;
     950           1 :         expected1->records[0].printed = false;
     951           1 :         expected1->records[1].printed = false;
     952           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
     953             :                                                   expected1->query_name, dbdata,
     954             :                                                   (dns_sdlzlookup_t *)expected1,
     955             :                                                   methods, clientinfo),
     956             :                                  ISC_R_SUCCESS,
     957             :                                  "Not found hostname");
     958           1 :         torture_assert(tctx, expected1->records[0].printed,
     959             :                        talloc_asprintf(tctx,
     960             :                        "Failed to have putrr callback run name[%s] for type %s",
     961             :                        expected1->records[0].name,
     962             :                        expected1->records[0].type));
     963           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 1,
     964             :                                  "Got wrong record count");
     965             : 
     966             :         /* Step 6. */
     967           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
     968             :                                                       dbdata, &version),
     969             :                                  ISC_R_SUCCESS,
     970             :                                  "Failed to start transaction");
     971           1 :         torture_assert_int_equal_goto(tctx,
     972             :                         dlz_addrdataset(name, data1, dbdata, version),
     973             :                         ISC_R_SUCCESS, ret, cancel_version,
     974             :                         talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
     975             :                         name, data1));
     976           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
     977             : 
     978             :         /* Step 7. */
     979           1 :         expected1->num_rr = 0;
     980           1 :         expected1->records[0].printed = false;
     981           1 :         expected1->records[1].printed = false;
     982           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
     983             :                                                   expected1->query_name, dbdata,
     984             :                                                   (dns_sdlzlookup_t *)expected1,
     985             :                                                   methods, clientinfo),
     986             :                                  ISC_R_SUCCESS,
     987             :                                  "Not found hostname");
     988           1 :         torture_assert(tctx, expected1->records[0].printed,
     989             :                        talloc_asprintf(tctx,
     990             :                        "Failed to have putrr callback run name[%s] for type %s",
     991             :                        expected1->records[0].name,
     992             :                        expected1->records[0].type));
     993           1 :         torture_assert(tctx, expected1->records[1].printed,
     994             :                        talloc_asprintf(tctx,
     995             :                        "Failed to have putrr callback run name[%s] for type %s",
     996             :                        expected1->records[1].name,
     997             :                        expected1->records[1].type));
     998           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 2,
     999             :                                  "Got wrong record count");
    1000             : 
    1001             :         /* Step 8. */
    1002           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
    1003             :                                                       dbdata, &version),
    1004             :                                  ISC_R_SUCCESS,
    1005             :                                  "Failed to start transaction");
    1006           1 :         torture_assert_int_equal_goto(tctx,
    1007             :                         dlz_subrdataset(name, data2, dbdata, version),
    1008             :                         ISC_R_NOTFOUND, ret, cancel_version,
    1009             :                         talloc_asprintf(tctx, "Deleted name[%s] data[%s]\n",
    1010             :                         name, data2));
    1011           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
    1012             : 
    1013             :         /* Step 9. */
    1014           1 :         expected1->num_rr = 0;
    1015           1 :         expected1->records[0].printed = false;
    1016           1 :         expected1->records[1].printed = false;
    1017           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
    1018             :                                                   expected1->query_name, dbdata,
    1019             :                                                   (dns_sdlzlookup_t *)expected1,
    1020             :                                                   methods, clientinfo),
    1021             :                                  ISC_R_SUCCESS,
    1022             :                                  "Not found hostname");
    1023           1 :         torture_assert(tctx, expected1->records[0].printed,
    1024             :                        talloc_asprintf(tctx,
    1025             :                        "Failed to have putrr callback run name[%s] for type %s",
    1026             :                        expected1->records[0].name,
    1027             :                        expected1->records[0].type));
    1028           1 :         torture_assert(tctx, expected1->records[1].printed,
    1029             :                        talloc_asprintf(tctx,
    1030             :                        "Failed to have putrr callback run name[%s] for type %s",
    1031             :                        expected1->records[1].name,
    1032             :                        expected1->records[1].type));
    1033           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 2,
    1034             :                                  "Got wrong record count");
    1035             : 
    1036             :         /* Step 10. */
    1037           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
    1038             :                                                       dbdata, &version),
    1039             :                                  ISC_R_SUCCESS,
    1040             :                                  "Failed to start transaction");
    1041           1 :         torture_assert_int_equal_goto(tctx,
    1042             :                         dlz_subrdataset(name, data0, dbdata, version),
    1043             :                         ISC_R_SUCCESS, ret, cancel_version,
    1044             :                         talloc_asprintf(tctx, "Failed to delete name[%s] data[%s]\n",
    1045             :                         name, data0));
    1046           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
    1047             : 
    1048             :         /* Step 11. */
    1049           1 :         expected1->num_rr = 0;
    1050           1 :         expected1->records[0].printed = false;
    1051           1 :         expected1->records[1].printed = false;
    1052           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
    1053             :                                                   expected1->query_name, dbdata,
    1054             :                                                   (dns_sdlzlookup_t *)expected1,
    1055             :                                                   methods, clientinfo),
    1056             :                                  ISC_R_SUCCESS,
    1057             :                                  "Not found hostname");
    1058           1 :         torture_assert(tctx, expected1->records[1].printed,
    1059             :                        talloc_asprintf(tctx,
    1060             :                        "Failed to have putrr callback run name[%s] for type %s",
    1061             :                        expected1->records[1].name,
    1062             :                        expected1->records[1].type));
    1063           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 1,
    1064             :                                  "Got wrong record count");
    1065             : 
    1066             :         /* Step 12. */
    1067           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
    1068             :                                                       dbdata, &version),
    1069             :                                  ISC_R_SUCCESS,
    1070             :                                  "Failed to start transaction");
    1071           1 :         torture_assert_int_equal_goto(tctx,
    1072             :                         dlz_subrdataset(name, data1, dbdata, version),
    1073             :                         ISC_R_SUCCESS, ret, cancel_version,
    1074             :                         talloc_asprintf(tctx, "Failed to delete name[%s] data[%s]\n",
    1075             :                         name, data1));
    1076           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
    1077             : 
    1078             :         /* Step 13. */
    1079           1 :         expected1->num_rr = 0;
    1080           1 :         expected1->records[0].printed = false;
    1081           1 :         expected1->records[1].printed = false;
    1082           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
    1083             :                                                   expected1->query_name, dbdata,
    1084             :                                                   (dns_sdlzlookup_t *)expected1,
    1085             :                                                   methods, clientinfo),
    1086             :                                  ISC_R_NOTFOUND,
    1087             :                                  "Found hostname");
    1088           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 0,
    1089             :                                  "Got wrong record count");
    1090             : 
    1091             :         /* Step 14. */
    1092           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
    1093             :                                                       dbdata, &version),
    1094             :                                  ISC_R_SUCCESS,
    1095             :                                  "Failed to start transaction");
    1096           1 :         torture_assert_int_equal_goto(tctx,
    1097             :                         dlz_addrdataset(name, data0, dbdata, version),
    1098             :                         ISC_R_SUCCESS, ret, cancel_version,
    1099             :                         talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
    1100             :                         name, data0));
    1101           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
    1102             : 
    1103             :         /* Step 15. */
    1104           1 :         expected1->num_rr = 0;
    1105           1 :         expected1->records[0].printed = false;
    1106           1 :         expected1->records[1].printed = false;
    1107           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
    1108             :                                                   expected1->query_name, dbdata,
    1109             :                                                   (dns_sdlzlookup_t *)expected1,
    1110             :                                                   methods, clientinfo),
    1111             :                                  ISC_R_SUCCESS,
    1112             :                                  "Not found hostname");
    1113           1 :         torture_assert(tctx, expected1->records[0].printed,
    1114             :                        talloc_asprintf(tctx,
    1115             :                        "Failed to have putrr callback run name[%s] for type %s",
    1116             :                        expected1->records[0].name,
    1117             :                        expected1->records[0].type));
    1118           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 1,
    1119             :                                  "Got wrong record count");
    1120             : 
    1121             :         /* Step 16. */
    1122           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
    1123             :                                                       dbdata, &version),
    1124             :                                  ISC_R_SUCCESS,
    1125             :                                  "Failed to start transaction");
    1126           1 :         torture_assert_int_equal_goto(tctx,
    1127             :                         dlz_addrdataset(name, data1, dbdata, version),
    1128             :                         ISC_R_SUCCESS, ret, cancel_version,
    1129             :                         talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
    1130             :                         name, data1));
    1131           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
    1132             : 
    1133             :         /* Step 17. */
    1134           1 :         expected1->num_rr = 0;
    1135           1 :         expected1->records[0].printed = false;
    1136           1 :         expected1->records[1].printed = false;
    1137           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
    1138             :                                                   expected1->query_name, dbdata,
    1139             :                                                   (dns_sdlzlookup_t *)expected1,
    1140             :                                                   methods, clientinfo),
    1141             :                                  ISC_R_SUCCESS,
    1142             :                                  "Not found hostname");
    1143           1 :         torture_assert(tctx, expected1->records[0].printed,
    1144             :                        talloc_asprintf(tctx,
    1145             :                        "Failed to have putrr callback run name[%s] for type %s",
    1146             :                        expected1->records[0].name,
    1147             :                        expected1->records[0].type));
    1148           1 :         torture_assert(tctx, expected1->records[1].printed,
    1149             :                        talloc_asprintf(tctx,
    1150             :                        "Failed to have putrr callback run name[%s] for type %s",
    1151             :                        expected1->records[1].name,
    1152             :                        expected1->records[1].type));
    1153           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 2,
    1154             :                                  "Got wrong record count");
    1155             : 
    1156             :         /* Step 18. */
    1157           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
    1158             :                                                       dbdata, &version),
    1159             :                                  ISC_R_SUCCESS,
    1160             :                                  "Failed to start transaction");
    1161           1 :         torture_assert_int_equal_goto(tctx,
    1162             :                         dlz_addrdataset(name, data0, dbdata, version),
    1163             :                         ISC_R_SUCCESS, ret, cancel_version,
    1164             :                         talloc_asprintf(tctx, "Failed to update name[%s] data[%s]\n",
    1165             :                         name, data0));
    1166           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
    1167             : 
    1168             :         /* Step 19. */
    1169           1 :         expected1->num_rr = 0;
    1170           1 :         expected1->records[0].printed = false;
    1171           1 :         expected1->records[1].printed = false;
    1172           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
    1173             :                                                   expected1->query_name, dbdata,
    1174             :                                                   (dns_sdlzlookup_t *)expected1,
    1175             :                                                   methods, clientinfo),
    1176             :                                  ISC_R_SUCCESS,
    1177             :                                  "Not found hostname");
    1178           1 :         torture_assert(tctx, expected1->records[0].printed,
    1179             :                        talloc_asprintf(tctx,
    1180             :                        "Failed to have putrr callback run name[%s] for type %s",
    1181             :                        expected1->records[0].name,
    1182             :                        expected1->records[0].type));
    1183           1 :         torture_assert(tctx, expected1->records[1].printed,
    1184             :                        talloc_asprintf(tctx,
    1185             :                        "Failed to have putrr callback run name[%s] for type %s",
    1186             :                        expected1->records[1].name,
    1187             :                        expected1->records[1].type));
    1188           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 2,
    1189             :                                  "Got wrong record count");
    1190             : 
    1191             :         /* Step 20. */
    1192           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
    1193             :                                                       dbdata, &version),
    1194             :                                  ISC_R_SUCCESS,
    1195             :                                  "Failed to start transaction");
    1196           1 :         torture_assert_int_equal_goto(tctx,
    1197             :                         dlz_delrdataset(name, "txt", dbdata, version),
    1198             :                         ISC_R_FAILURE, ret, cancel_version,
    1199             :                         talloc_asprintf(tctx, "Deleted name[%s] type[%s]\n",
    1200             :                         name, "txt"));
    1201           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);
    1202             : 
    1203             :         /* Step 21. */
    1204           1 :         expected1->num_rr = 0;
    1205           1 :         expected1->records[0].printed = false;
    1206           1 :         expected1->records[1].printed = false;
    1207           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
    1208             :                                                   expected1->query_name, dbdata,
    1209             :                                                   (dns_sdlzlookup_t *)expected1,
    1210             :                                                   methods, clientinfo),
    1211             :                                  ISC_R_SUCCESS,
    1212             :                                  "Not found hostname");
    1213           1 :         torture_assert(tctx, expected1->records[0].printed,
    1214             :                        talloc_asprintf(tctx,
    1215             :                        "Failed to have putrr callback run name[%s] for type %s",
    1216             :                        expected1->records[0].name,
    1217             :                        expected1->records[0].type));
    1218           1 :         torture_assert(tctx, expected1->records[1].printed,
    1219             :                        talloc_asprintf(tctx,
    1220             :                        "Failed to have putrr callback run name[%s] for type %s",
    1221             :                        expected1->records[1].name,
    1222             :                        expected1->records[1].type));
    1223           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 2,
    1224             :                                  "Got wrong record count");
    1225             : 
    1226             :         /* Step 22. */
    1227           1 :         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
    1228             :                                                       dbdata, &version),
    1229             :                                  ISC_R_SUCCESS,
    1230             :                                  "Failed to start transaction");
    1231           1 :         torture_assert_int_equal_goto(tctx,
    1232             :                         dlz_delrdataset(name,
    1233             :                                         expected1->records[0].type,
    1234             :                                         dbdata, version),
    1235             :                         ISC_R_SUCCESS, ret, cancel_version,
    1236             :                         talloc_asprintf(tctx, "Failed to delete name[%s] type[%s]\n",
    1237             :                         name, expected1->records[0].type));
    1238           1 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
    1239             : 
    1240             :         /* Step 23. */
    1241           1 :         expected1->num_rr = 0;
    1242           1 :         expected1->records[0].printed = false;
    1243           1 :         expected1->records[1].printed = false;
    1244           1 :         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
    1245             :                                                   expected1->query_name, dbdata,
    1246             :                                                   (dns_sdlzlookup_t *)expected1,
    1247             :                                                   methods, clientinfo),
    1248             :                                  ISC_R_NOTFOUND,
    1249             :                                  "Found hostname");
    1250           1 :         torture_assert_int_equal(tctx, expected1->num_rr, 0,
    1251             :                                  "Got wrong record count");
    1252             : 
    1253           1 :         dlz_destroy(dbdata);
    1254             : 
    1255           1 :         return true;
    1256             : 
    1257           0 : cancel_version:
    1258           0 :         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);
    1259           0 :         return ret;
    1260             : }
    1261             : 
    1262             : /*
    1263             :  * Test zone transfer requests restrictions
    1264             :  *
    1265             :  * 1: test that zone transfer is denied by default
    1266             :  * 2: with an authorized list of IPs set in smb.conf, test that zone transfer
    1267             :  *    is accepted only for selected IPs.
    1268             :  */
    1269           1 : static bool test_dlz_bind9_allowzonexfr(struct torture_context *tctx)
    1270             : {
    1271           0 :         void *dbdata;
    1272           2 :         const char *argv[] = {
    1273             :                 "samba_dlz",
    1274             :                 "-H",
    1275           1 :                 dlz_bind9_binddns_dir(tctx, "dns/sam.ldb"),
    1276             :                 NULL
    1277             :         };
    1278           0 :         isc_result_t ret;
    1279           1 :         dns_dlzdb_t *dlzdb = NULL;
    1280           0 :         bool ok;
    1281             : 
    1282           1 :         tctx_static = tctx;
    1283           1 :         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
    1284             :                                                   "log", dlz_bind9_log_wrapper,
    1285             :                                                   "writeable_zone", dlz_bind9_writeable_zone_hook,
    1286             :                                                   "putrr", dlz_bind9_putrr_hook,
    1287             :                                                   "putnamedrr", dlz_bind9_putnamedrr_hook,
    1288             :                                                   NULL),
    1289             :                                  ISC_R_SUCCESS,
    1290             :                                  "Failed to create samba_dlz");
    1291             : 
    1292           1 :         torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dlzdb, dbdata),
    1293             :                                                      ISC_R_SUCCESS,
    1294             :                                              "Failed to configure samba_dlz");
    1295             : 
    1296             :     /* Ask for zone transfer with no specific config => expect denied */
    1297           1 :     ret = dlz_allowzonexfr(dbdata, lpcfg_dnsdomain(tctx->lp_ctx), "127.0.0.1");
    1298           1 :     torture_assert_int_equal(tctx, ret, ISC_R_NOPERM,
    1299             :                             "Zone transfer accepted with default settings");
    1300             : 
    1301             :     /* Ask for zone transfer with authorizations set */
    1302           1 :     ok = lpcfg_set_option(tctx->lp_ctx, "dns zone transfer clients allow=127.0.0.1,1234:5678::1,192.168.0.");
    1303           1 :     torture_assert(tctx, ok, "Failed to set dns zone transfer clients allow option.");
    1304             : 
    1305           1 :     ok = lpcfg_set_option(tctx->lp_ctx, "dns zone transfer clients deny=192.168.0.2");
    1306           1 :     torture_assert(tctx, ok, "Failed to set dns zone transfer clients deny option.");
    1307             : 
    1308           1 :     ret = dlz_allowzonexfr(dbdata, lpcfg_dnsdomain(tctx->lp_ctx), "127.0.0.1");
    1309           1 :     torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    1310             :                             "Zone transfer refused for authorized IPv4 address");
    1311             : 
    1312           1 :     ret = dlz_allowzonexfr(dbdata, lpcfg_dnsdomain(tctx->lp_ctx), "1234:5678::1");
    1313           1 :     torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    1314             :                              "Zone transfer refused for authorized IPv6 address.");
    1315             : 
    1316           1 :     ret = dlz_allowzonexfr(dbdata, lpcfg_dnsdomain(tctx->lp_ctx), "10.0.0.1");
    1317           1 :     torture_assert_int_equal(tctx, ret, ISC_R_NOPERM,
    1318             :                             "Zone transfer accepted for unauthorized IP");
    1319             : 
    1320           1 :     ret = dlz_allowzonexfr(dbdata, lpcfg_dnsdomain(tctx->lp_ctx), "192.168.0.1");
    1321           1 :     torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    1322             :                              "Zone transfer refused for address in authorized IPv4 subnet.");
    1323             : 
    1324           1 :     ret = dlz_allowzonexfr(dbdata, lpcfg_dnsdomain(tctx->lp_ctx), "192.168.0.2");
    1325           1 :     torture_assert_int_equal(tctx, ret, ISC_R_NOPERM,
    1326             :                             "Zone transfer allowed for denied client.");
    1327             : 
    1328           1 :     dlz_destroy(dbdata);
    1329           1 :     return true;
    1330             : }
    1331             : 
    1332             : 
    1333           1 : static int init_dlz(struct torture_context *tctx,
    1334             :                     void **dbdata)
    1335             : {
    1336           0 :         isc_result_t ret;
    1337           2 :         const char *argv[] = {
    1338             :                 "samba_dlz",
    1339             :                 "-H",
    1340           1 :                 dlz_bind9_binddns_dir(tctx, "dns/sam.ldb"),
    1341             :                 NULL
    1342             :         };
    1343             : 
    1344           1 :         ret = dlz_create("samba_dlz", 3, argv, dbdata,
    1345             :                          "log", dlz_bind9_log_wrapper,
    1346             :                          "writeable_zone", dlz_bind9_writeable_zone_hook,
    1347             :                          "putrr", dlz_bind9_putrr_hook,
    1348             :                          "putnamedrr", dlz_bind9_putnamedrr_hook,
    1349             :                          NULL);
    1350             : 
    1351           1 :         torture_assert_int_equal(tctx,
    1352             :                                  ret,
    1353             :                                  ISC_R_SUCCESS,
    1354             :                                  "Failed to create samba_dlz");
    1355             : 
    1356           1 :         ret = dlz_configure((void*)tctx, NULL, *dbdata);
    1357           1 :         torture_assert_int_equal(tctx,
    1358             :                                  ret,
    1359             :                                  ISC_R_SUCCESS,
    1360             :                                  "Failed to configure samba_dlz");
    1361             : 
    1362           1 :         return true;
    1363             : }
    1364             : 
    1365             : 
    1366           1 : static int init_gensec(struct torture_context *tctx,
    1367             :                        struct gensec_security **gensec_client_context)
    1368             : {
    1369           0 :         NTSTATUS status;
    1370             :         /*
    1371             :          * Prepare session info
    1372             :          */
    1373           1 :         status = gensec_client_start(tctx, gensec_client_context,
    1374             :                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx));
    1375           1 :         torture_assert_ntstatus_ok(tctx, status,
    1376             :                                    "gensec_client_start (client) failed");
    1377             : 
    1378             :         /*
    1379             :          * dlz_bind9 use the special dns/host.domain account
    1380             :          */
    1381           1 :         status = gensec_set_target_hostname(*gensec_client_context,
    1382           1 :                                             talloc_asprintf(tctx,
    1383             :                                 "%s.%s",
    1384             :                                 torture_setting_string(tctx, "host", NULL),
    1385             :                                 lpcfg_dnsdomain(tctx->lp_ctx)));
    1386           1 :         torture_assert_ntstatus_ok(tctx, status,
    1387             :                                    "gensec_set_target_hostname (client) failed");
    1388             : 
    1389           1 :         status = gensec_set_target_service(*gensec_client_context, "dns");
    1390           1 :         torture_assert_ntstatus_ok(tctx, status,
    1391             :                                    "gensec_set_target_service failed");
    1392             : 
    1393           1 :         status = gensec_set_credentials(*gensec_client_context,
    1394             :                                         samba_cmdline_get_creds());
    1395           1 :         torture_assert_ntstatus_ok(tctx, status,
    1396             :                                    "gensec_set_credentials (client) failed");
    1397             : 
    1398           1 :         status = gensec_start_mech_by_sasl_name(*gensec_client_context,
    1399             :                                                 "GSS-SPNEGO");
    1400           1 :         torture_assert_ntstatus_ok(tctx, status,
    1401             :                                    "gensec_start_mech_by_sasl_name (client) failed");
    1402             : 
    1403             : 
    1404           1 :         return true;
    1405             : }
    1406             : 
    1407             : 
    1408             : 
    1409           6 : static bool expected_record(TALLOC_CTX *mem_ctx,
    1410             :                             struct test_expected_record *r,
    1411             :                             const char *name,
    1412             :                             const char *type,
    1413             :                             const char *data)
    1414             : {
    1415           6 :         unsigned int ttl = 3600;
    1416           6 :         const char *rdata = talloc_asprintf(
    1417             :                 mem_ctx,
    1418             :                 "%s.\t" "%u\t" "in\t" "%s\t" "%s",
    1419             :                 name, ttl, type, data);
    1420           6 :         if (rdata == NULL) {
    1421           0 :                 return false;
    1422             :         }
    1423             : 
    1424           6 :         *r = (struct test_expected_record){
    1425             :                 .name = name,
    1426             :                 .type = type,
    1427             :                 .data = data,
    1428             :                 .ttl = ttl,
    1429             :                 .printed = false,
    1430             :                 .rdata = rdata
    1431             :         };
    1432           6 :         return true;
    1433             : }
    1434             : 
    1435             : 
    1436             : struct dlz_test_handle {
    1437             :         struct dcerpc_pipe *p;
    1438             : };
    1439             : 
    1440             : 
    1441           2 : static bool set_zone_aging(struct torture_context *tctx,
    1442             :                            const char *zone,
    1443             :                            int value)
    1444             : {
    1445           0 :         int ret;
    1446           2 :         char *cmd = talloc_asprintf(tctx,
    1447             :                                     "bin/samba-tool dns zoneoptions "
    1448             :                                     "$SERVER %s -U$USERNAME%%$PASSWORD "
    1449             :                                     "--aging %d", zone, value);
    1450             : 
    1451           2 :         if (cmd == NULL) {
    1452           0 :                 return false;
    1453             :         }
    1454             : 
    1455           2 :         ret = system(cmd);
    1456           2 :         if (ret != 0) {
    1457           0 :                 TALLOC_FREE(cmd);
    1458           0 :                 return false;
    1459             :         }
    1460           2 :         TALLOC_FREE(cmd);
    1461           2 :         return true;
    1462             : }
    1463             : 
    1464             : 
    1465           1 : static struct ldb_context* get_samdb(struct torture_context *tctx)
    1466             : {
    1467           1 :         struct ldb_context *samdb = NULL;
    1468           0 :         char *errstring;
    1469           1 :         int ret = samdb_connect_url(
    1470             :                 tctx,
    1471             :                 NULL,
    1472             :                 tctx->lp_ctx,
    1473             :                 system_session(tctx->lp_ctx),
    1474             :                 0,
    1475           1 :                 dlz_bind9_binddns_dir(tctx, "dns/sam.ldb"),
    1476             :                 NULL,
    1477             :                 &samdb,
    1478             :                 &errstring);
    1479           1 :         if (ret != LDB_SUCCESS) {
    1480           0 :                 return NULL;
    1481             :         }
    1482           1 :         return samdb;
    1483             : }
    1484             : 
    1485             : 
    1486          11 : static void print_node_records(struct torture_context *tctx,
    1487             :                                struct ldb_context *samdb,
    1488             :                                struct ldb_dn *node_dn,
    1489             :                                const char *msg)
    1490             : {
    1491           0 :         int ret;
    1492          11 :         struct ldb_result *result = NULL;
    1493           0 :         struct dnsp_DnssrvRpcRecord rec;
    1494          11 :         struct ldb_message_element *el = NULL;
    1495           0 :         size_t i;
    1496             : 
    1497          11 :         if (msg != NULL) {
    1498          11 :                 torture_comment(tctx,
    1499             :                                 "\033[1;32m%s\033[0m\n",
    1500             :                                 msg);
    1501             :         }
    1502             : 
    1503          11 :         ret = dsdb_search(samdb, tctx, &result, node_dn,
    1504             :                           LDB_SCOPE_SUBTREE, NULL,
    1505             :                           0, NULL);
    1506          11 :         if (ret != LDB_SUCCESS) {
    1507           0 :                 torture_comment(tctx,
    1508             :                                 "Failed to find node: %s",
    1509             :                                 ldb_errstring(samdb));
    1510             :         }
    1511             : 
    1512          11 :         el = ldb_msg_find_element(result->msgs[0], "dnsRecord");
    1513             : 
    1514          66 :         for (i = 0; i < el->num_values; i++) {
    1515         110 :                 ret = ndr_pull_struct_blob(
    1516          55 :                         &(el->values[i]),
    1517             :                         result,
    1518             :                         &rec,
    1519             :                         (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord);
    1520          55 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ret)) {
    1521           0 :                         DBG_ERR("Failed to pull dns rec blob [%zu].\n",
    1522             :                                 i);
    1523           0 :                         TALLOC_FREE(result);
    1524             :                 }
    1525          55 :                 torture_comment(tctx, "record[%zu]:\n", i);
    1526          55 :                 torture_comment(tctx, "type: %d\n", rec.wType);
    1527          55 :                 torture_comment(tctx, "timestamp: %u\n", rec.dwTimeStamp);
    1528          55 :                 torture_comment(tctx, "%s\n",
    1529             :                                 NDR_PRINT_STRUCT_STRING(result,
    1530             :                                                         dnsp_DnssrvRpcRecord,
    1531             :                                                         &rec));
    1532             :         }
    1533          11 : }
    1534             : 
    1535             : 
    1536             : 
    1537             : /*
    1538             :  * Test some MORE updates, this time focussing on more record types and aging.
    1539             :  */
    1540           1 : static bool test_dlz_bind9_aging(struct torture_context *tctx)
    1541             : {
    1542           1 :         struct gensec_security *gensec_client_context = NULL;
    1543           0 :         DATA_BLOB client_to_server, server_to_client;
    1544           0 :         NTSTATUS status;
    1545           1 :         void *dbdata = NULL;
    1546           1 :         void *version = NULL;
    1547           1 :         struct test_expected_rr *testdata = NULL;
    1548           1 :         bool ok = false;
    1549           1 :         struct ldb_context *samdb = NULL;
    1550           0 :         isc_result_t ret;
    1551           0 :         size_t i, j;
    1552           1 :         const char *domain = lpcfg_dnsdomain(tctx->lp_ctx);
    1553           1 :         struct ldb_dn *domain_dn = NULL;
    1554           1 :         struct ldb_dn *node_dn = NULL;
    1555           1 :         struct ldb_result *result = NULL;
    1556           0 :         uint32_t dns_timestamp_before;
    1557           0 :         uint32_t dns_timestamp_after;
    1558           1 :         const char *name = NULL;
    1559           1 :         const char *attrs[] = {"dnsrecord", NULL};
    1560           1 :         const char *node_dn_str = NULL;
    1561           1 :         struct ldb_message_element *el = NULL;
    1562           1 :         struct ldb_message *msg = NULL;
    1563             : 
    1564           1 :         tctx_static = tctx;
    1565             : 
    1566             :         /* Step 0. set things up */
    1567             : 
    1568           1 :         ok = init_dlz(tctx, &dbdata);
    1569           1 :         if (! ok) {
    1570           0 :                 torture_fail(tctx, "Failed to init_dlz");
    1571             :         }
    1572           1 :         ok = init_gensec(tctx, &gensec_client_context);
    1573           1 :         if (! ok) {
    1574           0 :                 torture_fail(tctx, "Failed to init_gensec");
    1575             :         }
    1576             : 
    1577           1 :         samdb = get_samdb(tctx);
    1578           1 :         if (samdb == NULL) {
    1579           0 :                 torture_fail(tctx, "Failed to connect to samdb");
    1580             :         }
    1581             : 
    1582           1 :         domain_dn = ldb_get_default_basedn(samdb);
    1583           1 :         testdata = talloc_zero(tctx, struct test_expected_rr);
    1584           1 :         torture_assert(tctx, testdata != NULL, "talloc failed");
    1585           1 :         testdata->tctx = tctx;
    1586             : 
    1587           1 :         testdata->query_name = __func__;
    1588             : 
    1589           1 :         name = talloc_asprintf(testdata, "%s.%s",
    1590             :                                testdata->query_name,
    1591             :                                domain);
    1592           1 :         torture_assert(tctx, name != NULL, "talloc failed");
    1593             : 
    1594           1 :         testdata->num_records = 6;
    1595           1 :         testdata->records = talloc_zero_array(testdata,
    1596             :                                               struct test_expected_record,
    1597             :                                               testdata->num_records);
    1598           1 :         torture_assert(tctx, testdata->records != NULL, "talloc failed");
    1599             : 
    1600           1 :         torture_assert(tctx,
    1601             :                        expected_record(testdata->records,
    1602             :                                        &testdata->records[0],
    1603             :                                        testdata->query_name,
    1604             :                                        "aaaa",
    1605             :                                        "::1"),
    1606             :                        "failed to add record");
    1607             : 
    1608           1 :         torture_assert(tctx,
    1609             :                        expected_record(testdata->records,
    1610             :                                        &testdata->records[1],
    1611             :                                        testdata->query_name,
    1612             :                                        "a",
    1613             :                                        "127.11.12.13"),
    1614             :                        "failed to add record");
    1615           1 :         torture_assert(tctx,
    1616             :                        expected_record(testdata->records,
    1617             :                                        &testdata->records[2],
    1618             :                                        testdata->query_name,
    1619             :                                        "a",
    1620             :                                        "127.11.12.14"),
    1621             :                        "failed to add record");
    1622             : 
    1623           1 :         torture_assert(tctx,
    1624             :                        expected_record(testdata->records,
    1625             :                                        &testdata->records[3],
    1626             :                                        testdata->query_name,
    1627             :                                        "ptr",
    1628             :                                        "samba.example.com"),
    1629             :                        "failed to add record");
    1630             : 
    1631             :         /*
    1632             :          * NOTE: Here we add the MX record with the priority before the name,
    1633             :          * rather than the other way around which you are more likely to see
    1634             :          * ("samba.example.com 11" e.g. in samba-tool dns), because this is
    1635             :          * how it goes in BIND9 configuration.
    1636             :          */
    1637           1 :         torture_assert(tctx,
    1638             :                        expected_record(testdata->records,
    1639             :                                        &testdata->records[4],
    1640             :                                        testdata->query_name,
    1641             :                                        "mx",
    1642             :                                        "11 samba.example.com."),
    1643             :                        "failed to add record");
    1644             : 
    1645           1 :         torture_assert(tctx,
    1646             :                        expected_record(testdata->records,
    1647             :                                        &testdata->records[5],
    1648             :                                        testdata->query_name,
    1649             :                                        "cname",
    1650             :                                        "samba.example.com"),
    1651             :                        "failed to add record");
    1652             : 
    1653             : 
    1654           1 :         server_to_client = data_blob(NULL, 0);
    1655             : 
    1656             :         /* Do one step of the client-server update dance */
    1657           1 :         status = gensec_update(gensec_client_context, tctx, server_to_client,
    1658             :                                &client_to_server);
    1659           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
    1660           0 :                 torture_assert_ntstatus_ok(tctx, status,
    1661             :                                            "gensec_update (client) failed");
    1662             :         }
    1663             : 
    1664           1 :         torture_assert_int_equal(tctx, dlz_ssumatch(
    1665             :                                 cli_credentials_get_username(
    1666             :                                         samba_cmdline_get_creds()),
    1667             :                                 domain,
    1668             :                                 "127.0.0.1",
    1669             :                                 testdata->records[0].type,
    1670             :                                 "key",
    1671             :                                 client_to_server.length,
    1672             :                                 client_to_server.data,
    1673             :                                 dbdata),
    1674             :                                 ISC_TRUE,
    1675             :                          "Failed to check key for update rights samba_dlz");
    1676             : 
    1677             :         /* remember the DN for use below */
    1678           1 :         node_dn = ldb_dn_copy(testdata, domain_dn);
    1679           1 :         if (node_dn == NULL) {
    1680           0 :                 torture_fail(tctx, "Failed to make node dn");
    1681             :         }
    1682             : 
    1683           1 :         ok = ldb_dn_add_child_fmt(
    1684             :                 node_dn,
    1685             :                 "DC=%s,DC=%s,CN=MicrosoftDNS,DC=DomainDnsZones",
    1686             :                 testdata->query_name,
    1687             :                 domain);
    1688           1 :         if (! ok) {
    1689           0 :                 torture_fail(tctx, "Failed to make node dn");
    1690             :         }
    1691           1 :         node_dn_str = ldb_dn_get_linearized(node_dn);
    1692           1 :         if (node_dn_str == NULL) {
    1693           0 :                 torture_fail(tctx, "Failed to linearise node dn");
    1694             :         }
    1695             : 
    1696             :         /* LOOK: we are chopping off the last one (the CNAME) for now */
    1697           1 :         testdata->num_records = 5;
    1698             : 
    1699             :         /*
    1700             :          * We test the following:
    1701             :          *
    1702             :          * Step 1.  Ensure we are starting with an empty node.
    1703             :          * Step 2.  Add all the records (with aging off).
    1704             :          * Step 3.  Check the timestamps are now-ish.
    1705             :          * Step 4.  Add all the records AGAIN.
    1706             :          * Step 5:  Turn aging on.
    1707             :          * Step 6.  Add all the records again.
    1708             :          * Step 7.  Check the timestamps are still now-ish.
    1709             :          * Step 8.  Wind back the timestamps in the database.
    1710             :          * Step 9.  Do another update, changing some timestamps
    1711             :          * Step 10. Check that the timestamps are right.
    1712             :          * Step 11. Set one record to be static.
    1713             :          * Step 12. Do updates on some records, zeroing their timestamps
    1714             :          * Step 13. Check that the record timeouts are *mostly* zero.
    1715             :          * Step 14. Turn aging off
    1716             :          * Step 15. Update, setting timestamps to zero
    1717             :          * Step 16. Check that the timestamps are all zero.
    1718             :          * Step 17. Reset to non-zero via ldb, with aging still off.
    1719             :          * Step 18. Update with aging off. Nothing should change.
    1720             :          * Step 19. Check that the timestamps didn't change.
    1721             :          * Step 20. Delete all the records, 1 by 1.
    1722             :          */
    1723             : 
    1724             : 
    1725             :         /*
    1726             :          * Step 1. Ensure we are starting with an empty node.
    1727             :          */
    1728           1 :         torture_comment(tctx, "step 1: %s records are not there\n",
    1729             :                         testdata->query_name);
    1730           1 :         testdata->num_rr = 0;
    1731           1 :         torture_assert_int_equal(tctx, dlz_lookup(domain,
    1732             :                                                   testdata->query_name,
    1733             :                                                   dbdata,
    1734             :                                                   (dns_sdlzlookup_t *)testdata,
    1735             :                                                   NULL, NULL),
    1736             :                                  ISC_R_NOTFOUND,
    1737             :                                  "Found hostname");
    1738           1 :         torture_assert_int_equal(tctx, testdata->num_rr, 0,
    1739             :                                  "Got records when there should be none");
    1740             : 
    1741             : 
    1742           1 :         dns_timestamp_before = unix_to_dns_timestamp(time(NULL));
    1743             : 
    1744             :         /*
    1745             :          * Step 2. Add all the records (with aging off).
    1746             :          * After adding each one, expect to find it and earlier ones.
    1747             :          */
    1748           1 :         torture_comment(tctx,
    1749             :                         "step 2: add %zu records\n",
    1750             :                         testdata->num_records);
    1751             : 
    1752           6 :         for (i = 0; i < testdata->num_records; i++) {
    1753           5 :                 struct test_expected_record r = testdata->records[i];
    1754           5 :                 ret = dlz_newversion(domain, dbdata, &version);
    1755           5 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    1756             :                                          "Failed to start transaction");
    1757             : 
    1758           5 :                 ret = dlz_addrdataset(name, r.rdata, dbdata, version);
    1759           5 :                 torture_assert_int_equal_goto(
    1760             :                         tctx, ret, ISC_R_SUCCESS, ok,
    1761             :                         cancel_version,
    1762             :                         talloc_asprintf(tctx,
    1763             :                                         "Failed to add record %zu «%s»\n",
    1764             :                                         i, r.rdata));
    1765             : 
    1766           5 :                 dlz_closeversion(domain, true, dbdata, &version);
    1767             : 
    1768           5 :                 testdata->num_rr = 0;
    1769             : 
    1770           5 :                 ret = dlz_lookup(domain, testdata->query_name, dbdata,
    1771             :                                  (dns_sdlzlookup_t *)testdata, NULL, NULL);
    1772             : 
    1773           5 :                 torture_assert_int_equal(tctx, ret,
    1774             :                                          ISC_R_SUCCESS,
    1775             :                                          "Not found hostname");
    1776           5 :                 torture_assert_int_equal(tctx, testdata->num_rr, i + 1,
    1777             :                                          "Got wrong record count");
    1778             : 
    1779          30 :                 for (j = 0; j < testdata->num_records; j++) {
    1780          25 :                         struct test_expected_record *r2 = &testdata->records[j];
    1781          25 :                         if (j <= i) {
    1782          15 :                                 torture_assertf(
    1783             :                                         tctx,
    1784             :                                         r2->printed,
    1785             :                                         "putrr callback not run on %s «%s»",
    1786             :                                         r2->type, r2->name);
    1787             :                         } else {
    1788          10 :                                 torture_assertf(
    1789             :                                         tctx,
    1790             :                                         ! r2->printed,
    1791             :                                         "putrr callback should not see %s «%s»",
    1792             :                                         r2->type, r2->name);
    1793             :                         }
    1794          25 :                         r2->printed = false;
    1795             :                 }
    1796             :         }
    1797             : 
    1798           1 :         dns_timestamp_after = unix_to_dns_timestamp(time(NULL));
    1799             :         /*
    1800             :          * Step 3. Check the timestamps are now-ish.
    1801             :          *
    1802             :          * Those records should have DNS timestamps between
    1803             :          * dns_timestamp_before and dns_timestamp_after (the resolution is
    1804             :          * hourly, so probably both are equal).
    1805             :          */
    1806           1 :         ret = dsdb_search(samdb, tctx, &result, node_dn,
    1807             :                           LDB_SCOPE_SUBTREE, NULL,
    1808             :                           0, NULL);
    1809           1 :         if (ret != LDB_SUCCESS) {
    1810           0 :                 torture_fail(tctx,
    1811             :                              talloc_asprintf(
    1812             :                                      tctx,
    1813             :                                      "Failed to find %s node: %s",
    1814             :                                      name, ldb_errstring(samdb)));
    1815             :         }
    1816           1 :         torture_assert_int_equal(tctx, result->count, 1,
    1817             :                                  "Should be one node");
    1818             : 
    1819           1 :         el = ldb_msg_find_element(result->msgs[0], "dnsRecord");
    1820           1 :         torture_assert_not_null(tctx, el, "el");
    1821           1 :         torture_assert(tctx, dns_timestamp_before <= dns_timestamp_after, "<");
    1822           1 :         torture_assert_int_equal(tctx, el->num_values, testdata->num_records,
    1823             :                                  "num_values != num_records");
    1824             : 
    1825           6 :         for (i = 0; i < el->num_values; i++) {
    1826           0 :                 struct dnsp_DnssrvRpcRecord rec;
    1827           5 :                 ret = ndr_pull_struct_blob(
    1828           5 :                         &(el->values[i]),
    1829             :                         result,
    1830             :                         &rec,
    1831             :                         (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord);
    1832           5 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ret)) {
    1833           0 :                         DBG_ERR("Failed to pull dns rec blob [%zu].\n",
    1834             :                                 i);
    1835           0 :                         TALLOC_FREE(result);
    1836           0 :                         torture_fail(tctx, "Failed to pull dns rec blob");
    1837             :                 }
    1838           5 :                 torture_comment(tctx, "record[%zu]:\n", i);
    1839           5 :                 torture_comment(tctx, "type: %d\n", rec.wType);
    1840           5 :                 torture_comment(tctx, "timestamp: %u\n", rec.dwTimeStamp);
    1841           5 :                 torture_comment(tctx, "%s\n",
    1842             :                                 NDR_PRINT_STRUCT_STRING(result,
    1843             :                                                         dnsp_DnssrvRpcRecord,
    1844             :                                                         &rec));
    1845             : 
    1846           5 :                 torture_assert(tctx, rec.dwTimeStamp >= dns_timestamp_before,
    1847             :                                "timestamp < dns_timestamp_before");
    1848           5 :                 torture_assert(tctx, rec.dwTimeStamp <= dns_timestamp_after,
    1849             :                                "timestamp > dns_timestamp_after");
    1850             :         }
    1851             : 
    1852           1 :         talloc_free(result);
    1853             : 
    1854             :         /*
    1855             :          * Step 4. Add all the records AGAIN.
    1856             :          *
    1857             :          * After adding each one, we expect no change in the number or nature
    1858             :          * of records.
    1859             :          */
    1860           1 :         torture_comment(tctx, "step 4: add the records again\n");
    1861           6 :         for (i = 0; i < testdata->num_records; i++) {
    1862           5 :                 struct test_expected_record r = testdata->records[i];
    1863             : 
    1864           5 :                 ret = dlz_newversion(domain, dbdata, &version);
    1865           5 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    1866             :                                          "Failed to start transaction");
    1867             : 
    1868           5 :                 ret = dlz_addrdataset(name, r.rdata, dbdata, version);
    1869           5 :                 torture_assert_int_equal_goto(
    1870             :                         tctx, ret, ISC_R_SUCCESS, ok,
    1871             :                         cancel_version,
    1872             :                         talloc_asprintf(tctx,
    1873             :                                         "Failed to add record %zu «%s»\n",
    1874             :                                         i, r.rdata));
    1875             : 
    1876           5 :                 dlz_closeversion(domain, true, dbdata, &version);
    1877             : 
    1878           5 :                 testdata->num_rr = 0;
    1879             : 
    1880           5 :                 ret = dlz_lookup(domain, testdata->query_name, dbdata,
    1881             :                                  (dns_sdlzlookup_t *)testdata, NULL, NULL);
    1882             : 
    1883           5 :                 torture_assert_int_equal(tctx, ret,
    1884             :                                          ISC_R_SUCCESS,
    1885             :                                          "Not found hostname");
    1886           5 :                 torture_assert_int_equal(tctx,
    1887             :                                          testdata->num_rr,
    1888             :                                          testdata->num_records,
    1889             :                                          "Got wrong record count");
    1890             : 
    1891          20 :                 for (j = 0; j <= i; j++) {
    1892             :                         /* these ones are printed again. */
    1893          15 :                         struct test_expected_record *r2 = &testdata->records[j];
    1894          15 :                         torture_assert(
    1895             :                                 tctx,
    1896             :                                 r2->printed,
    1897             :                                 talloc_asprintf(
    1898             :                                         tctx,
    1899             :                                         "putrr callback not run on %s «%s»",
    1900             :                                         r2->type, r2->name));
    1901          15 :                         r2->printed = false;
    1902             :                 }
    1903             :         }
    1904             : 
    1905           1 :         print_node_records(tctx, samdb, node_dn, "after adding again");
    1906             : 
    1907             : 
    1908             :         /*
    1909             :          * Step 5: Turn aging on.
    1910             :          */
    1911           1 :         torture_comment(tctx, "step 5: turn aging on\n");
    1912           1 :         ok = set_zone_aging(tctx, domain, 1);
    1913           1 :         torture_assert(tctx, ok, "failed to enable aging");
    1914             : 
    1915           1 :         print_node_records(tctx, samdb, node_dn, "aging on");
    1916             : 
    1917             :         /*
    1918             :          * Step 6. Add all the records again.
    1919             :          *
    1920             :          * We expect no change in the number or nature of records, even with
    1921             :          * aging on, because the default noRefreshInterval is 7 days (also,
    1922             :          * there should be no change because almost no time has passed).
    1923             :          */
    1924           1 :         torture_comment(tctx, "step 6: add records again\n");
    1925             : 
    1926           6 :         for (i = 0; i < testdata->num_records; i++) {
    1927           5 :                 struct test_expected_record r = testdata->records[i];
    1928             : 
    1929           5 :                 ret = dlz_newversion(domain, dbdata, &version);
    1930           5 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    1931             :                                          "Failed to start transaction");
    1932             : 
    1933           5 :                 ret = dlz_addrdataset(domain, r.rdata, dbdata, version);
    1934           5 :                 torture_assert_int_equal_goto(
    1935             :                         tctx, ret, ISC_R_SUCCESS, ok,
    1936             :                         cancel_version,
    1937             :                         talloc_asprintf(tctx,
    1938             :                                         "Failed to add record %zu «%s»\n",
    1939             :                                         i, r.rdata));
    1940             : 
    1941           5 :                 dlz_closeversion(domain, true, dbdata, &version);
    1942             :         }
    1943             : 
    1944           1 :         print_node_records(tctx, samdb, node_dn, "add again");
    1945             : 
    1946             : 
    1947             :         /*
    1948             :          * Step 7. Check the timestamps are still now-ish.
    1949             :          *
    1950             :          */
    1951           1 :         ret = dsdb_search(samdb, tctx, &result, node_dn,
    1952             :                           LDB_SCOPE_SUBTREE, NULL,
    1953             :                           0, NULL);
    1954           1 :         if (ret != LDB_SUCCESS) {
    1955           0 :                 torture_fail(tctx,
    1956             :                              talloc_asprintf(
    1957             :                                      tctx,
    1958             :                                      "Failed to find %s node: %s",
    1959             :                                      name, ldb_errstring(samdb)));
    1960             :         }
    1961           1 :         torture_assert_int_equal(tctx, result->count, 1,
    1962             :                                  "Should be one node");
    1963             : 
    1964           1 :         el = ldb_msg_find_element(result->msgs[0], "dnsRecord");
    1965           1 :         torture_assert_not_null(tctx, el, "el");
    1966           1 :         torture_assert(tctx, dns_timestamp_before <= dns_timestamp_after, "<");
    1967           1 :         torture_assert_int_equal(tctx, el->num_values, testdata->num_records,
    1968             :                                  "num_values != num_records");
    1969             : 
    1970           6 :         for (i = 0; i < el->num_values; i++) {
    1971           0 :                 struct dnsp_DnssrvRpcRecord rec;
    1972           5 :                 ret = ndr_pull_struct_blob(
    1973           5 :                         &(el->values[i]),
    1974             :                         result,
    1975             :                         &rec,
    1976             :                         (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord);
    1977           5 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ret)) {
    1978           0 :                         DBG_ERR("Failed to pull dns rec blob [%zu].\n",
    1979             :                                 i);
    1980           0 :                         TALLOC_FREE(result);
    1981           0 :                         torture_fail(tctx, "Failed to pull dns rec blob");
    1982             :                 }
    1983           5 :                 torture_comment(tctx, "record[%zu]:\n", i);
    1984           5 :                 torture_comment(tctx, "type: %d\n", rec.wType);
    1985           5 :                 torture_comment(tctx, "timestamp: %u\n", rec.dwTimeStamp);
    1986           5 :                 torture_comment(tctx, "%s\n",
    1987             :                                 NDR_PRINT_STRUCT_STRING(result,
    1988             :                                                         dnsp_DnssrvRpcRecord,
    1989             :                                                         &rec));
    1990             : 
    1991           5 :                 torture_assert(tctx, rec.dwTimeStamp >= dns_timestamp_before,
    1992             :                                "timestamp < dns_timestamp_before");
    1993           5 :                 torture_assert(tctx, rec.dwTimeStamp <= dns_timestamp_after,
    1994             :                                "timestamp > dns_timestamp_after");
    1995             :         }
    1996             : 
    1997           1 :         talloc_free(result);
    1998             : 
    1999             :         /*
    2000             :          * Step 8. Wind back the timestamps in the database.
    2001             :          *
    2002             :          * We use a different number of days for each record, so that some
    2003             :          * should be refreshed, and some shouldn't.
    2004             :          */
    2005           1 :         torture_comment(tctx, "step 8: alter timestamps\n");
    2006           1 :         ret = dsdb_search_one(samdb, tctx, &msg, node_dn,
    2007             :                               LDB_SCOPE_BASE, attrs,
    2008             :                               0, NULL);
    2009           1 :         if (ret != LDB_SUCCESS) {
    2010           0 :                 torture_fail(tctx,
    2011             :                              talloc_asprintf(
    2012             :                                      tctx,
    2013             :                                      "Failed to find %s node: %s",
    2014             :                                      name, ldb_errstring(samdb)));
    2015             :         }
    2016             : 
    2017           1 :         el = ldb_msg_find_element(msg, "dnsRecord");
    2018           1 :         torture_assert_not_null(tctx, el, "el");
    2019           1 :         torture_assert_int_equal(tctx, el->num_values,
    2020             :                                  testdata->num_records,
    2021             :                                  "num_values != num_records");
    2022             : 
    2023           6 :         for (i = 0; i < el->num_values; i++) {
    2024           0 :                 struct dnsp_DnssrvRpcRecord rec;
    2025           5 :                 ret = ndr_pull_struct_blob(
    2026           5 :                         &(el->values[i]),
    2027             :                         msg,
    2028             :                         &rec,
    2029             :                         (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord);
    2030           5 :                 torture_assert_ndr_success(tctx, ret, "failed to pull record");
    2031             : 
    2032           5 :                 rec.dwTimeStamp = dns_timestamp_after + 3 - 24 * (i + 5);
    2033             : 
    2034           5 :                 ret = ndr_push_struct_blob(
    2035           5 :                         &el->values[i],
    2036             :                         msg,
    2037             :                         &rec,
    2038             :                         (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord);
    2039           5 :                 torture_assert_ndr_success(tctx, ret, "failed to PUSH record");
    2040             :         }
    2041           1 :         el->flags = LDB_FLAG_MOD_REPLACE;
    2042             : 
    2043           1 :         ret = ldb_modify(samdb, msg);
    2044           1 :         torture_assert_int_equal(tctx, ret, 0, "failed to ldb_modify");
    2045           1 :         print_node_records(tctx, samdb, node_dn, "after ldb_modify");
    2046             : 
    2047             : 
    2048             :         /*
    2049             :          * Step 9. Do another update, changing some timestamps
    2050             :          */
    2051             : 
    2052           6 :         for (i = 0; i < testdata->num_records; i++) {
    2053           5 :                 struct test_expected_record r = testdata->records[i];
    2054             : 
    2055           5 :                 ret = dlz_newversion(domain, dbdata, &version);
    2056           5 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    2057             :                                          "Failed to start transaction");
    2058             : 
    2059           5 :                 ret = dlz_addrdataset(name, r.rdata, dbdata, version);
    2060           5 :                 dlz_closeversion(domain, ret == ISC_R_SUCCESS, dbdata,
    2061             :                                  &version);
    2062           5 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    2063             :                                          "Failed to update record\n");
    2064             :         }
    2065           1 :         print_node_records(tctx, samdb, node_dn, "after update");
    2066             : 
    2067             :         /*
    2068             :          * Step 10. Check that the timestamps are right.
    2069             :          *
    2070             :          * The formula was
    2071             :          *    (i + 5) days + 3 hours
    2072             :          * so 1 is 6 days + 3 hours, and should not be renewed.
    2073             :          *    2 is 7 days + 3 hours, and should be renewed
    2074             :          *
    2075             :          * NOTE: the ldb record order is different from the insertion order,
    2076             :          * but it should stay the same between searches.
    2077             :          */
    2078           1 :         ret = dsdb_search_one(samdb, tctx, &msg, node_dn,
    2079             :                               LDB_SCOPE_BASE, attrs,
    2080             :                               0, NULL);
    2081           1 :         if (ret != LDB_SUCCESS) {
    2082           0 :                 torture_fail(tctx,
    2083             :                              talloc_asprintf(
    2084             :                                      tctx,
    2085             :                                      "Failed to find %s node: %s",
    2086             :                                      name, ldb_errstring(samdb)));
    2087             :         }
    2088             : 
    2089           1 :         el = ldb_msg_find_element(msg, "dnsRecord");
    2090           1 :         torture_assert_not_null(tctx, el, "el");
    2091           1 :         torture_assert_int_equal(tctx, el->num_values,
    2092             :                                  testdata->num_records,
    2093             :                                  "num_values != num_records");
    2094             : 
    2095           6 :         for (i = 0; i < el->num_values; i++) {
    2096           0 :                 struct dnsp_DnssrvRpcRecord rec;
    2097           5 :                 ret = ndr_pull_struct_blob(
    2098           5 :                         &(el->values[i]),
    2099             :                         msg,
    2100             :                         &rec,
    2101             :                         (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord);
    2102           5 :                 torture_assert_ndr_success(tctx, ret, "failed to pull record");
    2103           5 :                 if (i < 3) {
    2104             :                         /* records 0 and 1 should not have been renewed */
    2105           3 :                         int old_ts = dns_timestamp_after + 3 - 24 * (i + 5);
    2106           3 :                         torture_assertf(
    2107             :                                 tctx,
    2108             :                                 rec.dwTimeStamp == old_ts,
    2109             :                                 "record[%zu] timestamp should not be altered."
    2110             :                                 " diff is %d\n",
    2111             :                                 i, rec.dwTimeStamp - old_ts);
    2112             :                 } else {
    2113             :                         /* records 3+ should have a now-ish timestamp */
    2114           2 :                         int old_ts = dns_timestamp_after + 3 - 24 * (i + 5);
    2115           2 :                         torture_assertf(
    2116             :                                 tctx,
    2117             :                                 rec.dwTimeStamp >= dns_timestamp_before,
    2118             :                                 "record[%zu] should have altered timestamp "
    2119             :                                 "now ~= %d, then ~= %d, has %d, diff %d\n", i,
    2120             :                                 dns_timestamp_before, old_ts, rec.dwTimeStamp,
    2121             :                                 dns_timestamp_before - rec.dwTimeStamp
    2122             :                                 );
    2123             :                 }
    2124             :         }
    2125             : 
    2126             :         /*
    2127             :          * Step 11. Set one record to be static.
    2128             :          *
    2129             :          * This should make the node static, but it won't "know" that until we
    2130             :          * force it with an update.
    2131             :          */
    2132           1 :         torture_comment(tctx, "step 11: alter one timestamp to be 0\n");
    2133           1 :         ret = dsdb_search_one(samdb, tctx, &msg, node_dn,
    2134             :                               LDB_SCOPE_BASE, attrs,
    2135             :                               0, NULL);
    2136           1 :         if (ret != LDB_SUCCESS) {
    2137           0 :                 torture_fail(tctx,
    2138             :                              talloc_asprintf(
    2139             :                                      tctx,
    2140             :                                      "Failed to find %s node: %s",
    2141             :                                      name, ldb_errstring(samdb)));
    2142             :         }
    2143             : 
    2144           1 :         el = ldb_msg_find_element(msg, "dnsRecord");
    2145           1 :         torture_assert_not_null(tctx, el, "el");
    2146           1 :         torture_assert_int_equal(tctx, el->num_values,
    2147             :                                  testdata->num_records,
    2148             :                                  "num_values != num_records");
    2149             : 
    2150             :         {
    2151             :                 /* we're arbitrarily picking on record 3 */
    2152           0 :                 struct dnsp_DnssrvRpcRecord rec;
    2153           1 :                 ret = ndr_pull_struct_blob(
    2154           1 :                         &(el->values[3]),
    2155             :                         msg,
    2156             :                         &rec,
    2157             :                         (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord);
    2158           1 :                 torture_assert_ndr_success(tctx, ret, "failed to pull record");
    2159             : 
    2160           1 :                 rec.dwTimeStamp = 0;
    2161             : 
    2162           1 :                 ret = ndr_push_struct_blob(
    2163           1 :                         &el->values[3],
    2164             :                         msg,
    2165             :                         &rec,
    2166             :                         (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord);
    2167           1 :                 torture_assert_ndr_success(tctx, ret, "failed to PUSH record");
    2168             :         }
    2169           1 :         el->flags = LDB_FLAG_MOD_REPLACE;
    2170             : 
    2171           1 :         ret = ldb_modify(samdb, msg);
    2172           1 :         torture_assert_int_equal(tctx, ret, 0, "failed to ldb_modify");
    2173           1 :         print_node_records(tctx, samdb, node_dn, "after ldb_modify");
    2174             : 
    2175             : 
    2176             :         /*
    2177             :          * Step 12. Do updates on some records, zeroing their timestamps
    2178             :          *
    2179             :          * Zero means static. A single zero timestamp is infectious, so other
    2180             :          * records get it when they are updated.
    2181             :          */
    2182             : 
    2183           4 :         for (i = 0; i < testdata->num_records - 2; i++) {
    2184           3 :                 struct test_expected_record r = testdata->records[i];
    2185             : 
    2186           3 :                 ret = dlz_newversion(domain, dbdata, &version);
    2187           3 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    2188             :                                          "Failed to start transaction");
    2189             : 
    2190           3 :                 ret = dlz_addrdataset(name, r.rdata, dbdata, version);
    2191           3 :                 dlz_closeversion(domain, ret == ISC_R_SUCCESS, dbdata,
    2192             :                                  &version);
    2193           3 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    2194             :                                          "Failed to update record\n");
    2195             :         }
    2196           1 :         print_node_records(tctx, samdb, node_dn, "after update to static");
    2197             : 
    2198             : 
    2199             :         /*
    2200             :          * Step 13. Check that the record timeouts are *mostly* zero.
    2201             :          *
    2202             :          * one or two will be non-zero: we updated all but two, but one of
    2203             :          * excluded ones might be the el->records[3] that we explicitly set to
    2204             :          * zero.
    2205             :          */
    2206           1 :         ret = dsdb_search_one(samdb, tctx, &msg, node_dn,
    2207             :                               LDB_SCOPE_BASE, attrs,
    2208             :                               0, NULL);
    2209           1 :         if (ret != LDB_SUCCESS) {
    2210           0 :                 torture_fail(tctx,
    2211             :                              talloc_asprintf(
    2212             :                                      tctx,
    2213             :                                      "Failed to find %s node: %s",
    2214             :                                      name, ldb_errstring(samdb)));
    2215             :         }
    2216             : 
    2217           1 :         el = ldb_msg_find_element(msg, "dnsRecord");
    2218             :         {
    2219           1 :                 unsigned n_zero = 0;
    2220           6 :                 for (i = 0; i < el->num_values; i++) {
    2221           0 :                         struct dnsp_DnssrvRpcRecord rec;
    2222           5 :                         ret = ndr_pull_struct_blob(
    2223           5 :                                 &(el->values[i]),
    2224             :                                 msg,
    2225             :                                 &rec,
    2226             :                                 (ndr_pull_flags_fn_t)\
    2227             :                                 ndr_pull_dnsp_DnssrvRpcRecord);
    2228           5 :                         torture_assert_ndr_success(tctx, ret,
    2229             :                                                    "failed to pull record");
    2230           5 :                         if (rec.dwTimeStamp == 0) {
    2231           3 :                                 n_zero++;
    2232             :                         }
    2233             :                 }
    2234           1 :                 if (n_zero != el->num_values - 1 &&
    2235           1 :                     n_zero != el->num_values - 2) {
    2236           0 :                         torture_comment(tctx, "got %u zeros, expected %u or %u",
    2237             :                                         n_zero,
    2238           0 :                                         el->num_values - 2,
    2239           0 :                                         el->num_values - 1);
    2240           0 :                         torture_fail(tctx,
    2241             :                                      "static node not setting zero timestamps\n");
    2242             : 
    2243             :                 }
    2244             :         }
    2245             : 
    2246             : 
    2247             :         /*
    2248             :          * Step 14. Turn aging off.
    2249             :          */
    2250           1 :         torture_comment(tctx, "step 14: turn aging off\n");
    2251           1 :         ok = set_zone_aging(tctx, domain, 0);
    2252           1 :         torture_assert(tctx, ok, "failed to disable aging");
    2253           1 :         print_node_records(tctx, samdb, node_dn, "aging off");
    2254             : 
    2255             :         /*
    2256             :          * Step 15. Update, setting timestamps to zero.
    2257             :          *
    2258             :          * Even with aging off, timestamps are still changed to static.
    2259             :          */
    2260           6 :         for (i = 0; i < testdata->num_records; i++) {
    2261           5 :                 struct test_expected_record r = testdata->records[i];
    2262             : 
    2263           5 :                 ret = dlz_newversion(domain, dbdata, &version);
    2264           5 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    2265             :                                          "Failed to start transaction");
    2266             : 
    2267           5 :                 ret = dlz_addrdataset(name, r.rdata, dbdata, version);
    2268           5 :                 dlz_closeversion(domain, ret == ISC_R_SUCCESS, dbdata,
    2269             :                                  &version);
    2270           5 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    2271             :                                          "Failed to update record\n");
    2272             :         }
    2273           1 :         print_node_records(tctx, samdb, node_dn, "after update with aging off");
    2274             : 
    2275             : 
    2276             :         /*
    2277             :          * Step 16. Check that the timestamps are all zero.
    2278             :          */
    2279           1 :         ret = dsdb_search_one(samdb, tctx, &msg, node_dn,
    2280             :                               LDB_SCOPE_BASE, attrs,
    2281             :                               0, NULL);
    2282           1 :         if (ret != LDB_SUCCESS) {
    2283           0 :                 torture_fail(tctx,
    2284             :                              talloc_asprintf(
    2285             :                                      tctx,
    2286             :                                      "Failed to find %s node: %s",
    2287             :                                      name, ldb_errstring(samdb)));
    2288             :         }
    2289             : 
    2290           1 :         el = ldb_msg_find_element(msg, "dnsRecord");
    2291           6 :         for (i = 0; i < el->num_values; i++) {
    2292           0 :                 struct dnsp_DnssrvRpcRecord rec;
    2293           5 :                 ret = ndr_pull_struct_blob(
    2294           5 :                         &(el->values[i]),
    2295             :                         msg,
    2296             :                         &rec,
    2297             :                         (ndr_pull_flags_fn_t) ndr_pull_dnsp_DnssrvRpcRecord);
    2298           5 :                 torture_assert_ndr_success(tctx, ret,
    2299             :                                            "failed to pull record");
    2300           5 :                 torture_assertf(tctx, rec.dwTimeStamp == 0,
    2301             :                                 "record[%zu].dwTimeStamp is %u, expected 0\n",
    2302             :                                 i, rec.dwTimeStamp);
    2303             : 
    2304             :         }
    2305             : 
    2306             : 
    2307             :         /*
    2308             :          * Step 17. Reset to non-zero via ldb, with aging still off.
    2309             :          *
    2310             :          * We chose timestamps in the distant past that would all be updated
    2311             :          * if aging was on.
    2312             :          */
    2313           1 :         torture_comment(tctx, "step 17: reset to non-zero timestamps\n");
    2314           1 :         ret = dsdb_search_one(samdb, tctx, &msg, node_dn,
    2315             :                               LDB_SCOPE_BASE, attrs,
    2316             :                               0, NULL);
    2317           1 :         if (ret != LDB_SUCCESS) {
    2318           0 :                 torture_fail(tctx,
    2319             :                              talloc_asprintf(
    2320             :                                      tctx,
    2321             :                                      "Failed to find %s node: %s",
    2322             :                                      name, ldb_errstring(samdb)));
    2323             :         }
    2324             : 
    2325           1 :         el = ldb_msg_find_element(msg, "dnsRecord");
    2326             : 
    2327           6 :         for (i = 0; i < el->num_values; i++) {
    2328           0 :                 struct dnsp_DnssrvRpcRecord rec;
    2329           5 :                 ret = ndr_pull_struct_blob(
    2330           5 :                         &(el->values[i]),
    2331             :                         msg,
    2332             :                         &rec,
    2333             :                         (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord);
    2334           5 :                 torture_assert_ndr_success(tctx, ret, "failed to pull record");
    2335             : 
    2336           5 :                 rec.dwTimeStamp = 10000 + i; /* a long time ago */
    2337             : 
    2338           5 :                 ret = ndr_push_struct_blob(
    2339           5 :                         &el->values[i],
    2340             :                         msg,
    2341             :                         &rec,
    2342             :                         (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord);
    2343           5 :                 torture_assert_ndr_success(tctx, ret, "failed to PUSH record");
    2344             :         }
    2345           1 :         el->flags = LDB_FLAG_MOD_REPLACE;
    2346             : 
    2347           1 :         ret = ldb_modify(samdb, msg);
    2348           1 :         torture_assert_int_equal(tctx, ret, 0, "failed to ldb_modify");
    2349           1 :         print_node_records(tctx, samdb, node_dn, "timestamps no-zero, aging off");
    2350             : 
    2351             : 
    2352             :         /*
    2353             :          * Step 18. Update with aging off. Nothing should change.
    2354             :          *
    2355             :          */
    2356             : 
    2357             :         /* now, with another update, some will be updated and some won't */
    2358           6 :         for (i = 0; i < testdata->num_records; i++) {
    2359           5 :                 struct test_expected_record r = testdata->records[i];
    2360             : 
    2361           5 :                 ret = dlz_newversion(domain, dbdata, &version);
    2362           5 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    2363             :                                          "Failed to start transaction");
    2364             : 
    2365           5 :                 ret = dlz_addrdataset(name, r.rdata, dbdata, version);
    2366           5 :                 dlz_closeversion(domain, ret == ISC_R_SUCCESS, dbdata,
    2367             :                                  &version);
    2368           5 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    2369             :                                          "Failed to update record\n");
    2370             :         }
    2371           1 :         print_node_records(tctx, samdb, node_dn, "after update");
    2372             : 
    2373             : 
    2374             :         /*
    2375             :          * Step 19. Check that the timestamps didn't change.
    2376             :          */
    2377           1 :         el = ldb_msg_find_element(msg, "dnsRecord");
    2378           1 :         torture_assert_not_null(tctx, el, "el");
    2379           1 :         torture_assert_int_equal(tctx, el->num_values,
    2380             :                                  testdata->num_records,
    2381             :                                  "num_values != num_records");
    2382             : 
    2383           6 :         for (i = 0; i < el->num_values; i++) {
    2384           0 :                 struct dnsp_DnssrvRpcRecord rec;
    2385           5 :                 ret = ndr_pull_struct_blob(
    2386           5 :                         &(el->values[i]),
    2387             :                         msg,
    2388             :                         &rec,
    2389             :                         (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord);
    2390           5 :                 torture_assert_ndr_success(tctx, ret, "failed to pull record");
    2391           5 :                 torture_assertf(
    2392             :                         tctx,
    2393             :                         rec.dwTimeStamp == 10000 + i,
    2394             :                         "record[%zu] timestamp should not be altered.\n",
    2395             :                         i);
    2396             :         }
    2397             : 
    2398             : 
    2399             :         /*
    2400             :          * Step 20. Delete all the records, 1 by 1.
    2401             :          *
    2402             :          */
    2403           1 :         torture_comment(tctx, "step 20: delete the records\n");
    2404             : 
    2405           6 :         for (i = 0; i < testdata->num_records; i++) {
    2406           5 :                 struct test_expected_record r = testdata->records[i];
    2407             : 
    2408           5 :                 ret = dlz_newversion(domain, dbdata, &version);
    2409           5 :                 torture_assert_int_equal(tctx, ret, ISC_R_SUCCESS,
    2410             :                                          "Failed to start transaction");
    2411             : 
    2412           5 :                 ret = dlz_subrdataset(name, r.rdata, dbdata, version);
    2413           5 :                 torture_assert_int_equal_goto(
    2414             :                         tctx, ret, ISC_R_SUCCESS, ok,
    2415             :                         cancel_version,
    2416             :                         talloc_asprintf(tctx,
    2417             :                                         "Failed to delete record %zu «%s»\n",
    2418             :                                         i, r.rdata));
    2419             : 
    2420           5 :                 dlz_closeversion(domain, true, dbdata, &version);
    2421             : 
    2422           5 :                 testdata->num_rr = 0;
    2423             : 
    2424           5 :                 ret = dlz_lookup(domain, testdata->query_name, dbdata,
    2425             :                                  (dns_sdlzlookup_t *)testdata, NULL, NULL);
    2426             : 
    2427           5 :                 if (i ==  testdata->num_records - 1) {
    2428           1 :                         torture_assert_int_equal(tctx, ret,
    2429             :                                                  ISC_R_NOTFOUND,
    2430             :                                                  "no records should exist");
    2431             :                 } else {
    2432           4 :                         torture_assert_int_equal(tctx, ret,
    2433             :                                                  ISC_R_SUCCESS,
    2434             :                                                  "records not found");
    2435             :                 }
    2436             : 
    2437           5 :                 torture_assert_int_equal(tctx,
    2438             :                                          testdata->num_rr,
    2439             :                                          testdata->num_records - 1 - i,
    2440             :                                          "Got wrong record count");
    2441             : 
    2442          30 :                 for (j = 0; j < testdata->num_records; j++) {
    2443          25 :                         struct test_expected_record *r2 = &testdata->records[j];
    2444          25 :                         if (j > i) {
    2445          10 :                                 torture_assert(
    2446             :                                         tctx,
    2447             :                                         r2->printed,
    2448             :                                         talloc_asprintf(tctx,
    2449             :                                             "putrr callback not run on %s «%s»",
    2450             :                                                         r2->type, r2->name));
    2451             :                         } else {
    2452          15 :                                 torture_assert(
    2453             :                                         tctx,
    2454             :                                         ! r2->printed,
    2455             :                                         talloc_asprintf(tctx,
    2456             :                                             "putrr callback should not see  %s «%s»",
    2457             :                                                         r2->type, r2->name));
    2458             :                         }
    2459          25 :                         r2->printed = false;
    2460             :                 }
    2461             :         }
    2462             : 
    2463           1 :         dlz_destroy(dbdata);
    2464             : 
    2465           1 :         return true;
    2466             : 
    2467           0 : cancel_version:
    2468           0 :         DBG_ERR("exiting with %d\n", ret);
    2469           0 :         dlz_closeversion(domain, false, dbdata, &version);
    2470           0 :         return ret;
    2471             : }
    2472             : 
    2473             : 
    2474        1515 : static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx)
    2475             : {
    2476        1515 :         struct torture_suite *suite = torture_suite_create(ctx, "dlz_bind9");
    2477             : 
    2478        1515 :         suite->description = talloc_strdup(suite,
    2479             :                                            "Tests for the BIND 9 DLZ module");
    2480        1515 :         torture_suite_add_simple_test(suite, "version", test_dlz_bind9_version);
    2481        1515 :         torture_suite_add_simple_test(suite, "create", test_dlz_bind9_create);
    2482        1515 :         torture_suite_add_simple_test(suite, "configure", test_dlz_bind9_configure);
    2483        1515 :         torture_suite_add_simple_test(suite, "destroyoldestfirst",
    2484             :                                       test_dlz_bind9_destroy_oldest_first);
    2485        1515 :         torture_suite_add_simple_test(suite, "destroynewestfirst",
    2486             :                                       test_dlz_bind9_destroy_newest_first);
    2487        1515 :         torture_suite_add_simple_test(suite, "multipleconfigure",
    2488             :                                       test_dlz_bind9_multiple_configure);
    2489             : 
    2490        1515 :         torture_suite_add_simple_test(suite, "gssapi", test_dlz_bind9_gssapi);
    2491        1515 :         torture_suite_add_simple_test(suite, "spnego", test_dlz_bind9_spnego);
    2492        1515 :         torture_suite_add_simple_test(suite, "lookup", test_dlz_bind9_lookup);
    2493        1515 :         torture_suite_add_simple_test(suite, "zonedump", test_dlz_bind9_zonedump);
    2494        1515 :         torture_suite_add_simple_test(suite, "update01", test_dlz_bind9_update01);
    2495        1515 :         torture_suite_add_simple_test(suite, "aging", test_dlz_bind9_aging);
    2496        1515 :         torture_suite_add_simple_test(suite, "allowzonexfr", test_dlz_bind9_allowzonexfr);
    2497        1515 :         return suite;
    2498             : }
    2499             : 
    2500             : /**
    2501             :  * DNS torture module initialization
    2502             :  */
    2503             : NTSTATUS torture_bind_dns_init(TALLOC_CTX *);
    2504        1515 : NTSTATUS torture_bind_dns_init(TALLOC_CTX *ctx)
    2505             : {
    2506         125 :         struct torture_suite *suite;
    2507             : 
    2508             :         /* register DNS related test cases */
    2509        1515 :         suite = dlz_bind9_suite(ctx);
    2510        1515 :         if (!suite) return NT_STATUS_NO_MEMORY;
    2511        1515 :         torture_register_suite(ctx, suite);
    2512             : 
    2513        1515 :         return NT_STATUS_OK;
    2514             : }

Generated by: LCOV version 1.14