2 Unix SMB/CIFS implementation.
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/>.
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)); \
42 #define BASEDIR "test_rename"
45 * basic testing of rename: open file with DELETE access
49 static bool torture_smb2_rename_simple(struct torture_context
*torture
,
50 struct smb2_tree
*tree1
)
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");
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");
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");
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
);
121 torture_comment(torture
, "Cleaning up\n");
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
);
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
)
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");
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
);
200 torture_comment(torture
, "Cleaning up\n");
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
);
214 * testing of rename with no sharing allowed on file
218 static bool torture_smb2_rename_no_sharemode(struct torture_context
*torture
,
219 struct smb2_tree
*tree1
)
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");
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");
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
);
289 torture_comment(torture
, "Cleaning up\n");
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
);
302 * testing of rename when opening parent dir with delete access and delete
304 * should result in sharing violation
307 static bool torture_smb2_rename_with_delete_access(struct torture_context
*torture
,
308 struct smb2_tree
*tree1
)
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
|
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");
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
);
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
);
406 torture_comment(torture
, "Cleaning up\n");
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
));
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
);
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
)
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
|
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");
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
);
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
);
530 torture_comment(torture
, "Cleaning up\n");
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
));
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
);
550 * testing of rename when opening parent dir with no delete access and delete
555 static bool torture_smb2_rename_no_delete_access(struct torture_context
*torture
,
556 struct smb2_tree
*tree1
)
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
|
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");
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");
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
);
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
);
664 torture_comment(torture
, "Cleaning up\n");
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
));
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
);
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
)
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
|
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");
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
);
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
);
788 torture_comment(torture
, "Cleaning up\n");
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
));
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
);
808 * this is a replay of how Word 2010 saves a file
812 static bool torture_smb2_rename_msword(struct torture_context
*torture
,
813 struct smb2_tree
*tree1
)
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");
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");
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
);
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
);
912 torture_comment(torture
, "Cleaning up\n");
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
));
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
);
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
;
937 unsigned *rename_counter
;
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
);
966 state
->base_name
= base_name
;
967 state
->rename_counter
= rename_counter
;
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
;
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
);
1002 status
= smb2_setinfo_recv(subreq
);
1003 if (tevent_req_nterror(req
, status
)) {
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
);
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
)) {
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
)) {
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
);
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
;
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
;
1113 io
= talloc(state
, struct smb2_create
);
1114 if (tevent_req_nomem(io
, req
)) {
1118 status
= smb2_create_recv(subreq
, io
, io
);
1119 if (tevent_req_nterror(req
, status
)) {
1122 state
->file
= io
->out
.file
.handle
;
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
)) {
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
;
1144 status
= rename_one_dir_cycle_recv(subreq
);
1145 TALLOC_FREE(subreq
);
1146 if (tevent_req_nterror(req
, status
)) {
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
)) {
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
);
1172 status
= smb2_setinfo_recv(subreq
);
1173 if (tevent_req_nterror(req
, status
)) {
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
)) {
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
;
1195 status
= smb2_close_recv(subreq
, &cl
);
1196 if (tevent_req_nterror(req
, status
)) {
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
{
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
;
1226 req
= tevent_req_create(mem_ctx
, &state
,
1227 struct rename_dirs_bench_state
);
1231 state
->num_reqs
= num_parallel
;
1232 state
->num_done
= 0;
1234 for (i
=0; i
<num_parallel
; i
++) {
1235 struct tevent_req
*subreq
;
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
);
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
);
1261 status
= rename_dir_bench_recv(subreq
);
1262 TALLOC_FREE(subreq
);
1263 if (tevent_req_nterror(req
, status
)) {
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
;
1283 unsigned counter
= 0;
1286 req
= rename_dirs_bench_send(tctx
, tctx
->ev
, tree
, "dir", 3, 10,
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",
1297 torture_assert_ntstatus_ok(tctx
, status
, "bench failed");
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
,
1337 torture_smb2_rename_msword
);
1339 torture_suite_add_1smb2_test(suite
,
1341 torture_smb2_rename_dir_bench
);
1343 suite
->description
= talloc_strdup(suite
, "smb2.rename tests");