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