f16d16ec06134054d227cc85ddf2e02725829c75
[gd/samba-autobuild/.git] / source4 / torture / dns / dlz_bind9.c
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 "dlz_minimal.h"
23 #include <talloc.h>
24 #include <ldb.h>
25 #include "lib/param/param.h"
26 #include "dsdb/samdb/samdb.h"
27 #include "dsdb/common/util.h"
28 #include "auth/session.h"
29 #include "auth/gensec/gensec.h"
30 #include "auth/credentials/credentials.h"
31 #include "lib/cmdline/popt_common.h"
32
33 struct torture_context *tctx_static;
34
35 static void dlz_bind9_log_wrapper(int level, const char *fmt, ...)
36                                   PRINTF_ATTRIBUTE(2,3);
37
38 static void dlz_bind9_log_wrapper(int level, const char *fmt, ...)
39 {
40         va_list ap;
41         char *msg;
42         va_start(ap, fmt);
43         msg = talloc_vasprintf(NULL, fmt, ap);
44         torture_comment(tctx_static, "%s\n", msg);
45         TALLOC_FREE(msg);
46         va_end(ap);
47 }
48
49 static bool test_dlz_bind9_version(struct torture_context *tctx)
50 {
51         unsigned int flags = 0;
52         torture_assert_int_equal(tctx, dlz_version(&flags),
53                                  DLZ_DLOPEN_VERSION, "got wrong DLZ version");
54         return true;
55 }
56
57 static bool test_dlz_bind9_create(struct torture_context *tctx)
58 {
59         void *dbdata;
60         const char *argv[] = {
61                 "samba_dlz",
62                 "-H",
63                 lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
64                 NULL
65         };
66         tctx_static = tctx;
67         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
68                                                   "log", dlz_bind9_log_wrapper, NULL), ISC_R_SUCCESS,
69                 "Failed to create samba_dlz");
70
71         dlz_destroy(dbdata);
72
73         return true;
74 }
75
76 static isc_result_t dlz_bind9_writeable_zone_hook(dns_view_t *view,
77                                            const char *zone_name)
78 {
79         struct torture_context *tctx = talloc_get_type((void *)view, struct torture_context);
80         struct ldb_context *samdb = samdb_connect_url(tctx, NULL, tctx->lp_ctx,
81                                                       system_session(tctx->lp_ctx),
82                                                       0, lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"));
83         struct ldb_message *msg;
84         int ret;
85         const char *attrs[] = {
86                 NULL
87         };
88         if (!samdb) {
89                 torture_fail(tctx, "Failed to connect to samdb");
90                 return ISC_R_FAILURE;
91         }
92
93         ret = dsdb_search_one(samdb, tctx, &msg, NULL,
94                               LDB_SCOPE_SUBTREE, attrs, DSDB_SEARCH_SEARCH_ALL_PARTITIONS,
95                               "(&(objectClass=dnsZone)(name=%s))", zone_name);
96         if (ret != LDB_SUCCESS) {
97                 torture_fail(tctx, talloc_asprintf(tctx, "Failed to search for %s: %s", zone_name, ldb_errstring(samdb)));
98                 return ISC_R_FAILURE;
99         }
100         talloc_free(msg);
101
102         return ISC_R_SUCCESS;
103 }
104
105 static bool test_dlz_bind9_configure(struct torture_context *tctx)
106 {
107         void *dbdata;
108         const char *argv[] = {
109                 "samba_dlz",
110                 "-H",
111                 lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
112                 NULL
113         };
114         tctx_static = tctx;
115         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
116                                                   "log", dlz_bind9_log_wrapper,
117                                                   "writeable_zone", dlz_bind9_writeable_zone_hook, NULL),
118                                  ISC_R_SUCCESS,
119                                  "Failed to create samba_dlz");
120
121         torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata),
122                                                      ISC_R_SUCCESS,
123                                  "Failed to configure samba_dlz");
124
125         dlz_destroy(dbdata);
126
127         return true;
128 }
129
130 /*
131  * Test that a ticket obtained for the DNS service will be accepted on the Samba DLZ side
132  *
133  */
134 static bool test_dlz_bind9_gensec(struct torture_context *tctx, const char *mech)
135 {
136         NTSTATUS status;
137
138         struct gensec_security *gensec_client_context;
139
140         DATA_BLOB client_to_server, server_to_client;
141
142         void *dbdata;
143         const char *argv[] = {
144                 "samba_dlz",
145                 "-H",
146                 lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
147                 NULL
148         };
149         tctx_static = tctx;
150         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
151                                                   "log", dlz_bind9_log_wrapper,
152                                                   "writeable_zone", dlz_bind9_writeable_zone_hook, NULL),
153                                  ISC_R_SUCCESS,
154                                  "Failed to create samba_dlz");
155
156         torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata),
157                                                      ISC_R_SUCCESS,
158                                  "Failed to configure samba_dlz");
159
160         status = gensec_client_start(tctx, &gensec_client_context,
161                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx));
162         torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");
163
164         /*
165          * dlz_bind9 use the special dns/host.domain account
166          */
167         status = gensec_set_target_hostname(gensec_client_context,
168                                             talloc_asprintf(tctx,
169                                 "%s.%s",
170                                 torture_setting_string(tctx, "host", NULL),
171                                 lpcfg_dnsdomain(tctx->lp_ctx)));
172         torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed");
173
174         status = gensec_set_target_service(gensec_client_context, "dns");
175         torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_service failed");
176
177         status = gensec_set_credentials(gensec_client_context, cmdline_credentials);
178         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");
179
180         status = gensec_start_mech_by_sasl_name(gensec_client_context, mech);
181         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");
182
183         server_to_client = data_blob(NULL, 0);
184
185         /* Do one step of the client-server update dance */
186         status = gensec_update(gensec_client_context, tctx, server_to_client, &client_to_server);
187         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
188                 torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
189         }
190
191         torture_assert_int_equal(tctx, dlz_ssumatch(cli_credentials_get_username(cmdline_credentials),
192                                                     lpcfg_dnsdomain(tctx->lp_ctx),
193                                                     "127.0.0.1", "type", "key",
194                                                     client_to_server.length,
195                                                     client_to_server.data,
196                                                     dbdata),
197                                  ISC_TRUE,
198                                  "Failed to check key for update rights samba_dlz");
199
200         dlz_destroy(dbdata);
201
202         return true;
203 }
204
205 static bool test_dlz_bind9_gssapi(struct torture_context *tctx)
206 {
207         return test_dlz_bind9_gensec(tctx, "GSSAPI");
208 }
209
210 static bool test_dlz_bind9_spnego(struct torture_context *tctx)
211 {
212         return test_dlz_bind9_gensec(tctx, "GSS-SPNEGO");
213 }
214
215 struct test_expected_record {
216         const char *name;
217         const char *type;
218         const char *data;
219         int ttl;
220         bool printed;
221 };
222
223 struct test_expected_rr {
224         struct torture_context *tctx;
225         const char *query_name;
226         size_t num_records;
227         struct test_expected_record *records;
228         size_t num_rr;
229 };
230
231 static bool dlz_bind9_putnamedrr_torture_hook(struct test_expected_rr *expected,
232                                               const char *name,
233                                               const char *type,
234                                               dns_ttl_t ttl,
235                                               const char *data)
236 {
237         size_t i;
238
239         torture_assert(expected->tctx, name != NULL,
240                        talloc_asprintf(expected->tctx,
241                        "Got unnamed record type[%s] data[%s]\n",
242                        type, data));
243
244         expected->num_rr++;
245         torture_comment(expected->tctx, "%u: name[%s] type[%s] ttl[%u] data[%s]\n",
246                         (unsigned)expected->num_rr, name, type, (unsigned)ttl, data);
247
248         for (i = 0; i < expected->num_records; i++) {
249                 if (expected->records[i].name != NULL) {
250                         if (strcmp(name, expected->records[i].name) != 0) {
251                                 continue;
252                         }
253                 }
254
255                 if (strcmp(type, expected->records[i].type) != 0) {
256                         continue;
257                 }
258
259                 if (expected->records[i].data != NULL) {
260                         if (strcmp(data, expected->records[i].data) != 0) {
261                                 continue;
262                         }
263                 }
264
265                 torture_assert_int_equal(expected->tctx, ttl,
266                                          expected->records[i].ttl,
267                                          talloc_asprintf(expected->tctx,
268                                          "TTL did not match expectations for type %s",
269                                          type));
270
271                 expected->records[i].printed = true;
272         }
273
274         return true;
275 }
276
277 static isc_result_t dlz_bind9_putrr_hook(dns_sdlzlookup_t *lookup,
278                                          const char *type,
279                                          dns_ttl_t ttl,
280                                          const char *data)
281 {
282         struct test_expected_rr *expected =
283                 talloc_get_type_abort(lookup, struct test_expected_rr);
284         bool ok;
285
286         ok = dlz_bind9_putnamedrr_torture_hook(expected, expected->query_name,
287                                                type, ttl, data);
288         if (!ok) {
289                 return ISC_R_FAILURE;
290         }
291
292         return ISC_R_SUCCESS;
293 }
294
295 static isc_result_t dlz_bind9_putnamedrr_hook(dns_sdlzallnodes_t *allnodes,
296                                               const char *name,
297                                               const char *type,
298                                               dns_ttl_t ttl,
299                                               const char *data)
300 {
301         struct test_expected_rr *expected =
302                 talloc_get_type_abort(allnodes, struct test_expected_rr);
303         bool ok;
304
305         ok = dlz_bind9_putnamedrr_torture_hook(expected, name, type, ttl, data);
306         if (!ok) {
307                 return ISC_R_FAILURE;
308         }
309
310         return ISC_R_SUCCESS;
311 }
312
313 /*
314  * Tests some lookups
315  */
316 static bool test_dlz_bind9_lookup(struct torture_context *tctx)
317 {
318         size_t i;
319         void *dbdata;
320         const char *argv[] = {
321                 "samba_dlz",
322                 "-H",
323                 lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
324                 NULL
325         };
326         struct test_expected_rr *expected1 = NULL;
327         struct test_expected_rr *expected2 = NULL;
328
329         tctx_static = tctx;
330         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
331                                                   "log", dlz_bind9_log_wrapper,
332                                                   "writeable_zone", dlz_bind9_writeable_zone_hook,
333                                                   "putrr", dlz_bind9_putrr_hook,
334                                                   "putnamedrr", dlz_bind9_putnamedrr_hook,
335                                                   NULL),
336                                  ISC_R_SUCCESS,
337                                  "Failed to create samba_dlz");
338
339         torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata),
340                                                      ISC_R_SUCCESS,
341                                  "Failed to configure samba_dlz");
342
343         expected1 = talloc_zero(tctx, struct test_expected_rr);
344         torture_assert(tctx, expected1 != NULL, "talloc failed");
345         expected1->tctx = tctx;
346
347         expected1->query_name = "@";
348
349         expected1->num_records = 4;
350         expected1->records = talloc_zero_array(expected1,
351                                                struct test_expected_record,
352                                                expected1->num_records);
353         torture_assert(tctx, expected1->records != NULL, "talloc failed");
354
355         expected1->records[0].name = expected1->query_name;
356         expected1->records[0].type = "soa";
357         expected1->records[0].ttl = 3600;
358         expected1->records[0].data = talloc_asprintf(expected1->records,
359                                 "%s.%s. hostmaster.%s. 1 900 600 86400 3600",
360                                 torture_setting_string(tctx, "host", NULL),
361                                 lpcfg_dnsdomain(tctx->lp_ctx),
362                                 lpcfg_dnsdomain(tctx->lp_ctx));
363         torture_assert(tctx, expected1->records[0].data != NULL, "talloc failed");
364
365         expected1->records[1].name = expected1->query_name;
366         expected1->records[1].type = "ns";
367         expected1->records[1].ttl = 900;
368         expected1->records[1].data = talloc_asprintf(expected1->records, "%s.%s.",
369                                 torture_setting_string(tctx, "host", NULL),
370                                 lpcfg_dnsdomain(tctx->lp_ctx));
371         torture_assert(tctx, expected1->records[1].data != NULL, "talloc failed");
372
373         expected1->records[2].name = expected1->query_name;
374         expected1->records[2].type = "aaaa";
375         expected1->records[2].ttl = 900;
376
377         expected1->records[3].name = expected1->query_name;
378         expected1->records[3].type = "a";
379         expected1->records[3].ttl = 900;
380
381         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
382                                                   expected1->query_name, dbdata,
383                                                   (dns_sdlzlookup_t *)expected1),
384                                  ISC_R_SUCCESS,
385                                  "Failed to lookup @");
386         for (i = 0; i < expected1->num_records; i++) {
387                 torture_assert(tctx, expected1->records[i].printed,
388                                talloc_asprintf(tctx,
389                                "Failed to have putrr callback run for type %s",
390                                expected1->records[i].type));
391         }
392         torture_assert_int_equal(tctx, expected1->num_rr,
393                                  expected1->num_records,
394                                  "Got too much data");
395
396         expected2 = talloc_zero(tctx, struct test_expected_rr);
397         torture_assert(tctx, expected2 != NULL, "talloc failed");
398         expected2->tctx = tctx;
399
400         expected2->query_name = torture_setting_string(tctx, "host", NULL);
401         torture_assert(tctx, expected2->query_name != NULL, "unknown host");
402
403         expected2->num_records = 2;
404         expected2->records = talloc_zero_array(expected2,
405                                                struct test_expected_record,
406                                                expected2->num_records);
407         torture_assert(tctx, expected2->records != NULL, "talloc failed");
408
409         expected2->records[0].name = expected2->query_name;
410         expected2->records[0].type = "aaaa";
411         expected2->records[0].ttl = 900;
412
413         expected2->records[1].name = expected2->query_name;
414         expected2->records[1].type = "a";
415         expected2->records[1].ttl = 900;
416
417         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
418                                                   expected2->query_name, dbdata,
419                                                   (dns_sdlzlookup_t *)expected2),
420                                  ISC_R_SUCCESS,
421                                  "Failed to lookup hostname");
422         for (i = 0; i < expected2->num_records; i++) {
423                 torture_assert(tctx, expected2->records[i].printed,
424                                talloc_asprintf(tctx,
425                                "Failed to have putrr callback run name[%s] for type %s",
426                                expected2->records[i].name,
427                                expected2->records[i].type));
428         }
429         torture_assert_int_equal(tctx, expected2->num_rr,
430                                  expected2->num_records,
431                                  "Got too much data");
432
433         dlz_destroy(dbdata);
434
435         return true;
436 }
437
438 /*
439  * Test some zone dumps
440  */
441 static bool test_dlz_bind9_zonedump(struct torture_context *tctx)
442 {
443         size_t i;
444         void *dbdata;
445         const char *argv[] = {
446                 "samba_dlz",
447                 "-H",
448                 lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
449                 NULL
450         };
451         struct test_expected_rr *expected1 = NULL;
452
453         tctx_static = tctx;
454         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
455                                                   "log", dlz_bind9_log_wrapper,
456                                                   "writeable_zone", dlz_bind9_writeable_zone_hook,
457                                                   "putrr", dlz_bind9_putrr_hook,
458                                                   "putnamedrr", dlz_bind9_putnamedrr_hook,
459                                                   NULL),
460                                  ISC_R_SUCCESS,
461                                  "Failed to create samba_dlz");
462
463         torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata),
464                                                      ISC_R_SUCCESS,
465                                  "Failed to configure samba_dlz");
466
467         expected1 = talloc_zero(tctx, struct test_expected_rr);
468         torture_assert(tctx, expected1 != NULL, "talloc failed");
469         expected1->tctx = tctx;
470
471         expected1->num_records = 7;
472         expected1->records = talloc_zero_array(expected1,
473                                                struct test_expected_record,
474                                                expected1->num_records);
475         torture_assert(tctx, expected1->records != NULL, "talloc failed");
476
477         expected1->records[0].name = talloc_asprintf(expected1->records,
478                                 "%s.", lpcfg_dnsdomain(tctx->lp_ctx));
479         expected1->records[0].type = "soa";
480         expected1->records[0].ttl = 3600;
481         expected1->records[0].data = talloc_asprintf(expected1->records,
482                                 "%s.%s. hostmaster.%s. 1 900 600 86400 3600",
483                                 torture_setting_string(tctx, "host", NULL),
484                                 lpcfg_dnsdomain(tctx->lp_ctx),
485                                 lpcfg_dnsdomain(tctx->lp_ctx));
486         torture_assert(tctx, expected1->records[0].data != NULL, "talloc failed");
487
488         expected1->records[1].name = talloc_asprintf(expected1->records,
489                                 "%s.", lpcfg_dnsdomain(tctx->lp_ctx));
490         expected1->records[1].type = "ns";
491         expected1->records[1].ttl = 900;
492         expected1->records[1].data = talloc_asprintf(expected1->records, "%s.%s.",
493                                 torture_setting_string(tctx, "host", NULL),
494                                 lpcfg_dnsdomain(tctx->lp_ctx));
495         torture_assert(tctx, expected1->records[1].data != NULL, "talloc failed");
496
497         expected1->records[2].name = talloc_asprintf(expected1->records,
498                                 "%s.", lpcfg_dnsdomain(tctx->lp_ctx));
499         expected1->records[2].type = "aaaa";
500         expected1->records[2].ttl = 900;
501
502         expected1->records[3].name = talloc_asprintf(expected1->records,
503                                 "%s.", lpcfg_dnsdomain(tctx->lp_ctx));
504         expected1->records[3].type = "a";
505         expected1->records[3].ttl = 900;
506
507         expected1->records[4].name = talloc_asprintf(expected1->records, "%s.%s.",
508                                 torture_setting_string(tctx, "host", NULL),
509                                 lpcfg_dnsdomain(tctx->lp_ctx));
510         torture_assert(tctx, expected1->records[4].name != NULL, "unknown host");
511         expected1->records[4].type = "aaaa";
512         expected1->records[4].ttl = 900;
513
514         expected1->records[5].name = talloc_asprintf(expected1->records, "%s.%s.",
515                                 torture_setting_string(tctx, "host", NULL),
516                                 lpcfg_dnsdomain(tctx->lp_ctx));
517         torture_assert(tctx, expected1->records[5].name != NULL, "unknown host");
518         expected1->records[5].type = "a";
519         expected1->records[5].ttl = 900;
520
521         /*
522          * We expect multiple srv records
523          */
524         expected1->records[6].name = NULL;
525         expected1->records[6].type = "srv";
526         expected1->records[6].ttl = 900;
527
528         torture_assert_int_equal(tctx, dlz_allnodes(lpcfg_dnsdomain(tctx->lp_ctx),
529                                                     dbdata, (dns_sdlzallnodes_t *)expected1),
530                                  ISC_R_SUCCESS,
531                                  "Failed to configure samba_dlz");
532         for (i = 0; i < expected1->num_records; i++) {
533                 torture_assert(tctx, expected1->records[i].printed,
534                                talloc_asprintf(tctx,
535                                "Failed to have putrr callback run name[%s] for type %s",
536                                expected1->records[i].name,
537                                expected1->records[i].type));
538         }
539         torture_assert_int_equal(tctx, expected1->num_rr, 24,
540                                  "Got wrong record count");
541
542         dlz_destroy(dbdata);
543
544         return true;
545 }
546
547 /*
548  * Test some updates
549  */
550 static bool test_dlz_bind9_update01(struct torture_context *tctx)
551 {
552         NTSTATUS status;
553         struct gensec_security *gensec_client_context;
554         DATA_BLOB client_to_server, server_to_client;
555         void *dbdata;
556         void *version = NULL;
557         const char *argv[] = {
558                 "samba_dlz",
559                 "-H",
560                 lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
561                 NULL
562         };
563         struct test_expected_rr *expected1 = NULL;
564         char *name = NULL;
565         char *data0 = NULL;
566         char *data1 = NULL;
567         char *data2 = NULL;
568         bool ret = false;
569
570         tctx_static = tctx;
571         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
572                                                   "log", dlz_bind9_log_wrapper,
573                                                   "writeable_zone", dlz_bind9_writeable_zone_hook,
574                                                   "putrr", dlz_bind9_putrr_hook,
575                                                   "putnamedrr", dlz_bind9_putnamedrr_hook,
576                                                   NULL),
577                                  ISC_R_SUCCESS,
578                                  "Failed to create samba_dlz");
579
580         torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata),
581                                                      ISC_R_SUCCESS,
582                                  "Failed to configure samba_dlz");
583
584         expected1 = talloc_zero(tctx, struct test_expected_rr);
585         torture_assert(tctx, expected1 != NULL, "talloc failed");
586         expected1->tctx = tctx;
587
588         expected1->query_name = __func__;
589
590         name = talloc_asprintf(expected1, "%s.%s",
591                                 expected1->query_name,
592                                 lpcfg_dnsdomain(tctx->lp_ctx));
593         torture_assert(tctx, name != NULL, "talloc failed");
594
595         expected1->num_records = 2;
596         expected1->records = talloc_zero_array(expected1,
597                                                struct test_expected_record,
598                                                expected1->num_records);
599         torture_assert(tctx, expected1->records != NULL, "talloc failed");
600
601         expected1->records[0].name = expected1->query_name;
602         expected1->records[0].type = "a";
603         expected1->records[0].ttl = 3600;
604         expected1->records[0].data = "127.1.2.3";
605         expected1->records[0].printed = false;
606
607         data0 = talloc_asprintf(expected1,
608                                 "%s.\t" "%u\t" "%s\t" "%s\t" "%s",
609                                 name,
610                                 (unsigned)expected1->records[0].ttl,
611                                 "in",
612                                 expected1->records[0].type,
613                                 expected1->records[0].data);
614         torture_assert(tctx, data0 != NULL, "talloc failed");
615
616         expected1->records[1].name = expected1->query_name;
617         expected1->records[1].type = "a";
618         expected1->records[1].ttl = 3600;
619         expected1->records[1].data = "127.3.2.1";
620         expected1->records[1].printed = false;
621
622         data1 = talloc_asprintf(expected1,
623                                 "%s.\t" "%u\t" "%s\t" "%s\t" "%s",
624                                 name,
625                                 (unsigned)expected1->records[1].ttl,
626                                 "in",
627                                 expected1->records[1].type,
628                                 expected1->records[1].data);
629         torture_assert(tctx, data1 != NULL, "talloc failed");
630
631         data2 = talloc_asprintf(expected1,
632                                 "%s.\t" "0\t" "in\t" "a\t" "127.3.3.3",
633                                 name);
634         torture_assert(tctx, data2 != NULL, "talloc failed");
635
636         /*
637          * Prepare session info
638          */
639         status = gensec_client_start(tctx, &gensec_client_context,
640                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx));
641         torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");
642
643         /*
644          * dlz_bind9 use the special dns/host.domain account
645          */
646         status = gensec_set_target_hostname(gensec_client_context,
647                                             talloc_asprintf(tctx,
648                                 "%s.%s",
649                                 torture_setting_string(tctx, "host", NULL),
650                                 lpcfg_dnsdomain(tctx->lp_ctx)));
651         torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed");
652
653         status = gensec_set_target_service(gensec_client_context, "dns");
654         torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_service failed");
655
656         status = gensec_set_credentials(gensec_client_context, cmdline_credentials);
657         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");
658
659         status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSS-SPNEGO");
660         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");
661
662         server_to_client = data_blob(NULL, 0);
663
664         /* Do one step of the client-server update dance */
665         status = gensec_update(gensec_client_context, tctx, server_to_client, &client_to_server);
666         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
667                 torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
668         }
669
670         torture_assert_int_equal(tctx, dlz_ssumatch(cli_credentials_get_username(cmdline_credentials),
671                                                     name,
672                                                     "127.0.0.1",
673                                                     expected1->records[0].type,
674                                                     "key",
675                                                     client_to_server.length,
676                                                     client_to_server.data,
677                                                     dbdata),
678                                  ISC_TRUE,
679                                  "Failed to check key for update rights samba_dlz");
680
681         /*
682          * We test the following:
683          *
684          *  1. lookup the records => NOT_FOUND
685          *  2. delete all records => NOT_FOUND
686          *  3. delete 1st record => NOT_FOUND
687          *  4. create 1st record => SUCCESS
688          *  5. lookup the records => found 1st
689          *  6. create 2nd record => SUCCESS
690          *  7. lookup the records => found 1st and 2nd
691          *  8. delete unknown record => NOT_FOUND
692          *  9. lookup the records => found 1st and 2nd
693          * 10. delete 1st record => SUCCESS
694          * 11. lookup the records => found 2nd
695          * 12. delete 2nd record => SUCCESS
696          * 13. lookup the records => NOT_FOUND
697          * 14. create 1st record => SUCCESS
698          * 15. lookup the records => found 1st
699          * 16. create 2nd record => SUCCESS
700          * 17. lookup the records => found 1st and 2nd
701          * 18. update 1st record => SUCCESS
702          * 19. lookup the records => found 1st and 2nd
703          * 20. delete all unknown type records => NOT_FOUND
704          * 21. lookup the records => found 1st and 2nd
705          * 22. delete all records => SUCCESS
706          * 23. lookup the records => NOT_FOUND
707          */
708
709         /* Step 1. */
710         expected1->num_rr = 0;
711         expected1->records[0].printed = false;
712         expected1->records[1].printed = false;
713         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
714                                                   expected1->query_name, dbdata,
715                                                   (dns_sdlzlookup_t *)expected1),
716                                  ISC_R_NOTFOUND,
717                                  "Found hostname");
718         torture_assert_int_equal(tctx, expected1->num_rr, 0,
719                                  "Got wrong record count");
720
721         /* Step 2. */
722         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
723                                                       dbdata, &version),
724                                  ISC_R_SUCCESS,
725                                  "Failed to start transaction");
726         torture_assert_int_equal_goto(tctx,
727                         dlz_delrdataset(name,
728                                         expected1->records[0].type,
729                                         dbdata, version),
730                         ISC_R_NOTFOUND, ret, cancel_version,
731                         talloc_asprintf(tctx, "Deleted name[%s] type[%s]\n",
732                         name, expected1->records[0].type));
733         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);
734
735         /* Step 3. */
736         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
737                                                       dbdata, &version),
738                                  ISC_R_SUCCESS,
739                                  "Failed to start transaction");
740         torture_assert_int_equal_goto(tctx,
741                         dlz_subrdataset(name, data0, dbdata, version),
742                         ISC_R_NOTFOUND, ret, cancel_version,
743                         talloc_asprintf(tctx, "Deleted name[%s] data[%s]\n",
744                         name, data0));
745         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);
746
747         /* Step 4. */
748         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
749                                                       dbdata, &version),
750                                  ISC_R_SUCCESS,
751                                  "Failed to start transaction");
752         torture_assert_int_equal_goto(tctx,
753                         dlz_addrdataset(name, data0, dbdata, version),
754                         ISC_R_SUCCESS, ret, cancel_version,
755                         talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
756                         name, data0));
757         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
758
759         /* Step 5. */
760         expected1->num_rr = 0;
761         expected1->records[0].printed = false;
762         expected1->records[1].printed = false;
763         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
764                                                   expected1->query_name, dbdata,
765                                                   (dns_sdlzlookup_t *)expected1),
766                                  ISC_R_SUCCESS,
767                                  "Not found hostname");
768         torture_assert(tctx, expected1->records[0].printed,
769                        talloc_asprintf(tctx,
770                        "Failed to have putrr callback run name[%s] for type %s",
771                        expected1->records[0].name,
772                        expected1->records[0].type));
773         torture_assert_int_equal(tctx, expected1->num_rr, 1,
774                                  "Got wrong record count");
775
776         /* Step 6. */
777         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
778                                                       dbdata, &version),
779                                  ISC_R_SUCCESS,
780                                  "Failed to start transaction");
781         torture_assert_int_equal_goto(tctx,
782                         dlz_addrdataset(name, data1, dbdata, version),
783                         ISC_R_SUCCESS, ret, cancel_version,
784                         talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
785                         name, data1));
786         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
787
788         /* Step 7. */
789         expected1->num_rr = 0;
790         expected1->records[0].printed = false;
791         expected1->records[1].printed = false;
792         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
793                                                   expected1->query_name, dbdata,
794                                                   (dns_sdlzlookup_t *)expected1),
795                                  ISC_R_SUCCESS,
796                                  "Not found hostname");
797         torture_assert(tctx, expected1->records[0].printed,
798                        talloc_asprintf(tctx,
799                        "Failed to have putrr callback run name[%s] for type %s",
800                        expected1->records[0].name,
801                        expected1->records[0].type));
802         torture_assert(tctx, expected1->records[1].printed,
803                        talloc_asprintf(tctx,
804                        "Failed to have putrr callback run name[%s] for type %s",
805                        expected1->records[1].name,
806                        expected1->records[1].type));
807         torture_assert_int_equal(tctx, expected1->num_rr, 2,
808                                  "Got wrong record count");
809
810         /* Step 8. */
811         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
812                                                       dbdata, &version),
813                                  ISC_R_SUCCESS,
814                                  "Failed to start transaction");
815         torture_assert_int_equal_goto(tctx,
816                         dlz_subrdataset(name, data2, dbdata, version),
817                         ISC_R_NOTFOUND, ret, cancel_version,
818                         talloc_asprintf(tctx, "Deleted name[%s] data[%s]\n",
819                         name, data2));
820         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
821
822         /* Step 9. */
823         expected1->num_rr = 0;
824         expected1->records[0].printed = false;
825         expected1->records[1].printed = false;
826         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
827                                                   expected1->query_name, dbdata,
828                                                   (dns_sdlzlookup_t *)expected1),
829                                  ISC_R_SUCCESS,
830                                  "Not found hostname");
831         torture_assert(tctx, expected1->records[0].printed,
832                        talloc_asprintf(tctx,
833                        "Failed to have putrr callback run name[%s] for type %s",
834                        expected1->records[0].name,
835                        expected1->records[0].type));
836         torture_assert(tctx, expected1->records[1].printed,
837                        talloc_asprintf(tctx,
838                        "Failed to have putrr callback run name[%s] for type %s",
839                        expected1->records[1].name,
840                        expected1->records[1].type));
841         torture_assert_int_equal(tctx, expected1->num_rr, 2,
842                                  "Got wrong record count");
843
844         /* Step 10. */
845         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
846                                                       dbdata, &version),
847                                  ISC_R_SUCCESS,
848                                  "Failed to start transaction");
849         torture_assert_int_equal_goto(tctx,
850                         dlz_subrdataset(name, data0, dbdata, version),
851                         ISC_R_SUCCESS, ret, cancel_version,
852                         talloc_asprintf(tctx, "Failed to delete name[%s] data[%s]\n",
853                         name, data0));
854         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
855
856         /* Step 11. */
857         expected1->num_rr = 0;
858         expected1->records[0].printed = false;
859         expected1->records[1].printed = false;
860         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
861                                                   expected1->query_name, dbdata,
862                                                   (dns_sdlzlookup_t *)expected1),
863                                  ISC_R_SUCCESS,
864                                  "Not found hostname");
865         torture_assert(tctx, expected1->records[1].printed,
866                        talloc_asprintf(tctx,
867                        "Failed to have putrr callback run name[%s] for type %s",
868                        expected1->records[1].name,
869                        expected1->records[1].type));
870         torture_assert_int_equal(tctx, expected1->num_rr, 1,
871                                  "Got wrong record count");
872
873         /* Step 12. */
874         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
875                                                       dbdata, &version),
876                                  ISC_R_SUCCESS,
877                                  "Failed to start transaction");
878         torture_assert_int_equal_goto(tctx,
879                         dlz_subrdataset(name, data1, dbdata, version),
880                         ISC_R_SUCCESS, ret, cancel_version,
881                         talloc_asprintf(tctx, "Failed to delete name[%s] data[%s]\n",
882                         name, data1));
883         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
884
885         /* Step 13. */
886         expected1->num_rr = 0;
887         expected1->records[0].printed = false;
888         expected1->records[1].printed = false;
889         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
890                                                   expected1->query_name, dbdata,
891                                                   (dns_sdlzlookup_t *)expected1),
892                                  ISC_R_NOTFOUND,
893                                  "Found hostname");
894         torture_assert_int_equal(tctx, expected1->num_rr, 0,
895                                  "Got wrong record count");
896
897         /* Step 14. */
898         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
899                                                       dbdata, &version),
900                                  ISC_R_SUCCESS,
901                                  "Failed to start transaction");
902         torture_assert_int_equal_goto(tctx,
903                         dlz_addrdataset(name, data0, dbdata, version),
904                         ISC_R_SUCCESS, ret, cancel_version,
905                         talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
906                         name, data0));
907         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
908
909         /* Step 15. */
910         expected1->num_rr = 0;
911         expected1->records[0].printed = false;
912         expected1->records[1].printed = false;
913         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
914                                                   expected1->query_name, dbdata,
915                                                   (dns_sdlzlookup_t *)expected1),
916                                  ISC_R_SUCCESS,
917                                  "Not found hostname");
918         torture_assert(tctx, expected1->records[0].printed,
919                        talloc_asprintf(tctx,
920                        "Failed to have putrr callback run name[%s] for type %s",
921                        expected1->records[0].name,
922                        expected1->records[0].type));
923         torture_assert_int_equal(tctx, expected1->num_rr, 1,
924                                  "Got wrong record count");
925
926         /* Step 16. */
927         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
928                                                       dbdata, &version),
929                                  ISC_R_SUCCESS,
930                                  "Failed to start transaction");
931         torture_assert_int_equal_goto(tctx,
932                         dlz_addrdataset(name, data1, dbdata, version),
933                         ISC_R_SUCCESS, ret, cancel_version,
934                         talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
935                         name, data1));
936         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
937
938         /* Step 17. */
939         expected1->num_rr = 0;
940         expected1->records[0].printed = false;
941         expected1->records[1].printed = false;
942         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
943                                                   expected1->query_name, dbdata,
944                                                   (dns_sdlzlookup_t *)expected1),
945                                  ISC_R_SUCCESS,
946                                  "Not found hostname");
947         torture_assert(tctx, expected1->records[0].printed,
948                        talloc_asprintf(tctx,
949                        "Failed to have putrr callback run name[%s] for type %s",
950                        expected1->records[0].name,
951                        expected1->records[0].type));
952         torture_assert(tctx, expected1->records[1].printed,
953                        talloc_asprintf(tctx,
954                        "Failed to have putrr callback run name[%s] for type %s",
955                        expected1->records[1].name,
956                        expected1->records[1].type));
957         torture_assert_int_equal(tctx, expected1->num_rr, 2,
958                                  "Got wrong record count");
959
960         /* Step 18. */
961         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
962                                                       dbdata, &version),
963                                  ISC_R_SUCCESS,
964                                  "Failed to start transaction");
965         torture_assert_int_equal_goto(tctx,
966                         dlz_addrdataset(name, data0, dbdata, version),
967                         ISC_R_SUCCESS, ret, cancel_version,
968                         talloc_asprintf(tctx, "Failed to update name[%s] data[%s]\n",
969                         name, data0));
970         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
971
972         /* Step 19. */
973         expected1->num_rr = 0;
974         expected1->records[0].printed = false;
975         expected1->records[1].printed = false;
976         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
977                                                   expected1->query_name, dbdata,
978                                                   (dns_sdlzlookup_t *)expected1),
979                                  ISC_R_SUCCESS,
980                                  "Not found hostname");
981         torture_assert(tctx, expected1->records[0].printed,
982                        talloc_asprintf(tctx,
983                        "Failed to have putrr callback run name[%s] for type %s",
984                        expected1->records[0].name,
985                        expected1->records[0].type));
986         torture_assert(tctx, expected1->records[1].printed,
987                        talloc_asprintf(tctx,
988                        "Failed to have putrr callback run name[%s] for type %s",
989                        expected1->records[1].name,
990                        expected1->records[1].type));
991         torture_assert_int_equal(tctx, expected1->num_rr, 2,
992                                  "Got wrong record count");
993
994         /* Step 20. */
995         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
996                                                       dbdata, &version),
997                                  ISC_R_SUCCESS,
998                                  "Failed to start transaction");
999         torture_assert_int_equal_goto(tctx,
1000                         dlz_delrdataset(name, "txt", dbdata, version),
1001                         ISC_R_FAILURE, ret, cancel_version,
1002                         talloc_asprintf(tctx, "Deleted name[%s] type[%s]\n",
1003                         name, "txt"));
1004         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);
1005
1006         /* Step 21. */
1007         expected1->num_rr = 0;
1008         expected1->records[0].printed = false;
1009         expected1->records[1].printed = false;
1010         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
1011                                                   expected1->query_name, dbdata,
1012                                                   (dns_sdlzlookup_t *)expected1),
1013                                  ISC_R_SUCCESS,
1014                                  "Not found hostname");
1015         torture_assert(tctx, expected1->records[0].printed,
1016                        talloc_asprintf(tctx,
1017                        "Failed to have putrr callback run name[%s] for type %s",
1018                        expected1->records[0].name,
1019                        expected1->records[0].type));
1020         torture_assert(tctx, expected1->records[1].printed,
1021                        talloc_asprintf(tctx,
1022                        "Failed to have putrr callback run name[%s] for type %s",
1023                        expected1->records[1].name,
1024                        expected1->records[1].type));
1025         torture_assert_int_equal(tctx, expected1->num_rr, 2,
1026                                  "Got wrong record count");
1027
1028         /* Step 22. */
1029         torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
1030                                                       dbdata, &version),
1031                                  ISC_R_SUCCESS,
1032                                  "Failed to start transaction");
1033         torture_assert_int_equal_goto(tctx,
1034                         dlz_delrdataset(name,
1035                                         expected1->records[0].type,
1036                                         dbdata, version),
1037                         ISC_R_SUCCESS, ret, cancel_version,
1038                         talloc_asprintf(tctx, "Failed to delete name[%s] type[%s]\n",
1039                         name, expected1->records[0].type));
1040         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);
1041
1042         /* Step 23. */
1043         expected1->num_rr = 0;
1044         expected1->records[0].printed = false;
1045         expected1->records[1].printed = false;
1046         torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
1047                                                   expected1->query_name, dbdata,
1048                                                   (dns_sdlzlookup_t *)expected1),
1049                                  ISC_R_NOTFOUND,
1050                                  "Found hostname");
1051         torture_assert_int_equal(tctx, expected1->num_rr, 0,
1052                                  "Got wrong record count");
1053
1054         dlz_destroy(dbdata);
1055
1056         return true;
1057
1058 cancel_version:
1059         dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);
1060         return ret;
1061 }
1062
1063 static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx)
1064 {
1065         struct torture_suite *suite = torture_suite_create(ctx, "dlz_bind9");
1066
1067         suite->description = talloc_strdup(suite,
1068                                            "Tests for the BIND 9 DLZ module");
1069         torture_suite_add_simple_test(suite, "version", test_dlz_bind9_version);
1070         torture_suite_add_simple_test(suite, "create", test_dlz_bind9_create);
1071         torture_suite_add_simple_test(suite, "configure", test_dlz_bind9_configure);
1072         torture_suite_add_simple_test(suite, "gssapi", test_dlz_bind9_gssapi);
1073         torture_suite_add_simple_test(suite, "spnego", test_dlz_bind9_spnego);
1074         torture_suite_add_simple_test(suite, "lookup", test_dlz_bind9_lookup);
1075         torture_suite_add_simple_test(suite, "zonedump", test_dlz_bind9_zonedump);
1076         torture_suite_add_simple_test(suite, "update01", test_dlz_bind9_update01);
1077         return suite;
1078 }
1079
1080 /**
1081  * DNS torture module initialization
1082  */
1083 NTSTATUS torture_bind_dns_init(TALLOC_CTX *);
1084 NTSTATUS torture_bind_dns_init(TALLOC_CTX *ctx)
1085 {
1086         struct torture_suite *suite;
1087
1088         /* register DNS related test cases */
1089         suite = dlz_bind9_suite(ctx);
1090         if (!suite) return NT_STATUS_NO_MEMORY;
1091         torture_register_suite(ctx, suite);
1092
1093         return NT_STATUS_OK;
1094 }