ctdb-scripts: Support storing statd-callout state in cluster filesystem
[samba4-gss.git] / source4 / torture / smb2 / rename.c
blob31e30fa19b49f207dfc7f95e9719a053b0626df0
1 /*
2 Unix SMB/CIFS implementation.
4 SMB2 rename test suite
6 Copyright (C) Christian Ambach 2012
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25 #include <tevent.h>
26 #include "lib/util/tevent_ntstatus.h"
28 #include "torture/torture.h"
29 #include "torture/util.h"
30 #include "torture/smb2/proto.h"
32 #include "librpc/gen_ndr/security.h"
34 #define CHECK_VAL(v, correct) \
35 do { \
36 if ((v) != (correct)) { \
37 torture_result(torture, \
38 TORTURE_FAIL, \
39 "(%s): wrong value for %s got " \
40 "0x%llx - should be 0x%llx\n", \
41 __location__, #v, \
42 (unsigned long long)v, \
43 (unsigned long long)correct); \
44 ret = false; \
45 goto done; \
46 }} while (0)
48 #define CHECK_CREATED(__io, __created, __attribute) \
49 do { \
50 CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \
51 CHECK_VAL((__io)->out.size, 0); \
52 CHECK_VAL((__io)->out.file_attr, (__attribute)); \
53 CHECK_VAL((__io)->out.reserved2, 0); \
54 } while(0)
56 #define CHECK_STATUS(status, correct) do { \
57 if (!NT_STATUS_EQUAL(status, correct)) { \
58 torture_result(torture, TORTURE_FAIL, \
59 "(%s) Incorrect status %s - should be %s\n", \
60 __location__, nt_errstr(status), nt_errstr(correct)); \
61 ret = false; \
62 goto done; \
63 }} while (0)
65 #define BASEDIR "test_rename"
68 * basic testing of rename: open file with DELETE access
69 * this should pass
72 static bool torture_smb2_rename_simple(struct torture_context *torture,
73 struct smb2_tree *tree1)
75 bool ret = true;
76 NTSTATUS status;
77 union smb_open io;
78 union smb_close cl;
79 union smb_setfileinfo sinfo;
80 union smb_fileinfo fi;
81 struct smb2_handle h1;
83 ZERO_STRUCT(h1);
85 smb2_deltree(tree1, BASEDIR);
86 smb2_util_rmdir(tree1, BASEDIR);
88 torture_comment(torture, "Creating base directory\n");
90 smb2_util_mkdir(tree1, BASEDIR);
93 torture_comment(torture, "Creating test file\n");
95 ZERO_STRUCT(io.smb2);
96 io.generic.level = RAW_OPEN_SMB2;
97 io.smb2.in.create_flags = 0;
98 io.smb2.in.desired_access = SEC_FILE_ALL|SEC_STD_DELETE;
99 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
100 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
101 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
102 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
103 io.smb2.in.alloc_size = 0;
104 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
105 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
106 io.smb2.in.security_flags = 0;
107 io.smb2.in.fname = BASEDIR "\\file.txt";
109 status = smb2_create(tree1, torture, &(io.smb2));
110 CHECK_STATUS(status, NT_STATUS_OK);
111 h1 = io.smb2.out.file.handle;
113 torture_comment(torture, "Renaming test file\n");
115 ZERO_STRUCT(sinfo);
116 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
117 sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
118 sinfo.rename_information.in.overwrite = 0;
119 sinfo.rename_information.in.root_fid = 0;
120 sinfo.rename_information.in.new_name =
121 BASEDIR "\\newname.txt";
122 status = smb2_setinfo_file(tree1, &sinfo);
123 CHECK_STATUS(status, NT_STATUS_OK);
125 torture_comment(torture, "Checking for new filename\n");
127 ZERO_STRUCT(fi);
128 fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
129 fi.generic.in.file.handle = h1;
130 status = smb2_getinfo_file(tree1, torture, &fi);
131 CHECK_STATUS(status, NT_STATUS_OK);
134 torture_comment(torture, "Closing test file\n");
136 ZERO_STRUCT(cl.smb2);
137 cl.smb2.level = RAW_CLOSE_SMB2;
138 cl.smb2.in.file.handle = h1;
139 status = smb2_close(tree1, &(cl.smb2));
140 CHECK_STATUS(status, NT_STATUS_OK);
142 ZERO_STRUCT(h1);
144 done:
146 torture_comment(torture, "Cleaning up\n");
148 if (h1.data[0] || h1.data[1]) {
149 ZERO_STRUCT(cl.smb2);
150 cl.smb2.level = RAW_CLOSE_SMB2;
151 cl.smb2.in.file.handle = h1;
152 status = smb2_close(tree1, &(cl.smb2));
154 smb2_deltree(tree1, BASEDIR);
155 return ret;
159 * basic testing of rename, this time do not request DELETE access
160 * for the file, this should fail
163 static bool torture_smb2_rename_simple2(struct torture_context *torture,
164 struct smb2_tree *tree1)
166 bool ret = true;
167 NTSTATUS status;
168 union smb_open io;
169 union smb_close cl;
170 union smb_setfileinfo sinfo;
171 struct smb2_handle h1;
173 ZERO_STRUCT(h1);
175 smb2_deltree(tree1, BASEDIR);
176 smb2_util_rmdir(tree1, BASEDIR);
178 torture_comment(torture, "Creating base directory\n");
180 smb2_util_mkdir(tree1, BASEDIR);
183 torture_comment(torture, "Creating test file\n");
185 ZERO_STRUCT(io.smb2);
186 io.generic.level = RAW_OPEN_SMB2;
187 io.smb2.in.create_flags = 0;
188 io.smb2.in.desired_access = SEC_FILE_ALL;
189 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
190 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
191 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
192 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
193 io.smb2.in.alloc_size = 0;
194 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
195 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
196 io.smb2.in.security_flags = 0;
197 io.smb2.in.fname = BASEDIR "\\file.txt";
199 status = smb2_create(tree1, torture, &(io.smb2));
200 CHECK_STATUS(status, NT_STATUS_OK);
201 h1 = io.smb2.out.file.handle;
203 torture_comment(torture, "Renaming test file\n");
205 ZERO_STRUCT(sinfo);
206 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
207 sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
208 sinfo.rename_information.in.overwrite = 0;
209 sinfo.rename_information.in.root_fid = 0;
210 sinfo.rename_information.in.new_name =
211 BASEDIR "\\newname.txt";
212 status = smb2_setinfo_file(tree1, &sinfo);
213 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
215 torture_comment(torture, "Closing test file\n");
217 ZERO_STRUCT(cl.smb2);
218 cl.smb2.level = RAW_CLOSE_SMB2;
219 cl.smb2.in.file.handle = h1;
220 status = smb2_close(tree1, &(cl.smb2));
221 CHECK_STATUS(status, NT_STATUS_OK);
223 ZERO_STRUCT(h1);
225 done:
227 torture_comment(torture, "Cleaning up\n");
229 if (h1.data[0] || h1.data[1]) {
230 ZERO_STRUCT(cl.smb2);
231 cl.smb2.level = RAW_CLOSE_SMB2;
232 cl.smb2.in.file.handle = h1;
233 status = smb2_close(tree1, &(cl.smb2));
235 smb2_deltree(tree1, BASEDIR);
236 return ret;
241 * testing of rename with no sharing allowed on file
242 * this should work
245 static bool torture_smb2_rename_no_sharemode(struct torture_context *torture,
246 struct smb2_tree *tree1)
248 bool ret = true;
249 NTSTATUS status;
250 union smb_open io;
251 union smb_close cl;
252 union smb_setfileinfo sinfo;
253 union smb_fileinfo fi;
254 struct smb2_handle h1;
256 ZERO_STRUCT(h1);
258 smb2_deltree(tree1, BASEDIR);
259 smb2_util_rmdir(tree1, BASEDIR);
261 torture_comment(torture, "Creating base directory\n");
263 smb2_util_mkdir(tree1, BASEDIR);
266 torture_comment(torture, "Creating test file\n");
268 ZERO_STRUCT(io.smb2);
269 io.generic.level = RAW_OPEN_SMB2;
270 io.smb2.in.create_flags = 0;
271 io.smb2.in.desired_access = 0x0017019f;
272 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
273 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
274 io.smb2.in.share_access = 0;
275 io.smb2.in.alloc_size = 0;
276 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
277 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
278 io.smb2.in.security_flags = 0;
279 io.smb2.in.fname = BASEDIR "\\file.txt";
281 status = smb2_create(tree1, torture, &(io.smb2));
282 CHECK_STATUS(status, NT_STATUS_OK);
283 h1 = io.smb2.out.file.handle;
285 torture_comment(torture, "Renaming test file\n");
287 ZERO_STRUCT(sinfo);
288 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
289 sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
290 sinfo.rename_information.in.overwrite = 0;
291 sinfo.rename_information.in.root_fid = 0;
292 sinfo.rename_information.in.new_name =
293 BASEDIR "\\newname.txt";
294 status = smb2_setinfo_file(tree1, &sinfo);
295 CHECK_STATUS(status, NT_STATUS_OK);
297 torture_comment(torture, "Checking for new filename\n");
299 ZERO_STRUCT(fi);
300 fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
301 fi.generic.in.file.handle = h1;
302 status = smb2_getinfo_file(tree1, torture, &fi);
303 CHECK_STATUS(status, NT_STATUS_OK);
306 torture_comment(torture, "Closing test file\n");
308 ZERO_STRUCT(cl.smb2);
309 cl.smb2.level = RAW_CLOSE_SMB2;
310 cl.smb2.in.file.handle = h1;
311 status = smb2_close(tree1, &(cl.smb2));
312 CHECK_STATUS(status, NT_STATUS_OK);
314 ZERO_STRUCT(h1);
316 done:
318 torture_comment(torture, "Cleaning up\n");
320 if (h1.data[0] || h1.data[1]) {
321 ZERO_STRUCT(cl.smb2);
322 cl.smb2.level = RAW_CLOSE_SMB2;
323 cl.smb2.in.file.handle = h1;
324 status = smb2_close(tree1, &(cl.smb2));
326 smb2_deltree(tree1, BASEDIR);
327 return ret;
331 * testing of rename when opening parent dir with delete access and delete
332 * sharing allowed
333 * should result in sharing violation
336 static bool torture_smb2_rename_with_delete_access(struct torture_context *torture,
337 struct smb2_tree *tree1)
339 bool ret = true;
340 NTSTATUS status;
341 union smb_open io;
342 union smb_close cl;
343 union smb_setfileinfo sinfo;
344 struct smb2_handle fh, dh;
346 ZERO_STRUCT(fh);
347 ZERO_STRUCT(dh);
349 smb2_deltree(tree1, BASEDIR);
350 smb2_util_rmdir(tree1, BASEDIR);
352 torture_comment(torture, "Creating base directory\n");
354 smb2_util_mkdir(tree1, BASEDIR);
356 torture_comment(torture, "Opening parent directory\n");
358 ZERO_STRUCT(io.smb2);
359 io.generic.level = RAW_OPEN_SMB2;
360 io.smb2.in.create_flags = 0;
361 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
362 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
363 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
364 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
365 SEC_FILE_WRITE_DATA;
366 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
367 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
368 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
369 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
370 io.smb2.in.alloc_size = 0;
371 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
372 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
373 io.smb2.in.security_flags = 0;
374 io.smb2.in.fname = BASEDIR;
376 status = smb2_create(tree1, torture, &(io.smb2));
377 CHECK_STATUS(status, NT_STATUS_OK);
378 dh = io.smb2.out.file.handle;
381 torture_comment(torture, "Creating test file\n");
383 ZERO_STRUCT(io.smb2);
384 io.generic.level = RAW_OPEN_SMB2;
385 io.smb2.in.create_flags = 0;
386 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
387 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
388 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
389 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
390 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
391 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
392 io.smb2.in.share_access = 0;
393 io.smb2.in.alloc_size = 0;
394 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
395 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
396 io.smb2.in.security_flags = 0;
397 io.smb2.in.fname = BASEDIR "\\file.txt";
399 status = smb2_create(tree1, torture, &(io.smb2));
400 CHECK_STATUS(status, NT_STATUS_OK);
401 fh = io.smb2.out.file.handle;
403 torture_comment(torture, "Renaming test file\n");
405 ZERO_STRUCT(sinfo);
406 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
407 sinfo.rename_information.in.file.handle = fh;
408 sinfo.rename_information.in.overwrite = 0;
409 sinfo.rename_information.in.root_fid = 0;
410 sinfo.rename_information.in.new_name =
411 BASEDIR "\\newname.txt";
412 status = smb2_setinfo_file(tree1, &sinfo);
413 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
415 torture_comment(torture, "Closing test file\n");
417 ZERO_STRUCT(cl.smb2);
418 cl.smb2.level = RAW_CLOSE_SMB2;
419 cl.smb2.in.file.handle = fh;
420 status = smb2_close(tree1, &(cl.smb2));
421 CHECK_STATUS(status, NT_STATUS_OK);
423 ZERO_STRUCT(fh);
425 torture_comment(torture, "Closing directory\n");
427 ZERO_STRUCT(cl.smb2);
428 cl.smb2.level = RAW_CLOSE_SMB2;
429 cl.smb2.in.file.handle = dh;
430 status = smb2_close(tree1, &(cl.smb2));
431 CHECK_STATUS(status, NT_STATUS_OK);
433 ZERO_STRUCT(dh);
436 done:
438 torture_comment(torture, "Cleaning up\n");
440 if (fh.data[0] || fh.data[1]) {
441 ZERO_STRUCT(cl.smb2);
442 cl.smb2.level = RAW_CLOSE_SMB2;
443 cl.smb2.in.file.handle = fh;
444 status = smb2_close(tree1, &(cl.smb2));
446 if (dh.data[0] || dh.data[1]) {
447 ZERO_STRUCT(cl.smb2);
448 cl.smb2.level = RAW_CLOSE_SMB2;
449 cl.smb2.in.file.handle = dh;
450 status = smb2_close(tree1, &(cl.smb2));
453 smb2_deltree(tree1, BASEDIR);
454 return ret;
459 * testing of rename with delete access on parent dir
460 * this is a variation of the test above: parent dir is opened
461 * without share_delete, so rename must fail
464 static bool torture_smb2_rename_with_delete_access2(struct torture_context *torture,
465 struct smb2_tree *tree1)
467 bool ret = true;
468 NTSTATUS status;
469 union smb_open io;
470 union smb_close cl;
471 union smb_setfileinfo sinfo;
472 struct smb2_handle fh, dh;
474 ZERO_STRUCT(fh);
475 ZERO_STRUCT(dh);
477 smb2_deltree(tree1, BASEDIR);
478 smb2_util_rmdir(tree1, BASEDIR);
480 torture_comment(torture, "Creating base directory\n");
482 smb2_util_mkdir(tree1, BASEDIR);
484 torture_comment(torture, "Opening parent directory\n");
486 ZERO_STRUCT(io.smb2);
487 io.generic.level = RAW_OPEN_SMB2;
488 io.smb2.in.create_flags = 0;
489 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
490 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
491 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
492 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
493 SEC_FILE_WRITE_DATA;
494 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
495 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
496 io.smb2.in.share_access = 0;
497 io.smb2.in.alloc_size = 0;
498 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
499 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
500 io.smb2.in.security_flags = 0;
501 io.smb2.in.fname = BASEDIR;
503 status = smb2_create(tree1, torture, &(io.smb2));
504 CHECK_STATUS(status, NT_STATUS_OK);
505 dh = io.smb2.out.file.handle;
508 torture_comment(torture, "Creating test file\n");
510 ZERO_STRUCT(io.smb2);
511 io.generic.level = RAW_OPEN_SMB2;
512 io.smb2.in.create_flags = 0;
513 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
514 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
515 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
516 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
517 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
518 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
519 io.smb2.in.share_access = 0;
520 io.smb2.in.alloc_size = 0;
521 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
522 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
523 io.smb2.in.security_flags = 0;
524 io.smb2.in.fname = BASEDIR "\\file.txt";
526 status = smb2_create(tree1, torture, &(io.smb2));
527 CHECK_STATUS(status, NT_STATUS_OK);
528 fh = io.smb2.out.file.handle;
530 torture_comment(torture, "Renaming test file\n");
532 ZERO_STRUCT(sinfo);
533 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
534 sinfo.rename_information.in.file.handle = fh;
535 sinfo.rename_information.in.overwrite = 0;
536 sinfo.rename_information.in.root_fid = 0;
537 sinfo.rename_information.in.new_name =
538 BASEDIR "\\newname.txt";
539 status = smb2_setinfo_file(tree1, &sinfo);
540 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
542 torture_comment(torture, "Closing test file\n");
544 ZERO_STRUCT(cl.smb2);
545 cl.smb2.level = RAW_CLOSE_SMB2;
546 cl.smb2.in.file.handle = fh;
547 status = smb2_close(tree1, &(cl.smb2));
548 CHECK_STATUS(status, NT_STATUS_OK);
550 ZERO_STRUCT(fh);
552 torture_comment(torture, "Closing directory\n");
554 ZERO_STRUCT(cl.smb2);
555 cl.smb2.level = RAW_CLOSE_SMB2;
556 cl.smb2.in.file.handle = dh;
557 status = smb2_close(tree1, &(cl.smb2));
558 CHECK_STATUS(status, NT_STATUS_OK);
560 ZERO_STRUCT(dh);
563 done:
565 torture_comment(torture, "Cleaning up\n");
567 if (fh.data[0] || fh.data[1]) {
568 ZERO_STRUCT(cl.smb2);
569 cl.smb2.level = RAW_CLOSE_SMB2;
570 cl.smb2.in.file.handle = fh;
571 status = smb2_close(tree1, &(cl.smb2));
573 if (dh.data[0] || dh.data[1]) {
574 ZERO_STRUCT(cl.smb2);
575 cl.smb2.level = RAW_CLOSE_SMB2;
576 cl.smb2.in.file.handle = dh;
577 status = smb2_close(tree1, &(cl.smb2));
580 smb2_deltree(tree1, BASEDIR);
581 return ret;
585 * testing of rename when opening parent dir with no delete access and delete
586 * sharing allowed
587 * this should pass
590 static bool torture_smb2_rename_no_delete_access(struct torture_context *torture,
591 struct smb2_tree *tree1)
593 bool ret = true;
594 NTSTATUS status;
595 union smb_open io;
596 union smb_close cl;
597 union smb_setfileinfo sinfo;
598 union smb_fileinfo fi;
599 struct smb2_handle fh, dh;
601 ZERO_STRUCT(fh);
602 ZERO_STRUCT(dh);
604 smb2_deltree(tree1, BASEDIR);
605 smb2_util_rmdir(tree1, BASEDIR);
607 torture_comment(torture, "Creating base directory\n");
609 smb2_util_mkdir(tree1, BASEDIR);
611 torture_comment(torture, "Opening parent directory\n");
613 ZERO_STRUCT(io.smb2);
614 io.generic.level = RAW_OPEN_SMB2;
615 io.smb2.in.create_flags = 0;
616 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
617 SEC_STD_READ_CONTROL | SEC_FILE_WRITE_ATTRIBUTE |
618 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
619 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
620 SEC_FILE_WRITE_DATA;
621 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
622 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
623 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
624 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
625 io.smb2.in.alloc_size = 0;
626 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
627 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
628 io.smb2.in.security_flags = 0;
629 io.smb2.in.fname = BASEDIR;
631 status = smb2_create(tree1, torture, &(io.smb2));
632 CHECK_STATUS(status, NT_STATUS_OK);
633 dh = io.smb2.out.file.handle;
636 torture_comment(torture, "Creating test file\n");
638 ZERO_STRUCT(io.smb2);
639 io.generic.level = RAW_OPEN_SMB2;
640 io.smb2.in.create_flags = 0;
641 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
642 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
643 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
644 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
645 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
646 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
647 io.smb2.in.share_access = 0;
648 io.smb2.in.alloc_size = 0;
649 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
650 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
651 io.smb2.in.security_flags = 0;
652 io.smb2.in.fname = BASEDIR "\\file.txt";
654 status = smb2_create(tree1, torture, &(io.smb2));
655 CHECK_STATUS(status, NT_STATUS_OK);
656 fh = io.smb2.out.file.handle;
658 torture_comment(torture, "Renaming test file\n");
660 ZERO_STRUCT(sinfo);
661 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
662 sinfo.rename_information.in.file.handle = fh;
663 sinfo.rename_information.in.overwrite = 0;
664 sinfo.rename_information.in.root_fid = 0;
665 sinfo.rename_information.in.new_name =
666 BASEDIR "\\newname.txt";
667 status = smb2_setinfo_file(tree1, &sinfo);
668 CHECK_STATUS(status, NT_STATUS_OK);
670 torture_comment(torture, "Checking for new filename\n");
672 ZERO_STRUCT(fi);
673 fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
674 fi.generic.in.file.handle = fh;
675 status = smb2_getinfo_file(tree1, torture, &fi);
676 CHECK_STATUS(status, NT_STATUS_OK);
679 torture_comment(torture, "Closing test file\n");
681 ZERO_STRUCT(cl.smb2);
682 cl.smb2.level = RAW_CLOSE_SMB2;
683 cl.smb2.in.file.handle = fh;
684 status = smb2_close(tree1, &(cl.smb2));
685 CHECK_STATUS(status, NT_STATUS_OK);
687 ZERO_STRUCT(fh);
689 torture_comment(torture, "Closing directory\n");
691 ZERO_STRUCT(cl.smb2);
692 cl.smb2.level = RAW_CLOSE_SMB2;
693 cl.smb2.in.file.handle = dh;
694 status = smb2_close(tree1, &(cl.smb2));
695 CHECK_STATUS(status, NT_STATUS_OK);
697 ZERO_STRUCT(dh);
700 done:
702 torture_comment(torture, "Cleaning up\n");
704 if (fh.data[0] || fh.data[1]) {
705 ZERO_STRUCT(cl.smb2);
706 cl.smb2.level = RAW_CLOSE_SMB2;
707 cl.smb2.in.file.handle = fh;
708 status = smb2_close(tree1, &(cl.smb2));
710 if (dh.data[0] || dh.data[1]) {
711 ZERO_STRUCT(cl.smb2);
712 cl.smb2.level = RAW_CLOSE_SMB2;
713 cl.smb2.in.file.handle = dh;
714 status = smb2_close(tree1, &(cl.smb2));
717 smb2_deltree(tree1, BASEDIR);
718 return ret;
723 * testing of rename with no delete access on parent dir
724 * this is the negative case of the test above: parent dir is opened
725 * without share_delete, so rename must fail
728 static bool torture_smb2_rename_no_delete_access2(struct torture_context *torture,
729 struct smb2_tree *tree1)
731 bool ret = true;
732 NTSTATUS status;
733 union smb_open io;
734 union smb_close cl;
735 union smb_setfileinfo sinfo;
736 struct smb2_handle fh, dh;
738 ZERO_STRUCT(fh);
739 ZERO_STRUCT(dh);
741 smb2_deltree(tree1, BASEDIR);
742 smb2_util_rmdir(tree1, BASEDIR);
744 torture_comment(torture, "Creating base directory\n");
746 smb2_util_mkdir(tree1, BASEDIR);
748 torture_comment(torture, "Opening parent directory\n");
750 ZERO_STRUCT(io.smb2);
751 io.generic.level = RAW_OPEN_SMB2;
752 io.smb2.in.create_flags = 0;
753 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
754 SEC_STD_READ_CONTROL | SEC_FILE_WRITE_ATTRIBUTE |
755 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
756 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
757 SEC_FILE_WRITE_DATA;
758 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
759 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
760 io.smb2.in.share_access = 0;
761 io.smb2.in.alloc_size = 0;
762 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
763 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
764 io.smb2.in.security_flags = 0;
765 io.smb2.in.fname = BASEDIR;
767 status = smb2_create(tree1, torture, &(io.smb2));
768 CHECK_STATUS(status, NT_STATUS_OK);
769 dh = io.smb2.out.file.handle;
772 torture_comment(torture, "Creating test file\n");
774 ZERO_STRUCT(io.smb2);
775 io.generic.level = RAW_OPEN_SMB2;
776 io.smb2.in.create_flags = 0;
777 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
778 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
779 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
780 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
781 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
782 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
783 io.smb2.in.share_access = 0;
784 io.smb2.in.alloc_size = 0;
785 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
786 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
787 io.smb2.in.security_flags = 0;
788 io.smb2.in.fname = BASEDIR "\\file.txt";
790 status = smb2_create(tree1, torture, &(io.smb2));
791 CHECK_STATUS(status, NT_STATUS_OK);
792 fh = io.smb2.out.file.handle;
794 torture_comment(torture, "Renaming test file\n");
796 ZERO_STRUCT(sinfo);
797 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
798 sinfo.rename_information.in.file.handle = fh;
799 sinfo.rename_information.in.overwrite = 0;
800 sinfo.rename_information.in.root_fid = 0;
801 sinfo.rename_information.in.new_name =
802 BASEDIR "\\newname.txt";
803 status = smb2_setinfo_file(tree1, &sinfo);
804 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
806 torture_comment(torture, "Closing test file\n");
808 ZERO_STRUCT(cl.smb2);
809 cl.smb2.level = RAW_CLOSE_SMB2;
810 cl.smb2.in.file.handle = fh;
811 status = smb2_close(tree1, &(cl.smb2));
812 CHECK_STATUS(status, NT_STATUS_OK);
814 ZERO_STRUCT(fh);
816 torture_comment(torture, "Closing directory\n");
818 ZERO_STRUCT(cl.smb2);
819 cl.smb2.level = RAW_CLOSE_SMB2;
820 cl.smb2.in.file.handle = dh;
821 status = smb2_close(tree1, &(cl.smb2));
822 CHECK_STATUS(status, NT_STATUS_OK);
824 ZERO_STRUCT(dh);
827 done:
829 torture_comment(torture, "Cleaning up\n");
831 if (fh.data[0] || fh.data[1]) {
832 ZERO_STRUCT(cl.smb2);
833 cl.smb2.level = RAW_CLOSE_SMB2;
834 cl.smb2.in.file.handle = fh;
835 status = smb2_close(tree1, &(cl.smb2));
837 if (dh.data[0] || dh.data[1]) {
838 ZERO_STRUCT(cl.smb2);
839 cl.smb2.level = RAW_CLOSE_SMB2;
840 cl.smb2.in.file.handle = dh;
841 status = smb2_close(tree1, &(cl.smb2));
844 smb2_deltree(tree1, BASEDIR);
845 return ret;
849 * this is a replay of how Word 2010 saves a file
850 * this should pass
853 static bool torture_smb2_rename_msword(struct torture_context *torture,
854 struct smb2_tree *tree1)
856 bool ret = true;
857 NTSTATUS status;
858 union smb_open io;
859 union smb_close cl;
860 union smb_setfileinfo sinfo;
861 union smb_fileinfo fi;
862 struct smb2_handle fh, dh;
864 ZERO_STRUCT(fh);
865 ZERO_STRUCT(dh);
867 smb2_deltree(tree1, BASEDIR);
868 smb2_util_rmdir(tree1, BASEDIR);
870 torture_comment(torture, "Creating base directory\n");
872 smb2_util_mkdir(tree1, BASEDIR);
874 torture_comment(torture, "Creating test file\n");
876 ZERO_STRUCT(io.smb2);
877 io.generic.level = RAW_OPEN_SMB2;
878 io.smb2.in.create_flags = 0;
879 io.smb2.in.desired_access = 0x0017019f;
880 io.smb2.in.create_options = 0x60;
881 io.smb2.in.file_attributes = 0;
882 io.smb2.in.share_access = 0;
883 io.smb2.in.alloc_size = 0;
884 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
885 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
886 io.smb2.in.security_flags = 0;
887 io.smb2.in.fname = BASEDIR "\\file.txt";
889 status = smb2_create(tree1, torture, &(io.smb2));
890 CHECK_STATUS(status, NT_STATUS_OK);
891 fh = io.smb2.out.file.handle;
893 torture_comment(torture, "Opening parent directory\n");
895 ZERO_STRUCT(io.smb2);
896 io.generic.level = RAW_OPEN_SMB2;
897 io.smb2.in.create_flags = 0;
898 io.smb2.in.desired_access = 0x00100080;
899 io.smb2.in.create_options = 0x00800021;
900 io.smb2.in.file_attributes = 0;
901 io.smb2.in.share_access = 0;
902 io.smb2.in.alloc_size = 0;
903 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
904 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
905 io.smb2.in.security_flags = 0;
906 io.smb2.in.fname = BASEDIR;
908 status = smb2_create(tree1, torture, &(io.smb2));
909 CHECK_STATUS(status, NT_STATUS_OK);
910 dh = io.smb2.out.file.handle;
912 torture_comment(torture, "Renaming test file\n");
914 ZERO_STRUCT(sinfo);
915 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
916 sinfo.rename_information.in.file.handle = fh;
917 sinfo.rename_information.in.overwrite = 0;
918 sinfo.rename_information.in.root_fid = 0;
919 sinfo.rename_information.in.new_name =
920 BASEDIR "\\newname.txt";
921 status = smb2_setinfo_file(tree1, &sinfo);
922 CHECK_STATUS(status, NT_STATUS_OK);
924 torture_comment(torture, "Checking for new filename\n");
926 ZERO_STRUCT(fi);
927 fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
928 fi.generic.in.file.handle = fh;
929 status = smb2_getinfo_file(tree1, torture, &fi);
930 CHECK_STATUS(status, NT_STATUS_OK);
933 torture_comment(torture, "Closing test file\n");
935 ZERO_STRUCT(cl.smb2);
936 cl.smb2.level = RAW_CLOSE_SMB2;
937 cl.smb2.in.file.handle = fh;
938 status = smb2_close(tree1, &(cl.smb2));
939 CHECK_STATUS(status, NT_STATUS_OK);
941 ZERO_STRUCT(fh);
943 torture_comment(torture, "Closing directory\n");
945 ZERO_STRUCT(cl.smb2);
946 cl.smb2.level = RAW_CLOSE_SMB2;
947 cl.smb2.in.file.handle = dh;
948 status = smb2_close(tree1, &(cl.smb2));
949 CHECK_STATUS(status, NT_STATUS_OK);
951 ZERO_STRUCT(dh);
954 done:
956 torture_comment(torture, "Cleaning up\n");
958 if (fh.data[0] || fh.data[1]) {
959 ZERO_STRUCT(cl.smb2);
960 cl.smb2.level = RAW_CLOSE_SMB2;
961 cl.smb2.in.file.handle = fh;
962 status = smb2_close(tree1, &(cl.smb2));
964 if (dh.data[0] || dh.data[1]) {
965 ZERO_STRUCT(cl.smb2);
966 cl.smb2.level = RAW_CLOSE_SMB2;
967 cl.smb2.in.file.handle = dh;
968 status = smb2_close(tree1, &(cl.smb2));
971 smb2_deltree(tree1, BASEDIR);
972 return ret;
975 static bool torture_smb2_rename_dir_openfile(struct torture_context *torture,
976 struct smb2_tree *tree1)
978 bool ret = true;
979 NTSTATUS status;
980 union smb_open io;
981 union smb_close cl;
982 union smb_setfileinfo sinfo;
983 struct smb2_handle d1, h1;
985 ZERO_STRUCT(d1);
986 ZERO_STRUCT(h1);
988 smb2_deltree(tree1, BASEDIR);
989 smb2_util_rmdir(tree1, BASEDIR);
991 torture_comment(torture, "Creating base directory\n");
993 ZERO_STRUCT(io.smb2);
994 io.generic.level = RAW_OPEN_SMB2;
995 io.smb2.in.create_flags = 0;
996 io.smb2.in.desired_access = 0x0017019f;
997 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
998 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
999 io.smb2.in.share_access = 0;
1000 io.smb2.in.alloc_size = 0;
1001 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
1002 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1003 io.smb2.in.security_flags = 0;
1004 io.smb2.in.fname = BASEDIR;
1006 status = smb2_create(tree1, torture, &(io.smb2));
1007 CHECK_STATUS(status, NT_STATUS_OK);
1008 d1 = io.smb2.out.file.handle;
1010 torture_comment(torture, "Creating test file\n");
1012 ZERO_STRUCT(io.smb2);
1013 io.generic.level = RAW_OPEN_SMB2;
1014 io.smb2.in.create_flags = 0;
1015 io.smb2.in.desired_access = 0x0017019f;
1016 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
1017 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1018 io.smb2.in.share_access = 0;
1019 io.smb2.in.alloc_size = 0;
1020 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
1021 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1022 io.smb2.in.security_flags = 0;
1023 io.smb2.in.fname = BASEDIR "\\file.txt";
1025 status = smb2_create(tree1, torture, &(io.smb2));
1026 CHECK_STATUS(status, NT_STATUS_OK);
1027 h1 = io.smb2.out.file.handle;
1029 torture_comment(torture, "Renaming directory\n");
1031 ZERO_STRUCT(sinfo);
1032 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
1033 sinfo.rename_information.in.file.handle = d1;
1034 sinfo.rename_information.in.overwrite = 0;
1035 sinfo.rename_information.in.root_fid = 0;
1036 sinfo.rename_information.in.new_name =
1037 BASEDIR "-new";
1038 status = smb2_setinfo_file(tree1, &sinfo);
1039 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1041 torture_comment(torture, "Closing directory\n");
1043 ZERO_STRUCT(cl.smb2);
1044 cl.smb2.level = RAW_CLOSE_SMB2;
1045 cl.smb2.in.file.handle = d1;
1046 status = smb2_close(tree1, &(cl.smb2));
1047 CHECK_STATUS(status, NT_STATUS_OK);
1048 ZERO_STRUCT(d1);
1050 torture_comment(torture, "Closing test file\n");
1052 cl.smb2.in.file.handle = h1;
1053 status = smb2_close(tree1, &(cl.smb2));
1054 CHECK_STATUS(status, NT_STATUS_OK);
1055 ZERO_STRUCT(h1);
1057 done:
1059 torture_comment(torture, "Cleaning up\n");
1061 if (h1.data[0] || h1.data[1]) {
1062 ZERO_STRUCT(cl.smb2);
1063 cl.smb2.level = RAW_CLOSE_SMB2;
1064 cl.smb2.in.file.handle = h1;
1065 status = smb2_close(tree1, &(cl.smb2));
1067 smb2_deltree(tree1, BASEDIR);
1068 return ret;
1071 struct rename_one_dir_cycle_state {
1072 struct tevent_context *ev;
1073 struct smb2_tree *tree;
1074 struct smb2_handle file;
1075 const char *base_name;
1076 char *new_name;
1077 unsigned *rename_counter;
1079 unsigned current;
1080 unsigned max;
1081 union smb_setfileinfo sinfo;
1084 static void rename_one_dir_cycle_done(struct smb2_request *subreq);
1086 static struct tevent_req *rename_one_dir_cycle_send(TALLOC_CTX *mem_ctx,
1087 struct tevent_context *ev,
1088 struct smb2_tree *tree,
1089 struct smb2_handle file,
1090 unsigned max_renames,
1091 const char *base_name,
1092 unsigned *rename_counter)
1094 struct tevent_req *req;
1095 struct rename_one_dir_cycle_state *state;
1096 struct smb2_request *subreq;
1098 req = tevent_req_create(mem_ctx, &state,
1099 struct rename_one_dir_cycle_state);
1100 if (req == NULL) {
1101 return NULL;
1103 state->ev = ev;
1104 state->tree = tree;
1105 state->file = file;
1106 state->base_name = base_name;
1107 state->rename_counter = rename_counter;
1108 state->current = 0;
1109 state->max = max_renames;
1111 ZERO_STRUCT(state->sinfo);
1112 state->sinfo.rename_information.level =
1113 RAW_SFILEINFO_RENAME_INFORMATION;
1114 state->sinfo.rename_information.in.file.handle = state->file;
1115 state->sinfo.rename_information.in.overwrite = 0;
1116 state->sinfo.rename_information.in.root_fid = 0;
1118 state->new_name = talloc_asprintf(
1119 state, "%s-%u", state->base_name, state->current);
1120 if (tevent_req_nomem(state->new_name, req)) {
1121 return tevent_req_post(req, ev);
1123 state->sinfo.rename_information.in.new_name = state->new_name;
1125 subreq = smb2_setinfo_file_send(state->tree, &state->sinfo);
1126 if (tevent_req_nomem(subreq, req)) {
1127 return tevent_req_post(req, ev);
1129 subreq->async.fn = rename_one_dir_cycle_done;
1130 subreq->async.private_data = req;
1131 return req;
1134 static void rename_one_dir_cycle_done(struct smb2_request *subreq)
1136 struct tevent_req *req = talloc_get_type_abort(
1137 subreq->async.private_data, struct tevent_req);
1138 struct rename_one_dir_cycle_state *state = tevent_req_data(
1139 req, struct rename_one_dir_cycle_state);
1140 NTSTATUS status;
1142 status = smb2_setinfo_recv(subreq);
1143 if (tevent_req_nterror(req, status)) {
1144 return;
1146 TALLOC_FREE(state->new_name);
1148 *state->rename_counter += 1;
1150 state->current += 1;
1151 if (state->current >= state->max) {
1152 tevent_req_done(req);
1153 return;
1156 ZERO_STRUCT(state->sinfo);
1157 state->sinfo.rename_information.level =
1158 RAW_SFILEINFO_RENAME_INFORMATION;
1159 state->sinfo.rename_information.in.file.handle = state->file;
1160 state->sinfo.rename_information.in.overwrite = 0;
1161 state->sinfo.rename_information.in.root_fid = 0;
1163 state->new_name = talloc_asprintf(
1164 state, "%s-%u", state->base_name, state->current);
1165 if (tevent_req_nomem(state->new_name, req)) {
1166 return;
1168 state->sinfo.rename_information.in.new_name = state->new_name;
1170 subreq = smb2_setinfo_file_send(state->tree, &state->sinfo);
1171 if (tevent_req_nomem(subreq, req)) {
1172 return;
1174 subreq->async.fn = rename_one_dir_cycle_done;
1175 subreq->async.private_data = req;
1178 static NTSTATUS rename_one_dir_cycle_recv(struct tevent_req *req)
1180 return tevent_req_simple_recv_ntstatus(req);
1183 struct rename_dir_bench_state {
1184 struct tevent_context *ev;
1185 struct smb2_tree *tree;
1186 const char *base_name;
1187 unsigned max_renames;
1188 unsigned *rename_counter;
1190 struct smb2_create io;
1191 union smb_setfileinfo sinfo;
1192 struct smb2_close cl;
1194 struct smb2_handle file;
1197 static void rename_dir_bench_opened(struct smb2_request *subreq);
1198 static void rename_dir_bench_renamed(struct tevent_req *subreq);
1199 static void rename_dir_bench_set_doc(struct smb2_request *subreq);
1200 static void rename_dir_bench_closed(struct smb2_request *subreq);
1202 static struct tevent_req *rename_dir_bench_send(TALLOC_CTX *mem_ctx,
1203 struct tevent_context *ev,
1204 struct smb2_tree *tree,
1205 const char *base_name,
1206 unsigned max_renames,
1207 unsigned *rename_counter)
1209 struct tevent_req *req;
1210 struct rename_dir_bench_state *state;
1211 struct smb2_request *subreq;
1213 req = tevent_req_create(mem_ctx, &state,
1214 struct rename_dir_bench_state);
1215 if (req == NULL) {
1216 return NULL;
1218 state->ev = ev;
1219 state->tree = tree;
1220 state->base_name = base_name;
1221 state->max_renames = max_renames;
1222 state->rename_counter = rename_counter;
1224 ZERO_STRUCT(state->io);
1225 state->io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1226 state->io.in.share_access =
1227 NTCREATEX_SHARE_ACCESS_READ|
1228 NTCREATEX_SHARE_ACCESS_WRITE;
1229 state->io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1230 state->io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1231 state->io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1232 state->io.in.fname = state->base_name;
1234 subreq = smb2_create_send(state->tree, &state->io);
1235 if (tevent_req_nomem(subreq, req)) {
1236 return tevent_req_post(req, ev);
1238 subreq->async.fn = rename_dir_bench_opened;
1239 subreq->async.private_data = req;
1240 return req;
1243 static void rename_dir_bench_opened(struct smb2_request *subreq)
1245 struct tevent_req *req = talloc_get_type_abort(
1246 subreq->async.private_data, struct tevent_req);
1247 struct rename_dir_bench_state *state = tevent_req_data(
1248 req, struct rename_dir_bench_state);
1249 struct smb2_create *io;
1250 struct tevent_req *subreq2;
1251 NTSTATUS status;
1253 io = talloc(state, struct smb2_create);
1254 if (tevent_req_nomem(io, req)) {
1255 return;
1258 status = smb2_create_recv(subreq, io, io);
1259 if (tevent_req_nterror(req, status)) {
1260 return;
1262 state->file = io->out.file.handle;
1263 TALLOC_FREE(io);
1265 subreq2 = rename_one_dir_cycle_send(
1266 state, state->ev, state->tree, state->file,
1267 state->max_renames, state->base_name,
1268 state->rename_counter);
1269 if (tevent_req_nomem(subreq2, req)) {
1270 return;
1272 tevent_req_set_callback(subreq2, rename_dir_bench_renamed, req);
1275 static void rename_dir_bench_renamed(struct tevent_req *subreq)
1277 struct tevent_req *req = tevent_req_callback_data(
1278 subreq, struct tevent_req);
1279 struct rename_dir_bench_state *state = tevent_req_data(
1280 req, struct rename_dir_bench_state);
1281 struct smb2_request *subreq2;
1282 NTSTATUS status;
1284 status = rename_one_dir_cycle_recv(subreq);
1285 TALLOC_FREE(subreq);
1286 if (tevent_req_nterror(req, status)) {
1287 return;
1290 ZERO_STRUCT(state->sinfo);
1291 state->sinfo.disposition_info.level =
1292 RAW_SFILEINFO_DISPOSITION_INFORMATION;
1293 state->sinfo.disposition_info.in.file.handle = state->file;
1294 state->sinfo.disposition_info.in.delete_on_close = true;
1296 subreq2 = smb2_setinfo_file_send(state->tree, &state->sinfo);
1297 if (tevent_req_nomem(subreq2, req)) {
1298 return;
1300 subreq2->async.fn = rename_dir_bench_set_doc;
1301 subreq2->async.private_data = req;
1304 static void rename_dir_bench_set_doc(struct smb2_request *subreq)
1306 struct tevent_req *req = talloc_get_type_abort(
1307 subreq->async.private_data, struct tevent_req);
1308 struct rename_dir_bench_state *state = tevent_req_data(
1309 req, struct rename_dir_bench_state);
1310 NTSTATUS status;
1312 status = smb2_setinfo_recv(subreq);
1313 if (tevent_req_nterror(req, status)) {
1314 return;
1317 ZERO_STRUCT(state->cl);
1318 state->cl.in.file.handle = state->file;
1320 subreq = smb2_close_send(state->tree, &state->cl);
1321 if (tevent_req_nomem(subreq, req)) {
1322 return;
1324 subreq->async.fn = rename_dir_bench_closed;
1325 subreq->async.private_data = req;
1328 static void rename_dir_bench_closed(struct smb2_request *subreq)
1330 struct tevent_req *req = talloc_get_type_abort(
1331 subreq->async.private_data, struct tevent_req);
1332 struct smb2_close cl;
1333 NTSTATUS status;
1335 status = smb2_close_recv(subreq, &cl);
1336 if (tevent_req_nterror(req, status)) {
1337 return;
1339 tevent_req_done(req);
1342 static NTSTATUS rename_dir_bench_recv(struct tevent_req *req)
1344 return tevent_req_simple_recv_ntstatus(req);
1347 struct rename_dirs_bench_state {
1348 unsigned num_reqs;
1349 unsigned num_done;
1352 static void rename_dirs_bench_done(struct tevent_req *subreq);
1354 static struct tevent_req *rename_dirs_bench_send(TALLOC_CTX *mem_ctx,
1355 struct tevent_context *ev,
1356 struct smb2_tree *tree,
1357 const char *base_name,
1358 unsigned num_parallel,
1359 unsigned max_renames,
1360 unsigned *rename_counter)
1362 struct tevent_req *req;
1363 struct rename_dirs_bench_state *state;
1364 unsigned i;
1366 req = tevent_req_create(mem_ctx, &state,
1367 struct rename_dirs_bench_state);
1368 if (req == NULL) {
1369 return NULL;
1371 state->num_reqs = num_parallel;
1372 state->num_done = 0;
1374 for (i=0; i<num_parallel; i++) {
1375 struct tevent_req *subreq;
1376 char *sub_base;
1378 sub_base = talloc_asprintf(state, "%s-%u", base_name, i);
1379 if (tevent_req_nomem(sub_base, req)) {
1380 return tevent_req_post(req, ev);
1383 subreq = rename_dir_bench_send(state, ev, tree, sub_base,
1384 max_renames, rename_counter);
1385 if (tevent_req_nomem(subreq, req)) {
1386 return tevent_req_post(req, ev);
1388 tevent_req_set_callback(subreq, rename_dirs_bench_done, req);
1390 return req;
1393 static void rename_dirs_bench_done(struct tevent_req *subreq)
1395 struct tevent_req *req = tevent_req_callback_data(
1396 subreq, struct tevent_req);
1397 struct rename_dirs_bench_state *state = tevent_req_data(
1398 req, struct rename_dirs_bench_state);
1399 NTSTATUS status;
1401 status = rename_dir_bench_recv(subreq);
1402 TALLOC_FREE(subreq);
1403 if (tevent_req_nterror(req, status)) {
1404 return;
1407 state->num_done += 1;
1408 if (state->num_done >= state->num_reqs) {
1409 tevent_req_done(req);
1413 static NTSTATUS rename_dirs_bench_recv(struct tevent_req *req)
1415 return tevent_req_simple_recv_ntstatus(req);
1418 static bool torture_smb2_rename_dir_bench(struct torture_context *tctx,
1419 struct smb2_tree *tree)
1421 struct tevent_req *req;
1422 NTSTATUS status;
1423 unsigned counter = 0;
1424 bool ret;
1426 req = rename_dirs_bench_send(tctx, tctx->ev, tree, "dir", 3, 10,
1427 &counter);
1428 torture_assert(tctx, req != NULL, "rename_dirs_bench_send failed");
1430 ret = tevent_req_poll(req, tctx->ev);
1431 torture_assert(tctx, ret, "tevent_req_poll failed");
1433 status = rename_dirs_bench_recv(req);
1434 torture_comment(tctx, "rename_dirs_bench returned %s\n",
1435 nt_errstr(status));
1436 TALLOC_FREE(req);
1437 torture_assert_ntstatus_ok(tctx, status, "bench failed");
1438 return true;
1442 * This test basically verifies that modify and change timestamps are preserved
1443 * after file rename with outstanding open file handles.
1446 static bool torture_smb2_rename_simple_modtime(
1447 struct torture_context *torture,
1448 struct smb2_tree *tree1)
1450 struct smb2_create c1, c2;
1451 union smb_fileinfo gi;
1452 union smb_setfileinfo si;
1453 struct smb2_handle h1 = {{0}};
1454 struct smb2_handle h2 = {{0}};
1455 NTSTATUS status;
1456 bool ret = true;
1458 smb2_deltree(tree1, BASEDIR);
1459 smb2_util_mkdir(tree1, BASEDIR);
1461 torture_comment(torture, "Creating test file: file1.txt\n");
1463 c1 = (struct smb2_create) {
1464 .in.desired_access = SEC_FILE_ALL|SEC_STD_DELETE,
1465 .in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE,
1466 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
1467 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
1468 .in.create_disposition = NTCREATEX_DISP_CREATE,
1469 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
1470 .in.fname = BASEDIR "\\file1.txt",
1473 status = smb2_create(tree1, torture, &c1);
1474 torture_assert_ntstatus_ok_goto(torture, status, ret, done,
1475 "smb2_create failed\n");
1476 h1 = c1.out.file.handle;
1478 torture_comment(torture, "Waitig for 5 secs..\n");
1479 sleep(5);
1481 torture_comment(torture, "Creating test file: file2.txt\n");
1483 c2 = (struct smb2_create) {
1484 .in.desired_access = SEC_FILE_ALL|SEC_STD_DELETE,
1485 .in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE,
1486 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
1487 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
1488 .in.create_disposition = NTCREATEX_DISP_CREATE,
1489 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
1490 .in.fname = BASEDIR "\\file2.txt",
1493 status = smb2_create(tree1, torture, &c2);
1494 torture_assert_ntstatus_ok_goto(torture, status, ret, done,
1495 "smb2_create failed\n");
1496 h2 = c2.out.file.handle;
1498 torture_comment(torture, "Renaming file1.txt --> tmp1.txt\n");
1500 si = (union smb_setfileinfo) {
1501 .rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION,
1502 .rename_information.in.file.handle = h1,
1503 .rename_information.in.new_name =
1504 BASEDIR "\\tmp1.txt",
1507 status = smb2_setinfo_file(tree1, &si);
1508 torture_assert_ntstatus_ok_goto(torture, status, ret, done,
1509 "smb2_setinfo_file failed\n");
1511 torture_comment(torture, "GetInfo of tmp1.txt\n");
1513 gi = (union smb_fileinfo) {
1514 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
1515 .generic.in.file.handle = h1,
1518 status = smb2_getinfo_file(tree1, torture, &gi);
1519 torture_assert_ntstatus_ok_goto(torture, status, ret, done,
1520 "smb2_getinfo_file failed\n");
1522 torture_comment(torture, "Check if timestamps are good after rename(file1.txt --> tmp1.txt).\n");
1524 torture_assert_nttime_equal(
1525 torture, c1.out.write_time, gi.all_info.out.write_time,
1526 "Bad timestamp\n");
1527 torture_assert_nttime_equal(
1528 torture, c1.out.change_time, gi.all_info.out.change_time,
1529 "Bad timestamp\n");
1531 torture_comment(torture, "Renaming file2.txt --> file1.txt\n");
1533 si = (union smb_setfileinfo) {
1534 .rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION,
1535 .rename_information.in.file.handle = h2,
1536 .rename_information.in.new_name =
1537 BASEDIR "\\file1.txt",
1539 status = smb2_setinfo_file(tree1, &si);
1540 torture_assert_ntstatus_ok_goto(torture, status, ret, done,
1541 "smb2_setinfo_file failed\n");
1543 torture_comment(torture, "GetInfo of file1.txt\n");
1545 gi = (union smb_fileinfo) {
1546 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
1547 .generic.in.file.handle = h2,
1550 status = smb2_getinfo_file(tree1, torture, &gi);
1551 torture_assert_ntstatus_ok_goto(torture, status, ret, done,
1552 "smb2_getinfo_file failed\n");
1554 torture_comment(torture, "Check if timestamps are good after rename(file2.txt --> file1.txt).\n");
1556 torture_assert_nttime_equal(
1557 torture, c2.out.write_time, gi.all_info.out.write_time,
1558 "Bad timestamp\n");
1559 torture_assert_nttime_equal(
1560 torture, c2.out.change_time, gi.all_info.out.change_time,
1561 "Bad timestamp\n");
1563 done:
1564 if (!smb2_util_handle_empty(h1)) {
1565 smb2_util_close(tree1, h1);
1567 if (!smb2_util_handle_empty(h2)) {
1568 smb2_util_close(tree1, h2);
1570 smb2_deltree(tree1, BASEDIR);
1571 return ret;
1574 static bool test_smb2_close_full_information(struct torture_context *torture,
1575 struct smb2_tree *tree1,
1576 struct smb2_tree *tree2)
1578 union smb_close cl;
1579 struct smb2_create io = {0};
1580 struct smb2_handle h1 = {{0}};
1581 struct smb2_handle h2 = {{0}};
1582 struct smb2_handle h3 = {{0}};
1583 union smb_setfileinfo sinfo;
1584 NTSTATUS status;
1585 const char *fname_src = "request.dat";
1586 const char *fname_dst = "renamed.dat";
1587 bool ret = true;
1589 /* Start with a tidy share. */
1590 smb2_util_unlink(tree1, fname_src);
1591 smb2_util_unlink(tree1, fname_dst);
1593 /* Create the test file, and leave it open. */
1594 io.in.fname = fname_src;
1595 io.in.desired_access = SEC_FILE_READ_DATA | SEC_FILE_READ_ATTRIBUTE;
1596 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1597 io.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1598 NTCREATEX_SHARE_ACCESS_WRITE |
1599 NTCREATEX_SHARE_ACCESS_DELETE;
1600 status = smb2_create(tree1, tree1, &io);
1601 CHECK_STATUS(status, NT_STATUS_OK);
1602 h1 = io.out.file.handle;
1603 CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1605 /* Open the test file on the second connection. */
1606 ZERO_STRUCT(io);
1607 io.in.fname = fname_src;
1608 io.in.desired_access = SEC_FILE_READ_DATA | SEC_FILE_READ_ATTRIBUTE;
1609 io.in.create_disposition = NTCREATEX_DISP_OPEN;
1610 io.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1611 NTCREATEX_SHARE_ACCESS_WRITE |
1612 NTCREATEX_SHARE_ACCESS_DELETE;
1613 status = smb2_create(tree2, tree2, &io);
1614 CHECK_STATUS(status, NT_STATUS_OK);
1615 h2 = io.out.file.handle;
1617 /* Now open for rename on the first connection. */
1618 ZERO_STRUCT(io);
1619 io.in.fname = fname_src;
1620 io.in.desired_access = SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE;
1621 io.in.create_disposition = NTCREATEX_DISP_OPEN;
1622 io.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1623 NTCREATEX_SHARE_ACCESS_WRITE |
1624 NTCREATEX_SHARE_ACCESS_DELETE;
1625 status = smb2_create(tree1, tree1, &io);
1626 CHECK_STATUS(status, NT_STATUS_OK);
1627 h3 = io.out.file.handle;
1629 /* Do the rename. */
1630 ZERO_STRUCT(sinfo);
1631 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
1632 sinfo.rename_information.in.file.handle = h3;
1633 sinfo.rename_information.in.new_name = fname_dst;
1634 status = smb2_setinfo_file(tree1, &sinfo);
1635 CHECK_STATUS(status, NT_STATUS_OK);
1637 /* And close h3. */
1638 ZERO_STRUCT(cl.smb2);
1639 cl.smb2.level = RAW_CLOSE_SMB2;
1640 cl.smb2.in.file.handle = h3;
1641 status = smb2_close(tree1, &cl.smb2);
1642 CHECK_STATUS(status, NT_STATUS_OK);
1643 ZERO_STRUCT(h3);
1646 * Close h1 with SMB2_CLOSE_FLAGS_FULL_INFORMATION.
1647 * Ensure we get data.
1649 ZERO_STRUCT(cl.smb2);
1650 cl.smb2.level = RAW_CLOSE_SMB2;
1651 cl.smb2.in.file.handle = h1;
1652 cl.smb2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION;
1653 status = smb2_close(tree1, &cl.smb2);
1654 CHECK_STATUS(status, NT_STATUS_OK);
1655 ZERO_STRUCT(h1);
1656 CHECK_VAL(cl.smb2.out.file_attr, 0x20);
1659 * Wait 3 seconds for name change to propagate
1660 * to the other connection.
1662 sleep(3);
1665 * Close h2 with SMB2_CLOSE_FLAGS_FULL_INFORMATION.
1666 * This is on connection2.
1667 * Ensure we get data.
1669 ZERO_STRUCT(cl.smb2);
1670 cl.smb2.level = RAW_CLOSE_SMB2;
1671 cl.smb2.in.file.handle = h2;
1672 cl.smb2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION;
1673 status = smb2_close(tree2, &cl.smb2);
1674 CHECK_STATUS(status, NT_STATUS_OK);
1675 ZERO_STRUCT(h2);
1676 CHECK_VAL(cl.smb2.out.file_attr, 0x20);
1678 done:
1680 if (h1.data[0] != 0 || h1.data[1] != 0) {
1681 smb2_util_close(tree1, h1);
1683 if (h2.data[0] != 0 || h2.data[1] != 0) {
1684 smb2_util_close(tree2, h2);
1686 if (h3.data[0] != 0 || h3.data[1] != 0) {
1687 smb2_util_close(tree1, h3);
1690 smb2_util_unlink(tree1, fname_src);
1691 smb2_util_unlink(tree1, fname_dst);
1693 return ret;
1696 static bool torture_smb2_rename_open(struct torture_context *torture,
1697 struct smb2_tree *tree1,
1698 struct smb2_tree *tree2)
1700 struct smb2_create c1 = {};
1701 struct smb2_create c2 = {};
1702 union smb_setfileinfo sinfo = {};
1703 struct smb2_handle h1 = {};
1704 struct smb2_handle h2 = {};
1705 NTSTATUS status;
1706 bool ret = true;
1708 smb2_deltree(tree1, BASEDIR);
1709 smb2_util_mkdir(tree1, BASEDIR);
1711 /* Create testfile */
1713 c1.in.desired_access = SEC_STD_DELETE;
1714 c1.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
1715 c1.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1716 c1.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1717 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
1718 c1.in.create_disposition = NTCREATEX_DISP_CREATE;
1719 c1.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1720 c1.in.fname = BASEDIR "\\file.txt";
1722 status = smb2_create(tree1, torture, &c1);
1723 torture_assert_ntstatus_ok_goto(torture, status, ret, done,
1724 "smb2_create failed\n");
1725 h1 = c1.out.file.handle;
1727 /* 2nd open on testfile */
1729 c2.in.desired_access = SEC_FILE_READ_DATA;
1730 c2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
1731 c2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1732 c2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1733 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
1734 c2.in.create_disposition = NTCREATEX_DISP_OPEN;
1735 c2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1736 c2.in.fname = BASEDIR "\\file.txt";
1738 status = smb2_create(tree2, torture, &c2);
1739 torture_assert_ntstatus_ok_goto(torture, status, ret, done,
1740 "smb2_create failed\n");
1741 h2 = c2.out.file.handle;
1743 torture_comment(torture, "Renaming test file\n");
1745 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
1746 sinfo.rename_information.in.file.handle = h1;
1747 sinfo.rename_information.in.new_name =
1748 BASEDIR "\\newname.txt";
1749 status = smb2_setinfo_file(tree1, &sinfo);
1750 torture_assert_ntstatus_ok_goto(torture, status, ret, done,
1751 "Rename failed\n");
1753 done:
1754 if (!smb2_util_handle_empty(h1)) {
1755 smb2_util_close(tree1, h1);
1757 if (!smb2_util_handle_empty(h2)) {
1758 smb2_util_close(tree2, h2);
1760 smb2_deltree(tree1, BASEDIR);
1761 return ret;
1765 basic testing of SMB2 rename
1767 struct torture_suite *torture_smb2_rename_init(TALLOC_CTX *ctx)
1769 struct torture_suite *suite =
1770 torture_suite_create(ctx, "rename");
1772 torture_suite_add_1smb2_test(suite, "simple",
1773 torture_smb2_rename_simple);
1775 torture_suite_add_1smb2_test(suite, "simple_modtime",
1776 torture_smb2_rename_simple_modtime);
1778 torture_suite_add_1smb2_test(suite, "simple_nodelete",
1779 torture_smb2_rename_simple2);
1781 torture_suite_add_1smb2_test(suite, "no_sharing",
1782 torture_smb2_rename_no_sharemode);
1784 torture_suite_add_1smb2_test(suite,
1785 "share_delete_and_delete_access",
1786 torture_smb2_rename_with_delete_access);
1788 torture_suite_add_1smb2_test(suite,
1789 "no_share_delete_but_delete_access",
1790 torture_smb2_rename_with_delete_access2);
1792 torture_suite_add_1smb2_test(suite,
1793 "share_delete_no_delete_access",
1794 torture_smb2_rename_no_delete_access);
1796 torture_suite_add_1smb2_test(suite,
1797 "no_share_delete_no_delete_access",
1798 torture_smb2_rename_no_delete_access2);
1800 torture_suite_add_1smb2_test(suite,
1801 "msword",
1802 torture_smb2_rename_msword);
1804 torture_suite_add_1smb2_test(
1805 suite, "rename_dir_openfile",
1806 torture_smb2_rename_dir_openfile);
1808 torture_suite_add_1smb2_test(suite,
1809 "rename_dir_bench",
1810 torture_smb2_rename_dir_bench);
1812 torture_suite_add_2smb2_test(suite,
1813 "close-full-information",
1814 test_smb2_close_full_information);
1816 torture_suite_add_2smb2_test(suite,
1817 "rename-open",
1818 torture_smb2_rename_open);
1820 suite->description = talloc_strdup(suite, "smb2.rename tests");
1822 return suite;