source: trunk/server/source4/torture/dfs/domaindfs.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 18.5 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 test suite for various Domain DFS
4 Copyright (C) Matthieu Patou 2010
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 "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"
29
30static bool test_getdomainreferral(struct torture_context *tctx,
31 struct smbcli_state *cli)
32{
33 struct dfs_GetDFSReferral r;
34 struct dfs_referral_resp resp;
35
36 r.in.req.max_referral_level = 3;
37 r.in.req.servername = "";
38 r.out.resp = &resp;
39
40 torture_assert_ntstatus_ok(tctx,
41 dfs_cli_do_call(cli->tree, &r),
42 "Get Domain referral failed");
43
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,
51 talloc_asprintf(tctx,
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,
55 talloc_asprintf(tctx,
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,
59 DFS_SERVER_NON_ROOT,
60 talloc_asprintf(tctx,
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,
65 talloc_asprintf(tctx,
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,
70 1,
71 "Length of domain is 0 or less");
72 return true;
73}
74
75static bool test_getdcreferral(struct torture_context *tctx,
76 struct smbcli_state *cli)
77{
78 struct dfs_GetDFSReferral r, r2, r3;
79 struct dfs_referral_resp resp, resp2, resp3;
80 const char* str;
81 const char* str2;
82
83 r.in.req.max_referral_level = 3;
84 r.in.req.servername = "";
85 r.out.resp = &resp;
86
87 torture_assert_ntstatus_ok(tctx,
88 dfs_cli_do_call(cli->tree, &r),
89 "Get Domain referral failed");
90
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;
94 }
95
96 r2.in.req.max_referral_level = 3;
97 r2.in.req.servername = str;
98 r2.out.resp = &resp2;
99
100 torture_assert_ntstatus_ok(tctx,
101 dfs_cli_do_call(cli->tree, &r2),
102 "Get DC Domain referral failed");
103
104
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,
116 DFS_SERVER_NON_ROOT,
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,
127 1,
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,
131 1,
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] == '\\') {
136 str2++;
137 }
138 torture_assert_int_equal(tctx, strlen(str) >0, 1 ,"Length of domain too short");
139 str++;
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));
143
144 r3.in.req.max_referral_level = 3;
145 /*
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
149 */
150 r3.in.req.servername = str;
151 r3.out.resp = &resp3;
152
153 torture_assert_ntstatus_ok(tctx,
154 dfs_cli_do_call(cli->tree, &r3),
155 "Get DC Domain referral failed");
156
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,
168 DFS_SERVER_NON_ROOT,
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,
179 1,
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,
183 1,
184 "Length of first dc is less than 0");
185 return true;
186}
187
188static bool test_getdcreferral_netbios(struct torture_context *tctx,
189 struct smbcli_state *cli)
190{
191 struct dfs_GetDFSReferral r, r2, r3;
192 struct dfs_referral_resp resp, resp2, resp3;
193 const char* str;
194
195 r.in.req.max_referral_level = 3;
196 r.in.req.servername = "";
197 r.out.resp = &resp;
198
199 torture_assert_ntstatus_ok(tctx,
200 dfs_cli_do_call(cli->tree, &r),
201 "Get Domain referral failed");
202
203 r2.in.req.max_referral_level = 3;
204
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;
208 }
209
210 r2.in.req.servername = str;
211 r2.out.resp = &resp2;
212
213 torture_assert_ntstatus_ok(tctx,
214 dfs_cli_do_call(cli->tree, &r2),
215 "Get DC Domain referral failed");
216
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,
228 DFS_SERVER_NON_ROOT,
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,
239 1,
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,
243 1,
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");
248
249 r3.in.req.max_referral_level = 3;
250 /*
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
254 */
255 r3.in.req.servername = str + 1;
256 r3.out.resp = &resp3;
257
258 torture_assert_ntstatus_ok(tctx,
259 dfs_cli_do_call(cli->tree, &r3),
260 "Get DC Domain referral failed");
261
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,
273 DFS_SERVER_NON_ROOT,
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,
284 1,
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,
288 1,
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");
293 return true;
294}
295
296static bool test_getsysvolreferral(struct torture_context *tctx,
297 struct smbcli_state *cli)
298{
299 const char* str;
300 struct dfs_GetDFSReferral r, r2, r3;
301 struct dfs_referral_resp resp, resp2, resp3;
302
303 r.in.req.max_referral_level = 3;
304 r.in.req.servername = "";
305 r.out.resp = &resp;
306
307 torture_assert_ntstatus_ok(tctx,
308 dfs_cli_do_call(cli->tree, &r),
309 "Get Domain referral failed");
310
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;
314 }
315
316 r2.in.req.max_referral_level = 3;
317 r2.in.req.servername = str;
318 r2.out.resp = &resp2;
319
320 torture_assert_ntstatus_ok(tctx,
321 dfs_cli_do_call(cli->tree, &r2),
322 "Get DC Domain referral failed");
323
324 r3.in.req.max_referral_level = 3;
325 r3.in.req.servername = talloc_asprintf(tctx, "%s\\sysvol", str);
326 r3.out.resp = &resp3;
327
328 torture_assert_ntstatus_ok(tctx,
329 dfs_cli_do_call(cli->tree, &r3),
330 "Get sysvol Domain referral failed");
331
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,
343 DFS_SERVER_NON_ROOT,
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,
348 0,
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,
354 1,
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,
358 1,
359 "Length of first referral is less than 0");
360
361 r3.in.req.max_referral_level = 4;
362
363 torture_assert_ntstatus_ok(tctx,
364 dfs_cli_do_call(cli->tree, &r3),
365 "Get sysvol Domain referral failed");
366
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));
371#if 0
372 /*
373 * We do not support fallback indication for the moment
374 */
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");
378#endif
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));
384 return true;
385}
386
387static bool test_unknowndomain(struct torture_context *tctx,
388 struct smbcli_state *cli)
389{
390 struct dfs_GetDFSReferral r, r2;
391 struct dfs_referral_resp resp, resp2;
392
393 r.in.req.max_referral_level = 3;
394 r.in.req.servername = "";
395 r.out.resp = &resp;
396
397 torture_assert_ntstatus_ok(tctx,
398 dfs_cli_do_call(cli->tree, &r),
399 "Get Domain referral failed");
400
401 r2.in.req.max_referral_level = 3;
402 r2.in.req.servername = "foobar.none.net";
403 r2.out.resp = &resp2;
404
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");
409
410 return true;
411}
412
413static bool test_getsysvolplusreferral(struct torture_context *tctx,
414 struct smbcli_state *cli)
415{
416 const char* str;
417 struct dfs_GetDFSReferral r, r2, r3;
418 struct dfs_referral_resp resp, resp2, resp3;
419
420 r.in.req.max_referral_level = 3;
421 r.in.req.servername = "";
422 r.out.resp = &resp;
423
424 torture_assert_ntstatus_ok(tctx,
425 dfs_cli_do_call(cli->tree, &r),
426 "Get Domain referral failed");
427
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;
431
432 torture_assert_ntstatus_ok(tctx,
433 dfs_cli_do_call(cli->tree, &r2),
434 "Get DC Domain referral failed");
435
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;
440
441 torture_assert_ntstatus_equal(tctx,
442 dfs_cli_do_call(cli->tree, &r3),
443 NT_STATUS_NOT_FOUND,
444 "Bad behavior with subtree sysvol referral");
445
446 return true;
447}
448
449static bool test_low_referral_level(struct torture_context *tctx,
450 struct smbcli_state *cli)
451{
452 struct dfs_GetDFSReferral r;
453 struct dfs_referral_resp resp;
454
455 r.in.req.max_referral_level = 2;
456 r.in.req.servername = "";
457 r.out.resp = &resp;
458
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");
463
464 return true;
465}
466
467NTSTATUS torture_dfs_init(void)
468{
469 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "dfs");
470 struct torture_suite *suite_basic = torture_suite_create(suite, "domain");
471
472 torture_suite_add_suite(suite, suite_basic);
473
474 torture_suite_add_1smb_test(suite_basic, "domain referral",
475 test_getdomainreferral);
476 torture_suite_add_1smb_test(suite_basic, "dc referral",
477 test_getdcreferral);
478 torture_suite_add_1smb_test(suite_basic, "dc referral netbios",
479 test_getdcreferral_netbios);
480
481 torture_suite_add_1smb_test(suite_basic, "sysvol referral",
482 test_getsysvolreferral);
483
484 /* Non standard case */
485
486 torture_suite_add_1smb_test(suite_basic, "dc referral on unknown domain",
487 test_unknowndomain);
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);
492
493 /*
494 * test with invalid level
495 * test with netbios
496 */
497
498 suite->description = talloc_strdup(suite, "DFS referrals calls");
499
500 torture_register_suite(suite);
501
502 return NT_STATUS_OK;
503}
Note: See TracBrowser for help on using the repository browser.