2 Unix SMB/CIFS implementation.
3 test suite for various Domain DFS
4 Copyright (C) Matthieu Patou 2010
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.
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.
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/>.
21 #include "libcli/libcli.h"
22 #include "torture/smbtorture.h"
23 #include "torture/util.h"
24 #include "../librpc/gen_ndr/ndr_dfsblobs.h"
25 #include "librpc/ndr/libndr.h"
26 #include "param/param.h"
27 #include "torture/torture.h"
28 #include "torture/dfs/proto.h"
30 static bool test_getdomainreferral(struct torture_context *tctx,
31 struct smbcli_state *cli)
33 struct dfs_GetDFSReferral r;
34 struct dfs_referral_resp resp;
36 r.in.req.max_referral_level = 3;
37 r.in.req.servername = "";
40 torture_assert_ntstatus_ok(tctx,
41 dfs_cli_do_call(cli->tree, &r),
42 "Get Domain referral failed");
44 torture_assert_int_equal(tctx, resp.path_consumed, 0,
45 "Path consumed not equal to 0");
46 torture_assert_int_equal(tctx, resp.nb_referrals != 0, 1,
47 "0 domains referrals returned");
48 torture_assert_int_equal(tctx, resp.header_flags, 0,
49 "Header flag different it's not a referral server");
50 torture_assert_int_equal(tctx, resp.referral_entries[1].version, 3,
52 "Not expected version for referral entry 1 got %d expected 3",
53 resp.referral_entries[1].version));
54 torture_assert_int_equal(tctx, resp.referral_entries[0].version, 3,
56 "Not expected version for referral entry 0 got %d expected 3",
57 resp.referral_entries[0].version));
58 torture_assert_int_equal(tctx, resp.referral_entries[0].referral.v3.data.server_type,
61 "Wrong server type, expected non root server and got %d",
62 resp.referral_entries[0].referral.v3.data.server_type));
63 torture_assert_int_equal(tctx, resp.referral_entries[0].referral.v3.data.entry_flags,
64 DFS_FLAG_REFERRAL_DOMAIN_RESP,
66 "Wrong entry flag expected to have a domain response and got %d",
67 resp.referral_entries[0].referral.v3.data.entry_flags));
68 torture_assert_int_equal(tctx, strlen(
69 resp.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
71 "Length of domain is 0 or less");
75 static bool test_getdcreferral(struct torture_context *tctx,
76 struct smbcli_state *cli)
78 struct dfs_GetDFSReferral r, r2, r3;
79 struct dfs_referral_resp resp, resp2, resp3;
83 r.in.req.max_referral_level = 3;
84 r.in.req.servername = "";
87 torture_assert_ntstatus_ok(tctx,
88 dfs_cli_do_call(cli->tree, &r),
89 "Get Domain referral failed");
91 str = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name;
92 if( strchr(str, '.') == NULL ) {
93 str = resp.referral_entries[1].referral.v3.data.referrals.r2.special_name;
96 r2.in.req.max_referral_level = 3;
97 r2.in.req.servername = str;
100 torture_assert_ntstatus_ok(tctx,
101 dfs_cli_do_call(cli->tree, &r2),
102 "Get DC Domain referral failed");
105 torture_assert_int_equal(tctx, resp2.path_consumed, 0,
106 "Path consumed not equal to 0");
107 torture_assert_int_equal(tctx, resp2.nb_referrals , 1,
108 "We do not received only 1 referral");
109 torture_assert_int_equal(tctx, resp2.header_flags, 0,
110 "Header flag different it's not a referral server");
111 torture_assert_int_equal(tctx, resp2.referral_entries[0].version, 3,
112 talloc_asprintf(tctx,
113 "Not expected version for referral entry 0 got %d expected 3",
114 resp2.referral_entries[0].version));
115 torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.server_type,
117 talloc_asprintf(tctx,
118 "Wrong server type, expected non root server and got %d",
119 resp2.referral_entries[0].referral.v3.data.server_type));
120 torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.entry_flags,
121 DFS_FLAG_REFERRAL_DOMAIN_RESP,
122 talloc_asprintf(tctx,
123 "Wrong entry flag expected to have a domain response and got %d",
124 resp2.referral_entries[0].referral.v3.data.entry_flags));
125 torture_assert_int_equal(tctx, strlen(
126 resp2.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
128 "Length of domain is 0 or less");
129 torture_assert_int_equal(tctx, strlen(
130 resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0,
132 "Length of first dc is less than 0");
133 str = strchr(resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0], '.');
134 str2 = resp2.referral_entries[0].referral.v3.data.referrals.r2.special_name;
135 if (str2[0] == '\\') {
138 torture_assert_int_equal(tctx, strlen(str) >0, 1 ,"Length of domain too short");
140 torture_assert_int_equal(tctx, strcmp(str,str2), 0,
141 talloc_asprintf(tctx, "Pb domain of the dc is not"\
142 "the same as the requested: domain = %s got =%s",str2 ,str));
144 r3.in.req.max_referral_level = 3;
146 * Windows 7 and at least windows 2008 server sends domain.fqdn instead of \domain.fqdn
147 * (as it is specified in the spec)
148 * Let's check that we are able to support it too
150 r3.in.req.servername = str;
151 r3.out.resp = &resp3;
153 torture_assert_ntstatus_ok(tctx,
154 dfs_cli_do_call(cli->tree, &r3),
155 "Get DC Domain referral failed");
157 torture_assert_int_equal(tctx, resp3.path_consumed, 0,
158 "Path consumed not equal to 0");
159 torture_assert_int_equal(tctx, resp3.nb_referrals , 1,
160 "We do not received only 1 referral");
161 torture_assert_int_equal(tctx, resp3.header_flags, 0,
162 "Header flag different it's not a referral server");
163 torture_assert_int_equal(tctx, resp3.referral_entries[0].version, 3,
164 talloc_asprintf(tctx,
165 "Not expected version for referral entry 0 got %d expected 3",
166 resp3.referral_entries[0].version));
167 torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.server_type,
169 talloc_asprintf(tctx,
170 "Wrong server type, expected non root server and got %d",
171 resp3.referral_entries[0].referral.v3.data.server_type));
172 torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.entry_flags,
173 DFS_FLAG_REFERRAL_DOMAIN_RESP,
174 talloc_asprintf(tctx,
175 "Wrong entry flag expected to have a domain response and got %d",
176 resp3.referral_entries[0].referral.v3.data.entry_flags));
177 torture_assert_int_equal(tctx, strlen(
178 resp3.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
180 "Length of domain is 0 or less");
181 torture_assert_int_equal(tctx, strlen(
182 resp3.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0,
184 "Length of first dc is less than 0");
188 static bool test_getdcreferral_netbios(struct torture_context *tctx,
189 struct smbcli_state *cli)
191 struct dfs_GetDFSReferral r, r2, r3;
192 struct dfs_referral_resp resp, resp2, resp3;
195 r.in.req.max_referral_level = 3;
196 r.in.req.servername = "";
199 torture_assert_ntstatus_ok(tctx,
200 dfs_cli_do_call(cli->tree, &r),
201 "Get Domain referral failed");
203 r2.in.req.max_referral_level = 3;
205 str = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name;
206 if( strchr(str, '.') != NULL ) {
207 str = resp.referral_entries[1].referral.v3.data.referrals.r2.special_name;
210 r2.in.req.servername = str;
211 r2.out.resp = &resp2;
213 torture_assert_ntstatus_ok(tctx,
214 dfs_cli_do_call(cli->tree, &r2),
215 "Get DC Domain referral failed");
217 torture_assert_int_equal(tctx, resp2.path_consumed, 0,
218 "Path consumed not equal to 0");
219 torture_assert_int_equal(tctx, resp2.nb_referrals , 1,
220 "We do not received only 1 referral");
221 torture_assert_int_equal(tctx, resp2.header_flags, 0,
222 "Header flag different it's not a referral server");
223 torture_assert_int_equal(tctx, resp2.referral_entries[0].version, 3,
224 talloc_asprintf(tctx,
225 "Not expected version for referral entry 0 got %d expected 3",
226 resp2.referral_entries[0].version));
227 torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.server_type,
229 talloc_asprintf(tctx,
230 "Wrong server type, expected non root server and got %d",
231 resp2.referral_entries[0].referral.v3.data.server_type));
232 torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.entry_flags,
233 DFS_FLAG_REFERRAL_DOMAIN_RESP,
234 talloc_asprintf(tctx,
235 "Wrong entry flag expected to have a domain response and got %d",
236 resp2.referral_entries[0].referral.v3.data.entry_flags));
237 torture_assert_int_equal(tctx, strlen(
238 resp2.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
240 "Length of domain is 0 or less");
241 torture_assert_int_equal(tctx, strlen(
242 resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0,
244 "Length of first dc is less than 0");
245 torture_assert(tctx, strchr(
246 resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0],'.') == NULL,
247 "referral contains dots it's not a netbios name");
249 r3.in.req.max_referral_level = 3;
251 * Windows 7 and at least windows 2008 server sends domain.fqdn instead of \domain.fqdn
252 * (as it is specified in the spec)
253 * Let's check that we are able to support it too
255 r3.in.req.servername = str + 1;
256 r3.out.resp = &resp3;
258 torture_assert_ntstatus_ok(tctx,
259 dfs_cli_do_call(cli->tree, &r3),
260 "Get DC Domain referral failed");
262 torture_assert_int_equal(tctx, resp3.path_consumed, 0,
263 "Path consumed not equal to 0");
264 torture_assert_int_equal(tctx, resp3.nb_referrals , 1,
265 "We do not received only 1 referral");
266 torture_assert_int_equal(tctx, resp3.header_flags, 0,
267 "Header flag different it's not a referral server");
268 torture_assert_int_equal(tctx, resp3.referral_entries[0].version, 3,
269 talloc_asprintf(tctx,
270 "Not expected version for referral entry 0 got %d expected 3",
271 resp3.referral_entries[0].version));
272 torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.server_type,
274 talloc_asprintf(tctx,
275 "Wrong server type, expected non root server and got %d",
276 resp3.referral_entries[0].referral.v3.data.server_type));
277 torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.entry_flags,
278 DFS_FLAG_REFERRAL_DOMAIN_RESP,
279 talloc_asprintf(tctx,
280 "Wrong entry flag expected to have a domain response and got %d",
281 resp3.referral_entries[0].referral.v3.data.entry_flags));
282 torture_assert_int_equal(tctx, strlen(
283 resp3.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
285 "Length of domain is 0 or less");
286 torture_assert_int_equal(tctx, strlen(
287 resp3.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0,
289 "Length of first dc is less than 0");
290 torture_assert(tctx, strchr(
291 resp3.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0],'.') == NULL,
292 "referral contains dots it's not a netbios name");
296 static bool test_getsysvolreferral(struct torture_context *tctx,
297 struct smbcli_state *cli)
300 struct dfs_GetDFSReferral r, r2, r3;
301 struct dfs_referral_resp resp, resp2, resp3;
303 r.in.req.max_referral_level = 3;
304 r.in.req.servername = "";
307 torture_assert_ntstatus_ok(tctx,
308 dfs_cli_do_call(cli->tree, &r),
309 "Get Domain referral failed");
311 str = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name;
312 if( strchr(str, '.') == NULL ) {
313 str = resp.referral_entries[1].referral.v3.data.referrals.r2.special_name;
316 r2.in.req.max_referral_level = 3;
317 r2.in.req.servername = str;
318 r2.out.resp = &resp2;
320 torture_assert_ntstatus_ok(tctx,
321 dfs_cli_do_call(cli->tree, &r2),
322 "Get DC Domain referral failed");
324 r3.in.req.max_referral_level = 3;
325 r3.in.req.servername = talloc_asprintf(tctx, "%s\\sysvol", str);
326 r3.out.resp = &resp3;
328 torture_assert_ntstatus_ok(tctx,
329 dfs_cli_do_call(cli->tree, &r3),
330 "Get sysvol Domain referral failed");
332 torture_assert_int_equal(tctx, resp3.path_consumed, 2*strlen(r3.in.req.servername),
333 "Path consumed not equal to length of the request");
334 torture_assert_int_equal(tctx, resp3.nb_referrals != 0, 1,
335 "We do not receive at least 1 referral");
336 torture_assert_int_equal(tctx, resp3.header_flags, DFS_HEADER_FLAG_STORAGE_SVR,
337 "Header flag different it's not a referral for a storage");
338 torture_assert_int_equal(tctx, resp3.referral_entries[0].version, 3,
339 talloc_asprintf(tctx,
340 "Not expected version for referral entry 0 got %d expected 3",
341 resp3.referral_entries[0].version));
342 torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.server_type,
344 talloc_asprintf(tctx,
345 "Wrong server type, expected non root server and got %d",
346 resp3.referral_entries[0].referral.v3.data.server_type));
347 torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.entry_flags,
349 talloc_asprintf(tctx,
350 "Wrong entry flag expected to have a non domain response and got %d",
351 resp3.referral_entries[0].referral.v3.data.entry_flags));
352 torture_assert_int_equal(tctx, strlen(
353 resp3.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
355 "Length of domain is 0 or less");
356 torture_assert_int_equal(tctx, strlen(
357 resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0,
359 "Length of first referral is less than 0");
361 r3.in.req.max_referral_level = 4;
363 torture_assert_ntstatus_ok(tctx,
364 dfs_cli_do_call(cli->tree, &r3),
365 "Get sysvol Domain referral failed");
367 torture_assert_int_equal(tctx, resp3.referral_entries[0].version, 4,
368 talloc_asprintf(tctx,
369 "Not expected version for referral entry 0 got %d expected 4",
370 resp3.referral_entries[0].version));
373 * We do not support fallback indication for the moment
375 torture_assert_int_equal(tctx, resp3.header_flags,
376 DFS_HEADER_FLAG_STORAGE_SVR | DFS_HEADER_FLAG_TARGET_BCK,
377 "Header flag different it's not a referral for a storage with fallback");
379 torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v4.entry_flags,
380 DFS_FLAG_REFERRAL_FIRST_TARGET_SET,
381 talloc_asprintf(tctx,
382 "Wrong entry flag expected to have a non domain response and got %d",
383 resp3.referral_entries[0].referral.v4.entry_flags));
387 static bool test_unknowndomain(struct torture_context *tctx,
388 struct smbcli_state *cli)
390 struct dfs_GetDFSReferral r, r2;
391 struct dfs_referral_resp resp, resp2;
393 r.in.req.max_referral_level = 3;
394 r.in.req.servername = "";
397 torture_assert_ntstatus_ok(tctx,
398 dfs_cli_do_call(cli->tree, &r),
399 "Get Domain referral failed");
401 r2.in.req.max_referral_level = 3;
402 r2.in.req.servername = "foobar.none.net";
403 r2.out.resp = &resp2;
405 torture_assert_ntstatus_equal(tctx,
406 dfs_cli_do_call(cli->tree, &r2),
407 NT_STATUS_INVALID_PARAMETER,
408 "Get DC Domain didn't return exptected error code");
413 static bool test_getsysvolplusreferral(struct torture_context *tctx,
414 struct smbcli_state *cli)
417 struct dfs_GetDFSReferral r, r2, r3;
418 struct dfs_referral_resp resp, resp2, resp3;
420 r.in.req.max_referral_level = 3;
421 r.in.req.servername = "";
424 torture_assert_ntstatus_ok(tctx,
425 dfs_cli_do_call(cli->tree, &r),
426 "Get Domain referral failed");
428 r2.in.req.max_referral_level = 3;
429 r2.in.req.servername = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name;
430 r2.out.resp = &resp2;
432 torture_assert_ntstatus_ok(tctx,
433 dfs_cli_do_call(cli->tree, &r2),
434 "Get DC Domain referral failed");
436 str = resp2.referral_entries[0].referral.v3.data.referrals.r2.special_name;
437 r3.in.req.max_referral_level = 3;
438 r3.in.req.servername = talloc_asprintf(tctx, "%s\\sysvol\\foo", str);
439 r3.out.resp = &resp3;
441 torture_assert_ntstatus_equal(tctx,
442 dfs_cli_do_call(cli->tree, &r3),
444 "Bad behavior with subtree sysvol referral");
449 static bool test_low_referral_level(struct torture_context *tctx,
450 struct smbcli_state *cli)
452 struct dfs_GetDFSReferral r;
453 struct dfs_referral_resp resp;
455 r.in.req.max_referral_level = 2;
456 r.in.req.servername = "";
459 torture_assert_ntstatus_equal(tctx,
460 dfs_cli_do_call(cli->tree, &r),
461 NT_STATUS_UNSUCCESSFUL,
462 "Unexpected STATUS for invalid deferral retquest");
467 NTSTATUS torture_dfs_init(void)
469 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "DFS");
470 struct torture_suite *suite_basic = torture_suite_create(suite, "DOMAIN");
472 torture_suite_add_suite(suite, suite_basic);
474 torture_suite_add_1smb_test(suite_basic, "domain referral",
475 test_getdomainreferral);
476 torture_suite_add_1smb_test(suite_basic, "dc referral",
478 torture_suite_add_1smb_test(suite_basic, "dc referral netbios",
479 test_getdcreferral_netbios);
481 torture_suite_add_1smb_test(suite_basic, "sysvol referral",
482 test_getsysvolreferral);
484 /* Non standard case */
486 torture_suite_add_1smb_test(suite_basic, "dc referral on unknown domain",
488 torture_suite_add_1smb_test(suite_basic, "sysvol with subtree referral",
489 test_getsysvolplusreferral);
490 torture_suite_add_1smb_test(suite_basic, "referral with a level 2",
491 test_low_referral_level);
494 * test with invalid level
498 suite->description = talloc_strdup(suite, "DFS referrals calls");
500 torture_register_suite(suite);