s4-smbtorture: Make test names lowercase and dot-separated.
[sfrench/samba-autobuild/.git] / source4 / torture / dfs / domaindfs.c
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
30 static 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
75 static 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
188 static 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
296 static 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
387 static 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
413 static 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
449 static 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
467 NTSTATUS 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 }