torture: Add smb2.rename.rename_dir_bench
[Samba.git] / source4 / torture / smb2 / rename.c
blob9d0f4e18731630ed8968a84d09589c47f021b8c6
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 "lib/tevent/tevent.h"
26 #include "lib/util/tevent_ntstatus.h"
28 #include "torture/torture.h"
29 #include "torture/smb2/proto.h"
31 #include "librpc/gen_ndr/security.h"
33 #define CHECK_STATUS(status, correct) do { \
34 if (!NT_STATUS_EQUAL(status, correct)) { \
35 torture_result(torture, TORTURE_FAIL, \
36 "(%s) Incorrect status %s - should be %s\n", \
37 __location__, nt_errstr(status), nt_errstr(correct)); \
38 ret = false; \
39 goto done; \
40 }} while (0)
42 #define BASEDIR "test_rename"
45 * basic testing of rename: open file with DELETE access
46 * this should pass
49 static bool torture_smb2_rename_simple(struct torture_context *torture,
50 struct smb2_tree *tree1)
52 bool ret = true;
53 NTSTATUS status;
54 union smb_open io;
55 union smb_close cl;
56 union smb_setfileinfo sinfo;
57 union smb_fileinfo fi;
58 struct smb2_handle h1;
60 smb2_deltree(tree1, BASEDIR);
61 smb2_util_rmdir(tree1, BASEDIR);
63 torture_comment(torture, "Creating base directory\n");
65 smb2_util_mkdir(tree1, BASEDIR);
68 torture_comment(torture, "Creating test file\n");
70 ZERO_STRUCT(io.smb2);
71 io.generic.level = RAW_OPEN_SMB2;
72 io.smb2.in.create_flags = 0;
73 io.smb2.in.desired_access = SEC_FILE_ALL|SEC_STD_DELETE;
74 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
75 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
76 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
77 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
78 io.smb2.in.alloc_size = 0;
79 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
80 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
81 io.smb2.in.security_flags = 0;
82 io.smb2.in.fname = BASEDIR "\\file.txt";
84 status = smb2_create(tree1, torture, &(io.smb2));
85 CHECK_STATUS(status, NT_STATUS_OK);
86 h1 = io.smb2.out.file.handle;
88 torture_comment(torture, "Renaming test file\n");
90 ZERO_STRUCT(sinfo);
91 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
92 sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
93 sinfo.rename_information.in.overwrite = 0;
94 sinfo.rename_information.in.root_fid = 0;
95 sinfo.rename_information.in.new_name =
96 BASEDIR "\\newname.txt";
97 status = smb2_setinfo_file(tree1, &sinfo);
98 CHECK_STATUS(status, NT_STATUS_OK);
100 torture_comment(torture, "Checking for new filename\n");
102 ZERO_STRUCT(fi);
103 fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
104 fi.generic.in.file.handle = h1;
105 status = smb2_getinfo_file(tree1, torture, &fi);
106 CHECK_STATUS(status, NT_STATUS_OK);
109 torture_comment(torture, "Closing test file\n");
111 ZERO_STRUCT(cl.smb2);
112 cl.smb2.level = RAW_CLOSE_SMB2;
113 cl.smb2.in.file.handle = h1;
114 status = smb2_close(tree1, &(cl.smb2));
115 CHECK_STATUS(status, NT_STATUS_OK);
117 ZERO_STRUCT(h1);
119 done:
121 torture_comment(torture, "Cleaning up\n");
123 if (h1.data) {
124 ZERO_STRUCT(cl.smb2);
125 cl.smb2.level = RAW_CLOSE_SMB2;
126 cl.smb2.in.file.handle = h1;
127 status = smb2_close(tree1, &(cl.smb2));
129 smb2_deltree(tree1, BASEDIR);
130 return ret;
134 * basic testing of rename, this time do not request DELETE access
135 * for the file, this should fail
138 static bool torture_smb2_rename_simple2(struct torture_context *torture,
139 struct smb2_tree *tree1)
141 bool ret = true;
142 NTSTATUS status;
143 union smb_open io;
144 union smb_close cl;
145 union smb_setfileinfo sinfo;
146 struct smb2_handle h1;
148 smb2_deltree(tree1, BASEDIR);
149 smb2_util_rmdir(tree1, BASEDIR);
151 torture_comment(torture, "Creating base directory\n");
153 smb2_util_mkdir(tree1, BASEDIR);
156 torture_comment(torture, "Creating test file\n");
158 ZERO_STRUCT(io.smb2);
159 io.generic.level = RAW_OPEN_SMB2;
160 io.smb2.in.create_flags = 0;
161 io.smb2.in.desired_access = SEC_FILE_ALL;
162 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
163 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
164 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
165 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
166 io.smb2.in.alloc_size = 0;
167 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
168 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
169 io.smb2.in.security_flags = 0;
170 io.smb2.in.fname = BASEDIR "\\file.txt";
172 status = smb2_create(tree1, torture, &(io.smb2));
173 CHECK_STATUS(status, NT_STATUS_OK);
174 h1 = io.smb2.out.file.handle;
176 torture_comment(torture, "Renaming test file\n");
178 ZERO_STRUCT(sinfo);
179 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
180 sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
181 sinfo.rename_information.in.overwrite = 0;
182 sinfo.rename_information.in.root_fid = 0;
183 sinfo.rename_information.in.new_name =
184 BASEDIR "\\newname.txt";
185 status = smb2_setinfo_file(tree1, &sinfo);
186 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
188 torture_comment(torture, "Closing test file\n");
190 ZERO_STRUCT(cl.smb2);
191 cl.smb2.level = RAW_CLOSE_SMB2;
192 cl.smb2.in.file.handle = h1;
193 status = smb2_close(tree1, &(cl.smb2));
194 CHECK_STATUS(status, NT_STATUS_OK);
196 ZERO_STRUCT(h1);
198 done:
200 torture_comment(torture, "Cleaning up\n");
202 if (h1.data) {
203 ZERO_STRUCT(cl.smb2);
204 cl.smb2.level = RAW_CLOSE_SMB2;
205 cl.smb2.in.file.handle = h1;
206 status = smb2_close(tree1, &(cl.smb2));
208 smb2_deltree(tree1, BASEDIR);
209 return ret;
214 * testing of rename with no sharing allowed on file
215 * this should work
218 static bool torture_smb2_rename_no_sharemode(struct torture_context *torture,
219 struct smb2_tree *tree1)
221 bool ret = true;
222 NTSTATUS status;
223 union smb_open io;
224 union smb_close cl;
225 union smb_setfileinfo sinfo;
226 union smb_fileinfo fi;
227 struct smb2_handle h1;
229 smb2_deltree(tree1, BASEDIR);
230 smb2_util_rmdir(tree1, BASEDIR);
232 torture_comment(torture, "Creating base directory\n");
234 smb2_util_mkdir(tree1, BASEDIR);
237 torture_comment(torture, "Creating test file\n");
239 ZERO_STRUCT(io.smb2);
240 io.generic.level = RAW_OPEN_SMB2;
241 io.smb2.in.create_flags = 0;
242 io.smb2.in.desired_access = 0x0017019f;
243 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
244 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
245 io.smb2.in.share_access = 0;
246 io.smb2.in.alloc_size = 0;
247 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
248 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
249 io.smb2.in.security_flags = 0;
250 io.smb2.in.fname = BASEDIR "\\file.txt";
252 status = smb2_create(tree1, torture, &(io.smb2));
253 CHECK_STATUS(status, NT_STATUS_OK);
254 h1 = io.smb2.out.file.handle;
256 torture_comment(torture, "Renaming test file\n");
258 ZERO_STRUCT(sinfo);
259 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
260 sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
261 sinfo.rename_information.in.overwrite = 0;
262 sinfo.rename_information.in.root_fid = 0;
263 sinfo.rename_information.in.new_name =
264 BASEDIR "\\newname.txt";
265 status = smb2_setinfo_file(tree1, &sinfo);
266 CHECK_STATUS(status, NT_STATUS_OK);
268 torture_comment(torture, "Checking for new filename\n");
270 ZERO_STRUCT(fi);
271 fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
272 fi.generic.in.file.handle = h1;
273 status = smb2_getinfo_file(tree1, torture, &fi);
274 CHECK_STATUS(status, NT_STATUS_OK);
277 torture_comment(torture, "Closing test file\n");
279 ZERO_STRUCT(cl.smb2);
280 cl.smb2.level = RAW_CLOSE_SMB2;
281 cl.smb2.in.file.handle = h1;
282 status = smb2_close(tree1, &(cl.smb2));
283 CHECK_STATUS(status, NT_STATUS_OK);
285 ZERO_STRUCT(h1);
287 done:
289 torture_comment(torture, "Cleaning up\n");
291 if (h1.data) {
292 ZERO_STRUCT(cl.smb2);
293 cl.smb2.level = RAW_CLOSE_SMB2;
294 cl.smb2.in.file.handle = h1;
295 status = smb2_close(tree1, &(cl.smb2));
297 smb2_deltree(tree1, BASEDIR);
298 return ret;
302 * testing of rename when opening parent dir with delete access and delete
303 * sharing allowed
304 * should result in sharing violation
307 static bool torture_smb2_rename_with_delete_access(struct torture_context *torture,
308 struct smb2_tree *tree1)
310 bool ret = true;
311 NTSTATUS status;
312 union smb_open io;
313 union smb_close cl;
314 union smb_setfileinfo sinfo;
315 struct smb2_handle fh, dh;
317 smb2_deltree(tree1, BASEDIR);
318 smb2_util_rmdir(tree1, BASEDIR);
320 torture_comment(torture, "Creating base directory\n");
322 smb2_util_mkdir(tree1, BASEDIR);
324 torture_comment(torture, "Opening parent directory\n");
326 ZERO_STRUCT(io.smb2);
327 io.generic.level = RAW_OPEN_SMB2;
328 io.smb2.in.create_flags = 0;
329 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
330 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
331 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
332 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
333 SEC_FILE_WRITE_DATA;
334 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
335 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
336 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
337 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
338 io.smb2.in.alloc_size = 0;
339 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
340 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
341 io.smb2.in.security_flags = 0;
342 io.smb2.in.fname = BASEDIR;
344 status = smb2_create(tree1, torture, &(io.smb2));
345 CHECK_STATUS(status, NT_STATUS_OK);
346 dh = io.smb2.out.file.handle;
349 torture_comment(torture, "Creating test file\n");
351 ZERO_STRUCT(io.smb2);
352 io.generic.level = RAW_OPEN_SMB2;
353 io.smb2.in.create_flags = 0;
354 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
355 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
356 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
357 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
358 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
359 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
360 io.smb2.in.share_access = 0;
361 io.smb2.in.alloc_size = 0;
362 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
363 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
364 io.smb2.in.security_flags = 0;
365 io.smb2.in.fname = BASEDIR "\\file.txt";
367 status = smb2_create(tree1, torture, &(io.smb2));
368 CHECK_STATUS(status, NT_STATUS_OK);
369 fh = io.smb2.out.file.handle;
371 torture_comment(torture, "Renaming test file\n");
373 ZERO_STRUCT(sinfo);
374 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
375 sinfo.rename_information.in.file.handle = fh;
376 sinfo.rename_information.in.overwrite = 0;
377 sinfo.rename_information.in.root_fid = 0;
378 sinfo.rename_information.in.new_name =
379 BASEDIR "\\newname.txt";
380 status = smb2_setinfo_file(tree1, &sinfo);
381 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
383 torture_comment(torture, "Closing test file\n");
385 ZERO_STRUCT(cl.smb2);
386 cl.smb2.level = RAW_CLOSE_SMB2;
387 cl.smb2.in.file.handle = fh;
388 status = smb2_close(tree1, &(cl.smb2));
389 CHECK_STATUS(status, NT_STATUS_OK);
391 ZERO_STRUCT(fh);
393 torture_comment(torture, "Closing directory\n");
395 ZERO_STRUCT(cl.smb2);
396 cl.smb2.level = RAW_CLOSE_SMB2;
397 cl.smb2.in.file.handle = dh;
398 status = smb2_close(tree1, &(cl.smb2));
399 CHECK_STATUS(status, NT_STATUS_OK);
401 ZERO_STRUCT(dh);
404 done:
406 torture_comment(torture, "Cleaning up\n");
408 if (fh.data) {
409 ZERO_STRUCT(cl.smb2);
410 cl.smb2.level = RAW_CLOSE_SMB2;
411 cl.smb2.in.file.handle = fh;
412 status = smb2_close(tree1, &(cl.smb2));
414 if (dh.data) {
415 ZERO_STRUCT(cl.smb2);
416 cl.smb2.level = RAW_CLOSE_SMB2;
417 cl.smb2.in.file.handle = dh;
418 status = smb2_close(tree1, &(cl.smb2));
421 smb2_deltree(tree1, BASEDIR);
422 return ret;
427 * testing of rename with delete access on parent dir
428 * this is a variation of the test above: parent dir is opened
429 * without share_delete, so rename must fail
432 static bool torture_smb2_rename_with_delete_access2(struct torture_context *torture,
433 struct smb2_tree *tree1)
435 bool ret = true;
436 NTSTATUS status;
437 union smb_open io;
438 union smb_close cl;
439 union smb_setfileinfo sinfo;
440 struct smb2_handle fh, dh;
442 smb2_deltree(tree1, BASEDIR);
443 smb2_util_rmdir(tree1, BASEDIR);
445 torture_comment(torture, "Creating base directory\n");
447 smb2_util_mkdir(tree1, BASEDIR);
449 torture_comment(torture, "Opening parent directory\n");
451 ZERO_STRUCT(io.smb2);
452 io.generic.level = RAW_OPEN_SMB2;
453 io.smb2.in.create_flags = 0;
454 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
455 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
456 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
457 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
458 SEC_FILE_WRITE_DATA;
459 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
460 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
461 io.smb2.in.share_access = 0;
462 io.smb2.in.alloc_size = 0;
463 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
464 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
465 io.smb2.in.security_flags = 0;
466 io.smb2.in.fname = BASEDIR;
468 status = smb2_create(tree1, torture, &(io.smb2));
469 CHECK_STATUS(status, NT_STATUS_OK);
470 dh = io.smb2.out.file.handle;
473 torture_comment(torture, "Creating test file\n");
475 ZERO_STRUCT(io.smb2);
476 io.generic.level = RAW_OPEN_SMB2;
477 io.smb2.in.create_flags = 0;
478 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
479 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
480 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
481 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
482 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
483 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
484 io.smb2.in.share_access = 0;
485 io.smb2.in.alloc_size = 0;
486 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
487 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
488 io.smb2.in.security_flags = 0;
489 io.smb2.in.fname = BASEDIR "\\file.txt";
491 status = smb2_create(tree1, torture, &(io.smb2));
492 CHECK_STATUS(status, NT_STATUS_OK);
493 fh = io.smb2.out.file.handle;
495 torture_comment(torture, "Renaming test file\n");
497 ZERO_STRUCT(sinfo);
498 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
499 sinfo.rename_information.in.file.handle = fh;
500 sinfo.rename_information.in.overwrite = 0;
501 sinfo.rename_information.in.root_fid = 0;
502 sinfo.rename_information.in.new_name =
503 BASEDIR "\\newname.txt";
504 status = smb2_setinfo_file(tree1, &sinfo);
505 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
507 torture_comment(torture, "Closing test file\n");
509 ZERO_STRUCT(cl.smb2);
510 cl.smb2.level = RAW_CLOSE_SMB2;
511 cl.smb2.in.file.handle = fh;
512 status = smb2_close(tree1, &(cl.smb2));
513 CHECK_STATUS(status, NT_STATUS_OK);
515 ZERO_STRUCT(fh);
517 torture_comment(torture, "Closing directory\n");
519 ZERO_STRUCT(cl.smb2);
520 cl.smb2.level = RAW_CLOSE_SMB2;
521 cl.smb2.in.file.handle = dh;
522 status = smb2_close(tree1, &(cl.smb2));
523 CHECK_STATUS(status, NT_STATUS_OK);
525 ZERO_STRUCT(dh);
528 done:
530 torture_comment(torture, "Cleaning up\n");
532 if (fh.data) {
533 ZERO_STRUCT(cl.smb2);
534 cl.smb2.level = RAW_CLOSE_SMB2;
535 cl.smb2.in.file.handle = fh;
536 status = smb2_close(tree1, &(cl.smb2));
538 if (dh.data) {
539 ZERO_STRUCT(cl.smb2);
540 cl.smb2.level = RAW_CLOSE_SMB2;
541 cl.smb2.in.file.handle = dh;
542 status = smb2_close(tree1, &(cl.smb2));
545 smb2_deltree(tree1, BASEDIR);
546 return ret;
550 * testing of rename when opening parent dir with no delete access and delete
551 * sharing allowed
552 * this should pass
555 static bool torture_smb2_rename_no_delete_access(struct torture_context *torture,
556 struct smb2_tree *tree1)
558 bool ret = true;
559 NTSTATUS status;
560 union smb_open io;
561 union smb_close cl;
562 union smb_setfileinfo sinfo;
563 union smb_fileinfo fi;
564 struct smb2_handle fh, dh;
566 smb2_deltree(tree1, BASEDIR);
567 smb2_util_rmdir(tree1, BASEDIR);
569 torture_comment(torture, "Creating base directory\n");
571 smb2_util_mkdir(tree1, BASEDIR);
573 torture_comment(torture, "Opening parent directory\n");
575 ZERO_STRUCT(io.smb2);
576 io.generic.level = RAW_OPEN_SMB2;
577 io.smb2.in.create_flags = 0;
578 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
579 SEC_STD_READ_CONTROL | SEC_FILE_WRITE_ATTRIBUTE |
580 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
581 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
582 SEC_FILE_WRITE_DATA;
583 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
584 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
585 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
586 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
587 io.smb2.in.alloc_size = 0;
588 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
589 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
590 io.smb2.in.security_flags = 0;
591 io.smb2.in.fname = BASEDIR;
593 status = smb2_create(tree1, torture, &(io.smb2));
594 CHECK_STATUS(status, NT_STATUS_OK);
595 dh = io.smb2.out.file.handle;
598 torture_comment(torture, "Creating test file\n");
600 ZERO_STRUCT(io.smb2);
601 io.generic.level = RAW_OPEN_SMB2;
602 io.smb2.in.create_flags = 0;
603 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
604 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
605 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
606 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
607 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
608 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
609 io.smb2.in.share_access = 0;
610 io.smb2.in.alloc_size = 0;
611 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
612 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
613 io.smb2.in.security_flags = 0;
614 io.smb2.in.fname = BASEDIR "\\file.txt";
616 status = smb2_create(tree1, torture, &(io.smb2));
617 CHECK_STATUS(status, NT_STATUS_OK);
618 fh = io.smb2.out.file.handle;
620 torture_comment(torture, "Renaming test file\n");
622 ZERO_STRUCT(sinfo);
623 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
624 sinfo.rename_information.in.file.handle = fh;
625 sinfo.rename_information.in.overwrite = 0;
626 sinfo.rename_information.in.root_fid = 0;
627 sinfo.rename_information.in.new_name =
628 BASEDIR "\\newname.txt";
629 status = smb2_setinfo_file(tree1, &sinfo);
630 CHECK_STATUS(status, NT_STATUS_OK);
632 torture_comment(torture, "Checking for new filename\n");
634 ZERO_STRUCT(fi);
635 fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
636 fi.generic.in.file.handle = fh;
637 status = smb2_getinfo_file(tree1, torture, &fi);
638 CHECK_STATUS(status, NT_STATUS_OK);
641 torture_comment(torture, "Closing test file\n");
643 ZERO_STRUCT(cl.smb2);
644 cl.smb2.level = RAW_CLOSE_SMB2;
645 cl.smb2.in.file.handle = fh;
646 status = smb2_close(tree1, &(cl.smb2));
647 CHECK_STATUS(status, NT_STATUS_OK);
649 ZERO_STRUCT(fh);
651 torture_comment(torture, "Closing directory\n");
653 ZERO_STRUCT(cl.smb2);
654 cl.smb2.level = RAW_CLOSE_SMB2;
655 cl.smb2.in.file.handle = dh;
656 status = smb2_close(tree1, &(cl.smb2));
657 CHECK_STATUS(status, NT_STATUS_OK);
659 ZERO_STRUCT(dh);
662 done:
664 torture_comment(torture, "Cleaning up\n");
666 if (fh.data) {
667 ZERO_STRUCT(cl.smb2);
668 cl.smb2.level = RAW_CLOSE_SMB2;
669 cl.smb2.in.file.handle = fh;
670 status = smb2_close(tree1, &(cl.smb2));
672 if (dh.data) {
673 ZERO_STRUCT(cl.smb2);
674 cl.smb2.level = RAW_CLOSE_SMB2;
675 cl.smb2.in.file.handle = dh;
676 status = smb2_close(tree1, &(cl.smb2));
679 smb2_deltree(tree1, BASEDIR);
680 return ret;
685 * testing of rename with no delete access on parent dir
686 * this is the negative case of the test above: parent dir is opened
687 * without share_delete, so rename must fail
690 static bool torture_smb2_rename_no_delete_access2(struct torture_context *torture,
691 struct smb2_tree *tree1)
693 bool ret = true;
694 NTSTATUS status;
695 union smb_open io;
696 union smb_close cl;
697 union smb_setfileinfo sinfo;
698 struct smb2_handle fh, dh;
700 smb2_deltree(tree1, BASEDIR);
701 smb2_util_rmdir(tree1, BASEDIR);
703 torture_comment(torture, "Creating base directory\n");
705 smb2_util_mkdir(tree1, BASEDIR);
707 torture_comment(torture, "Opening parent directory\n");
709 ZERO_STRUCT(io.smb2);
710 io.generic.level = RAW_OPEN_SMB2;
711 io.smb2.in.create_flags = 0;
712 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
713 SEC_STD_READ_CONTROL | SEC_FILE_WRITE_ATTRIBUTE |
714 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
715 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
716 SEC_FILE_WRITE_DATA;
717 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
718 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
719 io.smb2.in.share_access = 0;
720 io.smb2.in.alloc_size = 0;
721 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
722 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
723 io.smb2.in.security_flags = 0;
724 io.smb2.in.fname = BASEDIR;
726 status = smb2_create(tree1, torture, &(io.smb2));
727 CHECK_STATUS(status, NT_STATUS_OK);
728 dh = io.smb2.out.file.handle;
731 torture_comment(torture, "Creating test file\n");
733 ZERO_STRUCT(io.smb2);
734 io.generic.level = RAW_OPEN_SMB2;
735 io.smb2.in.create_flags = 0;
736 io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
737 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
738 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
739 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
740 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
741 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
742 io.smb2.in.share_access = 0;
743 io.smb2.in.alloc_size = 0;
744 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
745 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
746 io.smb2.in.security_flags = 0;
747 io.smb2.in.fname = BASEDIR "\\file.txt";
749 status = smb2_create(tree1, torture, &(io.smb2));
750 CHECK_STATUS(status, NT_STATUS_OK);
751 fh = io.smb2.out.file.handle;
753 torture_comment(torture, "Renaming test file\n");
755 ZERO_STRUCT(sinfo);
756 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
757 sinfo.rename_information.in.file.handle = fh;
758 sinfo.rename_information.in.overwrite = 0;
759 sinfo.rename_information.in.root_fid = 0;
760 sinfo.rename_information.in.new_name =
761 BASEDIR "\\newname.txt";
762 status = smb2_setinfo_file(tree1, &sinfo);
763 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
765 torture_comment(torture, "Closing test file\n");
767 ZERO_STRUCT(cl.smb2);
768 cl.smb2.level = RAW_CLOSE_SMB2;
769 cl.smb2.in.file.handle = fh;
770 status = smb2_close(tree1, &(cl.smb2));
771 CHECK_STATUS(status, NT_STATUS_OK);
773 ZERO_STRUCT(fh);
775 torture_comment(torture, "Closing directory\n");
777 ZERO_STRUCT(cl.smb2);
778 cl.smb2.level = RAW_CLOSE_SMB2;
779 cl.smb2.in.file.handle = dh;
780 status = smb2_close(tree1, &(cl.smb2));
781 CHECK_STATUS(status, NT_STATUS_OK);
783 ZERO_STRUCT(dh);
786 done:
788 torture_comment(torture, "Cleaning up\n");
790 if (fh.data) {
791 ZERO_STRUCT(cl.smb2);
792 cl.smb2.level = RAW_CLOSE_SMB2;
793 cl.smb2.in.file.handle = fh;
794 status = smb2_close(tree1, &(cl.smb2));
796 if (dh.data) {
797 ZERO_STRUCT(cl.smb2);
798 cl.smb2.level = RAW_CLOSE_SMB2;
799 cl.smb2.in.file.handle = dh;
800 status = smb2_close(tree1, &(cl.smb2));
803 smb2_deltree(tree1, BASEDIR);
804 return ret;
808 * this is a replay of how Word 2010 saves a file
809 * this should pass
812 static bool torture_smb2_rename_msword(struct torture_context *torture,
813 struct smb2_tree *tree1)
815 bool ret = true;
816 NTSTATUS status;
817 union smb_open io;
818 union smb_close cl;
819 union smb_setfileinfo sinfo;
820 union smb_fileinfo fi;
821 struct smb2_handle fh, dh;
823 smb2_deltree(tree1, BASEDIR);
824 smb2_util_rmdir(tree1, BASEDIR);
826 torture_comment(torture, "Creating base directory\n");
828 smb2_util_mkdir(tree1, BASEDIR);
830 torture_comment(torture, "Creating test file\n");
832 ZERO_STRUCT(io.smb2);
833 io.generic.level = RAW_OPEN_SMB2;
834 io.smb2.in.create_flags = 0;
835 io.smb2.in.desired_access = 0x0017019f;
836 io.smb2.in.create_options = 0x60;
837 io.smb2.in.file_attributes = 0;
838 io.smb2.in.share_access = 0;
839 io.smb2.in.alloc_size = 0;
840 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
841 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
842 io.smb2.in.security_flags = 0;
843 io.smb2.in.fname = BASEDIR "\\file.txt";
845 status = smb2_create(tree1, torture, &(io.smb2));
846 CHECK_STATUS(status, NT_STATUS_OK);
847 fh = io.smb2.out.file.handle;
849 torture_comment(torture, "Opening parent directory\n");
851 ZERO_STRUCT(io.smb2);
852 io.generic.level = RAW_OPEN_SMB2;
853 io.smb2.in.create_flags = 0;
854 io.smb2.in.desired_access = 0x00100080;
855 io.smb2.in.create_options = 0x00800021;
856 io.smb2.in.file_attributes = 0;
857 io.smb2.in.share_access = 0;
858 io.smb2.in.alloc_size = 0;
859 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
860 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
861 io.smb2.in.security_flags = 0;
862 io.smb2.in.fname = BASEDIR;
864 status = smb2_create(tree1, torture, &(io.smb2));
865 CHECK_STATUS(status, NT_STATUS_OK);
866 dh = io.smb2.out.file.handle;
868 torture_comment(torture, "Renaming test file\n");
870 ZERO_STRUCT(sinfo);
871 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
872 sinfo.rename_information.in.file.handle = fh;
873 sinfo.rename_information.in.overwrite = 0;
874 sinfo.rename_information.in.root_fid = 0;
875 sinfo.rename_information.in.new_name =
876 BASEDIR "\\newname.txt";
877 status = smb2_setinfo_file(tree1, &sinfo);
878 CHECK_STATUS(status, NT_STATUS_OK);
880 torture_comment(torture, "Checking for new filename\n");
882 ZERO_STRUCT(fi);
883 fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
884 fi.generic.in.file.handle = fh;
885 status = smb2_getinfo_file(tree1, torture, &fi);
886 CHECK_STATUS(status, NT_STATUS_OK);
889 torture_comment(torture, "Closing test file\n");
891 ZERO_STRUCT(cl.smb2);
892 cl.smb2.level = RAW_CLOSE_SMB2;
893 cl.smb2.in.file.handle = fh;
894 status = smb2_close(tree1, &(cl.smb2));
895 CHECK_STATUS(status, NT_STATUS_OK);
897 ZERO_STRUCT(fh);
899 torture_comment(torture, "Closing directory\n");
901 ZERO_STRUCT(cl.smb2);
902 cl.smb2.level = RAW_CLOSE_SMB2;
903 cl.smb2.in.file.handle = dh;
904 status = smb2_close(tree1, &(cl.smb2));
905 CHECK_STATUS(status, NT_STATUS_OK);
907 ZERO_STRUCT(dh);
910 done:
912 torture_comment(torture, "Cleaning up\n");
914 if (fh.data) {
915 ZERO_STRUCT(cl.smb2);
916 cl.smb2.level = RAW_CLOSE_SMB2;
917 cl.smb2.in.file.handle = fh;
918 status = smb2_close(tree1, &(cl.smb2));
920 if (dh.data) {
921 ZERO_STRUCT(cl.smb2);
922 cl.smb2.level = RAW_CLOSE_SMB2;
923 cl.smb2.in.file.handle = dh;
924 status = smb2_close(tree1, &(cl.smb2));
927 smb2_deltree(tree1, BASEDIR);
928 return ret;
931 struct rename_one_dir_cycle_state {
932 struct tevent_context *ev;
933 struct smb2_tree *tree;
934 struct smb2_handle file;
935 const char *base_name;
936 char *new_name;
937 unsigned *rename_counter;
939 unsigned current;
940 unsigned max;
941 union smb_setfileinfo sinfo;
944 static void rename_one_dir_cycle_done(struct smb2_request *subreq);
946 static struct tevent_req *rename_one_dir_cycle_send(TALLOC_CTX *mem_ctx,
947 struct tevent_context *ev,
948 struct smb2_tree *tree,
949 struct smb2_handle file,
950 unsigned max_renames,
951 const char *base_name,
952 unsigned *rename_counter)
954 struct tevent_req *req;
955 struct rename_one_dir_cycle_state *state;
956 struct smb2_request *subreq;
958 req = tevent_req_create(mem_ctx, &state,
959 struct rename_one_dir_cycle_state);
960 if (req == NULL) {
961 return NULL;
963 state->ev = ev;
964 state->tree = tree;
965 state->file = file;
966 state->base_name = base_name;
967 state->rename_counter = rename_counter;
968 state->current = 0;
969 state->max = max_renames;
971 ZERO_STRUCT(state->sinfo);
972 state->sinfo.rename_information.level =
973 RAW_SFILEINFO_RENAME_INFORMATION;
974 state->sinfo.rename_information.in.file.handle = state->file;
975 state->sinfo.rename_information.in.overwrite = 0;
976 state->sinfo.rename_information.in.root_fid = 0;
978 state->new_name = talloc_asprintf(
979 state, "%s-%u", state->base_name, state->current);
980 if (tevent_req_nomem(state->new_name, req)) {
981 return tevent_req_post(req, ev);
983 state->sinfo.rename_information.in.new_name = state->new_name;
985 subreq = smb2_setinfo_file_send(state->tree, &state->sinfo);
986 if (tevent_req_nomem(subreq, req)) {
987 return tevent_req_post(req, ev);
989 subreq->async.fn = rename_one_dir_cycle_done;
990 subreq->async.private_data = req;
991 return req;
994 static void rename_one_dir_cycle_done(struct smb2_request *subreq)
996 struct tevent_req *req = talloc_get_type_abort(
997 subreq->async.private_data, struct tevent_req);
998 struct rename_one_dir_cycle_state *state = tevent_req_data(
999 req, struct rename_one_dir_cycle_state);
1000 NTSTATUS status;
1002 status = smb2_setinfo_recv(subreq);
1003 if (tevent_req_nterror(req, status)) {
1004 return;
1006 TALLOC_FREE(state->new_name);
1008 *state->rename_counter += 1;
1010 state->current += 1;
1011 if (state->current >= state->max) {
1012 tevent_req_done(req);
1013 return;
1016 ZERO_STRUCT(state->sinfo);
1017 state->sinfo.rename_information.level =
1018 RAW_SFILEINFO_RENAME_INFORMATION;
1019 state->sinfo.rename_information.in.file.handle = state->file;
1020 state->sinfo.rename_information.in.overwrite = 0;
1021 state->sinfo.rename_information.in.root_fid = 0;
1023 state->new_name = talloc_asprintf(
1024 state, "%s-%u", state->base_name, state->current);
1025 if (tevent_req_nomem(state->new_name, req)) {
1026 return;
1028 state->sinfo.rename_information.in.new_name = state->new_name;
1030 subreq = smb2_setinfo_file_send(state->tree, &state->sinfo);
1031 if (tevent_req_nomem(subreq, req)) {
1032 return;
1034 subreq->async.fn = rename_one_dir_cycle_done;
1035 subreq->async.private_data = req;
1038 static NTSTATUS rename_one_dir_cycle_recv(struct tevent_req *req)
1040 return tevent_req_simple_recv_ntstatus(req);
1043 struct rename_dir_bench_state {
1044 struct tevent_context *ev;
1045 struct smb2_tree *tree;
1046 const char *base_name;
1047 unsigned max_renames;
1048 unsigned *rename_counter;
1050 struct smb2_create io;
1051 union smb_setfileinfo sinfo;
1052 struct smb2_close cl;
1054 struct smb2_handle file;
1057 static void rename_dir_bench_opened(struct smb2_request *subreq);
1058 static void rename_dir_bench_renamed(struct tevent_req *subreq);
1059 static void rename_dir_bench_set_doc(struct smb2_request *subreq);
1060 static void rename_dir_bench_closed(struct smb2_request *subreq);
1062 static struct tevent_req *rename_dir_bench_send(TALLOC_CTX *mem_ctx,
1063 struct tevent_context *ev,
1064 struct smb2_tree *tree,
1065 const char *base_name,
1066 unsigned max_renames,
1067 unsigned *rename_counter)
1069 struct tevent_req *req;
1070 struct rename_dir_bench_state *state;
1071 struct smb2_request *subreq;
1073 req = tevent_req_create(mem_ctx, &state,
1074 struct rename_dir_bench_state);
1075 if (req == NULL) {
1076 return NULL;
1078 state->ev = ev;
1079 state->tree = tree;
1080 state->base_name = base_name;
1081 state->max_renames = max_renames;
1082 state->rename_counter = rename_counter;
1084 ZERO_STRUCT(state->io);
1085 state->io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1086 state->io.in.share_access =
1087 NTCREATEX_SHARE_ACCESS_READ|
1088 NTCREATEX_SHARE_ACCESS_WRITE;
1089 state->io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1090 state->io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1091 state->io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1092 state->io.in.fname = state->base_name;
1094 subreq = smb2_create_send(state->tree, &state->io);
1095 if (tevent_req_nomem(subreq, req)) {
1096 return tevent_req_post(req, ev);
1098 subreq->async.fn = rename_dir_bench_opened;
1099 subreq->async.private_data = req;
1100 return req;
1103 static void rename_dir_bench_opened(struct smb2_request *subreq)
1105 struct tevent_req *req = talloc_get_type_abort(
1106 subreq->async.private_data, struct tevent_req);
1107 struct rename_dir_bench_state *state = tevent_req_data(
1108 req, struct rename_dir_bench_state);
1109 struct smb2_create *io;
1110 struct tevent_req *subreq2;
1111 NTSTATUS status;
1113 io = talloc(state, struct smb2_create);
1114 if (tevent_req_nomem(io, req)) {
1115 return;
1118 status = smb2_create_recv(subreq, io, io);
1119 if (tevent_req_nterror(req, status)) {
1120 return;
1122 state->file = io->out.file.handle;
1123 TALLOC_FREE(io);
1125 subreq2 = rename_one_dir_cycle_send(
1126 state, state->ev, state->tree, state->file,
1127 state->max_renames, state->base_name,
1128 state->rename_counter);
1129 if (tevent_req_nomem(subreq2, req)) {
1130 return;
1132 tevent_req_set_callback(subreq2, rename_dir_bench_renamed, req);
1135 static void rename_dir_bench_renamed(struct tevent_req *subreq)
1137 struct tevent_req *req = tevent_req_callback_data(
1138 subreq, struct tevent_req);
1139 struct rename_dir_bench_state *state = tevent_req_data(
1140 req, struct rename_dir_bench_state);
1141 struct smb2_request *subreq2;
1142 NTSTATUS status;
1144 status = rename_one_dir_cycle_recv(subreq);
1145 TALLOC_FREE(subreq);
1146 if (tevent_req_nterror(req, status)) {
1147 return;
1150 ZERO_STRUCT(state->sinfo);
1151 state->sinfo.disposition_info.level =
1152 RAW_SFILEINFO_DISPOSITION_INFORMATION;
1153 state->sinfo.disposition_info.in.file.handle = state->file;
1154 state->sinfo.disposition_info.in.delete_on_close = true;
1156 subreq2 = smb2_setinfo_file_send(state->tree, &state->sinfo);
1157 if (tevent_req_nomem(subreq2, req)) {
1158 return;
1160 subreq2->async.fn = rename_dir_bench_set_doc;
1161 subreq2->async.private_data = req;
1164 static void rename_dir_bench_set_doc(struct smb2_request *subreq)
1166 struct tevent_req *req = talloc_get_type_abort(
1167 subreq->async.private_data, struct tevent_req);
1168 struct rename_dir_bench_state *state = tevent_req_data(
1169 req, struct rename_dir_bench_state);
1170 NTSTATUS status;
1172 status = smb2_setinfo_recv(subreq);
1173 if (tevent_req_nterror(req, status)) {
1174 return;
1177 ZERO_STRUCT(state->cl);
1178 state->cl.in.file.handle = state->file;
1180 subreq = smb2_close_send(state->tree, &state->cl);
1181 if (tevent_req_nomem(subreq, req)) {
1182 return;
1184 subreq->async.fn = rename_dir_bench_closed;
1185 subreq->async.private_data = req;
1188 static void rename_dir_bench_closed(struct smb2_request *subreq)
1190 struct tevent_req *req = talloc_get_type_abort(
1191 subreq->async.private_data, struct tevent_req);
1192 struct smb2_close cl;
1193 NTSTATUS status;
1195 status = smb2_close_recv(subreq, &cl);
1196 if (tevent_req_nterror(req, status)) {
1197 return;
1199 tevent_req_done(req);
1202 static NTSTATUS rename_dir_bench_recv(struct tevent_req *req)
1204 return tevent_req_simple_recv_ntstatus(req);
1207 struct rename_dirs_bench_state {
1208 unsigned num_reqs;
1209 unsigned num_done;
1212 static void rename_dirs_bench_done(struct tevent_req *subreq);
1214 static struct tevent_req *rename_dirs_bench_send(TALLOC_CTX *mem_ctx,
1215 struct tevent_context *ev,
1216 struct smb2_tree *tree,
1217 const char *base_name,
1218 unsigned num_parallel,
1219 unsigned max_renames,
1220 unsigned *rename_counter)
1222 struct tevent_req *req;
1223 struct rename_dirs_bench_state *state;
1224 unsigned i;
1226 req = tevent_req_create(mem_ctx, &state,
1227 struct rename_dirs_bench_state);
1228 if (req == NULL) {
1229 return NULL;
1231 state->num_reqs = num_parallel;
1232 state->num_done = 0;
1234 for (i=0; i<num_parallel; i++) {
1235 struct tevent_req *subreq;
1236 char *sub_base;
1238 sub_base = talloc_asprintf(state, "%s-%u", base_name, i);
1239 if (tevent_req_nomem(sub_base, req)) {
1240 return tevent_req_post(req, ev);
1243 subreq = rename_dir_bench_send(state, ev, tree, sub_base,
1244 max_renames, rename_counter);
1245 if (tevent_req_nomem(subreq, req)) {
1246 return tevent_req_post(req, ev);
1248 tevent_req_set_callback(subreq, rename_dirs_bench_done, req);
1250 return req;
1253 static void rename_dirs_bench_done(struct tevent_req *subreq)
1255 struct tevent_req *req = tevent_req_callback_data(
1256 subreq, struct tevent_req);
1257 struct rename_dirs_bench_state *state = tevent_req_data(
1258 req, struct rename_dirs_bench_state);
1259 NTSTATUS status;
1261 status = rename_dir_bench_recv(subreq);
1262 TALLOC_FREE(subreq);
1263 if (tevent_req_nterror(req, status)) {
1264 return;
1267 state->num_done += 1;
1268 if (state->num_done >= state->num_reqs) {
1269 tevent_req_done(req);
1273 static NTSTATUS rename_dirs_bench_recv(struct tevent_req *req)
1275 return tevent_req_simple_recv_ntstatus(req);
1278 static bool torture_smb2_rename_dir_bench(struct torture_context *tctx,
1279 struct smb2_tree *tree)
1281 struct tevent_req *req;
1282 NTSTATUS status;
1283 unsigned counter = 0;
1284 bool ret;
1286 req = rename_dirs_bench_send(tctx, tctx->ev, tree, "dir", 3, 10,
1287 &counter);
1288 torture_assert(tctx, req != NULL, "rename_dirs_bench_send failed");
1290 ret = tevent_req_poll(req, tctx->ev);
1291 torture_assert(tctx, ret, "tevent_req_poll failed");
1293 status = rename_dirs_bench_recv(req);
1294 torture_comment(tctx, "rename_dirs_bench returned %s\n",
1295 nt_errstr(status));
1296 TALLOC_FREE(req);
1297 torture_assert_ntstatus_ok(tctx, status, "bench failed");
1298 return true;
1303 basic testing of SMB2 rename
1305 struct torture_suite *torture_smb2_rename_init(void)
1307 struct torture_suite *suite =
1308 torture_suite_create(talloc_autofree_context(), "rename");
1310 torture_suite_add_1smb2_test(suite, "simple",
1311 torture_smb2_rename_simple);
1313 torture_suite_add_1smb2_test(suite, "simple_nodelete)",
1314 torture_smb2_rename_simple2);
1316 torture_suite_add_1smb2_test(suite, "no_sharing",
1317 torture_smb2_rename_no_sharemode);
1319 torture_suite_add_1smb2_test(suite,
1320 "share_delete_and_delete_access",
1321 torture_smb2_rename_with_delete_access);
1323 torture_suite_add_1smb2_test(suite,
1324 "no_share_delete_but_delete_access",
1325 torture_smb2_rename_with_delete_access2);
1327 torture_suite_add_1smb2_test(suite,
1328 "share_delete_no_delete_access",
1329 torture_smb2_rename_no_delete_access);
1331 torture_suite_add_1smb2_test(suite,
1332 "no_share_delete_no_delete_access",
1333 torture_smb2_rename_no_delete_access2);
1335 torture_suite_add_1smb2_test(suite,
1336 "msword",
1337 torture_smb2_rename_msword);
1339 torture_suite_add_1smb2_test(suite,
1340 "rename_dir_bench",
1341 torture_smb2_rename_dir_bench);
1343 suite->description = talloc_strdup(suite, "smb2.rename tests");
1345 return suite;