torture: Ensure that GSSAPI and SPNEGO packets are accepted by dlz_bind9
[mat/samba.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 {
37         va_list ap;
38         char *msg;
39         va_start(ap, fmt);
40         msg = talloc_vasprintf(NULL, fmt, ap);
41         torture_comment(tctx_static, "%s\n", msg);
42         TALLOC_FREE(msg);
43         va_end(ap);
44 }
45
46 static bool test_dlz_bind9_version(struct torture_context *tctx)
47 {
48         unsigned int flags = 0;
49         torture_assert_int_equal(tctx, dlz_version(&flags),
50                                  DLZ_DLOPEN_VERSION, "got wrong DLZ version");
51         return true;
52 }
53
54 static bool test_dlz_bind9_create(struct torture_context *tctx)
55 {
56         void *dbdata;
57         const char *argv[] = {
58                 "samba_dlz",
59                 "-H",
60                 lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
61                 NULL
62         };
63         tctx_static = tctx;
64         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, discard_const_p(char *, argv), &dbdata,
65                                                   "log", dlz_bind9_log_wrapper, NULL), ISC_R_SUCCESS,
66                 "Failed to create samba_dlz");
67
68         dlz_destroy(dbdata);
69
70         return true;
71 }
72
73 static isc_result_t dlz_bind9_writeable_zone_hook(dns_view_t *view,
74                                            const char *zone_name)
75 {
76         struct torture_context *tctx = talloc_get_type((void *)view, struct torture_context);
77         struct ldb_context *samdb = samdb_connect_url(tctx, NULL, tctx->lp_ctx,
78                                                       system_session(tctx->lp_ctx),
79                                                       0, lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"));
80         struct ldb_message *msg;
81         int ret;
82         const char *attrs[] = {
83                 NULL
84         };
85         if (!samdb) {
86                 torture_fail(tctx, "Failed to connect to samdb");
87                 return ISC_R_FAILURE;
88         }
89
90         ret = dsdb_search_one(samdb, tctx, &msg, NULL,
91                               LDB_SCOPE_SUBTREE, attrs, DSDB_SEARCH_SEARCH_ALL_PARTITIONS,
92                               "(&(objectClass=dnsZone)(name=%s))", zone_name);
93         if (ret != LDB_SUCCESS) {
94                 torture_fail(tctx, talloc_asprintf(tctx, "Failed to search for %s: %s", zone_name, ldb_errstring(samdb)));
95                 return ISC_R_FAILURE;
96         }
97         talloc_free(msg);
98
99         return ISC_R_SUCCESS;
100 }
101
102 static bool test_dlz_bind9_configure(struct torture_context *tctx)
103 {
104         void *dbdata;
105         const char *argv[] = {
106                 "samba_dlz",
107                 "-H",
108                 lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
109                 NULL
110         };
111         tctx_static = tctx;
112         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, discard_const_p(char *, argv), &dbdata,
113                                                   "log", dlz_bind9_log_wrapper,
114                                                   "writeable_zone", dlz_bind9_writeable_zone_hook, NULL),
115                                  ISC_R_SUCCESS,
116                                  "Failed to create samba_dlz");
117
118         torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata),
119                                                      ISC_R_SUCCESS,
120                                  "Failed to configure samba_dlz");
121
122         dlz_destroy(dbdata);
123
124         return true;
125 }
126
127 /*
128  * Test that a ticket obtained for the DNS service will be accepted on the Samba DLZ side
129  *
130  */
131 static bool test_dlz_bind9_gensec(struct torture_context *tctx, const char *mech)
132 {
133         NTSTATUS status;
134
135         struct gensec_security *gensec_client_context;
136
137         DATA_BLOB client_to_server, server_to_client;
138
139         void *dbdata;
140         const char *argv[] = {
141                 "samba_dlz",
142                 "-H",
143                 lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
144                 NULL
145         };
146         tctx_static = tctx;
147         torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, discard_const_p(char *, argv), &dbdata,
148                                                   "log", dlz_bind9_log_wrapper,
149                                                   "writeable_zone", dlz_bind9_writeable_zone_hook, NULL),
150                                  ISC_R_SUCCESS,
151                                  "Failed to create samba_dlz");
152
153         torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata),
154                                                      ISC_R_SUCCESS,
155                                  "Failed to configure samba_dlz");
156
157         status = gensec_client_start(tctx, &gensec_client_context,
158                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx));
159         torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");
160
161         status = gensec_set_target_hostname(gensec_client_context, torture_setting_string(tctx, "host", NULL));
162         torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed");
163
164         status = gensec_set_credentials(gensec_client_context, cmdline_credentials);
165         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");
166
167         status = gensec_start_mech_by_sasl_name(gensec_client_context, mech);
168         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");
169
170         server_to_client = data_blob(NULL, 0);
171
172         /* Do one step of the client-server update dance */
173         status = gensec_update(gensec_client_context, tctx, tctx->ev, server_to_client, &client_to_server);
174         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
175                 torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
176         }
177
178         torture_assert_int_equal(tctx, dlz_ssumatch(cli_credentials_get_username(cmdline_credentials),
179                                                     lpcfg_dnsdomain(tctx->lp_ctx),
180                                                     "127.0.0.1", "type", "key",
181                                                     client_to_server.length,
182                                                     client_to_server.data,
183                                                     dbdata),
184                                  ISC_R_SUCCESS,
185                                  "Failed to check key for update rights samba_dlz");
186
187         dlz_destroy(dbdata);
188
189         return true;
190 }
191
192 static bool test_dlz_bind9_gssapi(struct torture_context *tctx)
193 {
194         return test_dlz_bind9_gensec(tctx, "GSSAPI");
195 }
196
197 static bool test_dlz_bind9_spnego(struct torture_context *tctx)
198 {
199         return test_dlz_bind9_gensec(tctx, "GSS-SPNEGO");
200 }
201
202 static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx)
203 {
204         struct torture_suite *suite = torture_suite_create(ctx, "dlz_bind9");
205
206         suite->description = talloc_strdup(suite,
207                                            "Tests for the BIND 9 DLZ module");
208         torture_suite_add_simple_test(suite, "version", test_dlz_bind9_version);
209         torture_suite_add_simple_test(suite, "create", test_dlz_bind9_create);
210         torture_suite_add_simple_test(suite, "configure", test_dlz_bind9_configure);
211         torture_suite_add_simple_test(suite, "gssapi", test_dlz_bind9_gssapi);
212         torture_suite_add_simple_test(suite, "spnego", test_dlz_bind9_spnego);
213         return suite;
214 }
215
216 /**
217  * DNS torture module initialization
218  */
219 NTSTATUS torture_bind_dns_init(void)
220 {
221         struct torture_suite *suite;
222         TALLOC_CTX *mem_ctx = talloc_autofree_context();
223
224         /* register DNS related test cases */
225         suite = dlz_bind9_suite(mem_ctx);
226         if (!suite) return NT_STATUS_NO_MEMORY;
227         torture_register_suite(suite);
228
229         return NT_STATUS_OK;
230 }