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 static bool torture_smb2_rename_dir_openfile(struct torture_context
*torture
,
932 struct smb2_tree
*tree1
)
938 union smb_setfileinfo sinfo
;
939 struct smb2_handle d1
, h1
;
941 smb2_deltree(tree1
, BASEDIR
);
942 smb2_util_rmdir(tree1
, BASEDIR
);
944 torture_comment(torture
, "Creating base directory\n");
946 ZERO_STRUCT(io
.smb2
);
947 io
.generic
.level
= RAW_OPEN_SMB2
;
948 io
.smb2
.in
.create_flags
= 0;
949 io
.smb2
.in
.desired_access
= 0x0017019f;
950 io
.smb2
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
951 io
.smb2
.in
.file_attributes
= FILE_ATTRIBUTE_DIRECTORY
;
952 io
.smb2
.in
.share_access
= 0;
953 io
.smb2
.in
.alloc_size
= 0;
954 io
.smb2
.in
.create_disposition
= NTCREATEX_DISP_CREATE
;
955 io
.smb2
.in
.impersonation_level
= SMB2_IMPERSONATION_ANONYMOUS
;
956 io
.smb2
.in
.security_flags
= 0;
957 io
.smb2
.in
.fname
= BASEDIR
;
959 status
= smb2_create(tree1
, torture
, &(io
.smb2
));
960 CHECK_STATUS(status
, NT_STATUS_OK
);
961 d1
= io
.smb2
.out
.file
.handle
;
963 torture_comment(torture
, "Creating test file\n");
965 ZERO_STRUCT(io
.smb2
);
966 io
.generic
.level
= RAW_OPEN_SMB2
;
967 io
.smb2
.in
.create_flags
= 0;
968 io
.smb2
.in
.desired_access
= 0x0017019f;
969 io
.smb2
.in
.create_options
= NTCREATEX_OPTIONS_NON_DIRECTORY_FILE
;
970 io
.smb2
.in
.file_attributes
= FILE_ATTRIBUTE_NORMAL
;
971 io
.smb2
.in
.share_access
= 0;
972 io
.smb2
.in
.alloc_size
= 0;
973 io
.smb2
.in
.create_disposition
= NTCREATEX_DISP_CREATE
;
974 io
.smb2
.in
.impersonation_level
= SMB2_IMPERSONATION_ANONYMOUS
;
975 io
.smb2
.in
.security_flags
= 0;
976 io
.smb2
.in
.fname
= BASEDIR
"\\file.txt";
978 status
= smb2_create(tree1
, torture
, &(io
.smb2
));
979 CHECK_STATUS(status
, NT_STATUS_OK
);
980 h1
= io
.smb2
.out
.file
.handle
;
982 torture_comment(torture
, "Renaming directory\n");
985 sinfo
.rename_information
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
986 sinfo
.rename_information
.in
.file
.handle
= d1
;
987 sinfo
.rename_information
.in
.overwrite
= 0;
988 sinfo
.rename_information
.in
.root_fid
= 0;
989 sinfo
.rename_information
.in
.new_name
=
991 status
= smb2_setinfo_file(tree1
, &sinfo
);
992 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
994 torture_comment(torture
, "Closing directory\n");
996 ZERO_STRUCT(cl
.smb2
);
997 cl
.smb2
.level
= RAW_CLOSE_SMB2
;
998 cl
.smb2
.in
.file
.handle
= d1
;
999 status
= smb2_close(tree1
, &(cl
.smb2
));
1000 CHECK_STATUS(status
, NT_STATUS_OK
);
1003 torture_comment(torture
, "Closing test file\n");
1005 cl
.smb2
.in
.file
.handle
= h1
;
1006 status
= smb2_close(tree1
, &(cl
.smb2
));
1007 CHECK_STATUS(status
, NT_STATUS_OK
);
1012 torture_comment(torture
, "Cleaning up\n");
1015 ZERO_STRUCT(cl
.smb2
);
1016 cl
.smb2
.level
= RAW_CLOSE_SMB2
;
1017 cl
.smb2
.in
.file
.handle
= h1
;
1018 status
= smb2_close(tree1
, &(cl
.smb2
));
1020 smb2_deltree(tree1
, BASEDIR
);
1024 struct rename_one_dir_cycle_state
{
1025 struct tevent_context
*ev
;
1026 struct smb2_tree
*tree
;
1027 struct smb2_handle file
;
1028 const char *base_name
;
1030 unsigned *rename_counter
;
1034 union smb_setfileinfo sinfo
;
1037 static void rename_one_dir_cycle_done(struct smb2_request
*subreq
);
1039 static struct tevent_req
*rename_one_dir_cycle_send(TALLOC_CTX
*mem_ctx
,
1040 struct tevent_context
*ev
,
1041 struct smb2_tree
*tree
,
1042 struct smb2_handle file
,
1043 unsigned max_renames
,
1044 const char *base_name
,
1045 unsigned *rename_counter
)
1047 struct tevent_req
*req
;
1048 struct rename_one_dir_cycle_state
*state
;
1049 struct smb2_request
*subreq
;
1051 req
= tevent_req_create(mem_ctx
, &state
,
1052 struct rename_one_dir_cycle_state
);
1059 state
->base_name
= base_name
;
1060 state
->rename_counter
= rename_counter
;
1062 state
->max
= max_renames
;
1064 ZERO_STRUCT(state
->sinfo
);
1065 state
->sinfo
.rename_information
.level
=
1066 RAW_SFILEINFO_RENAME_INFORMATION
;
1067 state
->sinfo
.rename_information
.in
.file
.handle
= state
->file
;
1068 state
->sinfo
.rename_information
.in
.overwrite
= 0;
1069 state
->sinfo
.rename_information
.in
.root_fid
= 0;
1071 state
->new_name
= talloc_asprintf(
1072 state
, "%s-%u", state
->base_name
, state
->current
);
1073 if (tevent_req_nomem(state
->new_name
, req
)) {
1074 return tevent_req_post(req
, ev
);
1076 state
->sinfo
.rename_information
.in
.new_name
= state
->new_name
;
1078 subreq
= smb2_setinfo_file_send(state
->tree
, &state
->sinfo
);
1079 if (tevent_req_nomem(subreq
, req
)) {
1080 return tevent_req_post(req
, ev
);
1082 subreq
->async
.fn
= rename_one_dir_cycle_done
;
1083 subreq
->async
.private_data
= req
;
1087 static void rename_one_dir_cycle_done(struct smb2_request
*subreq
)
1089 struct tevent_req
*req
= talloc_get_type_abort(
1090 subreq
->async
.private_data
, struct tevent_req
);
1091 struct rename_one_dir_cycle_state
*state
= tevent_req_data(
1092 req
, struct rename_one_dir_cycle_state
);
1095 status
= smb2_setinfo_recv(subreq
);
1096 if (tevent_req_nterror(req
, status
)) {
1099 TALLOC_FREE(state
->new_name
);
1101 *state
->rename_counter
+= 1;
1103 state
->current
+= 1;
1104 if (state
->current
>= state
->max
) {
1105 tevent_req_done(req
);
1109 ZERO_STRUCT(state
->sinfo
);
1110 state
->sinfo
.rename_information
.level
=
1111 RAW_SFILEINFO_RENAME_INFORMATION
;
1112 state
->sinfo
.rename_information
.in
.file
.handle
= state
->file
;
1113 state
->sinfo
.rename_information
.in
.overwrite
= 0;
1114 state
->sinfo
.rename_information
.in
.root_fid
= 0;
1116 state
->new_name
= talloc_asprintf(
1117 state
, "%s-%u", state
->base_name
, state
->current
);
1118 if (tevent_req_nomem(state
->new_name
, req
)) {
1121 state
->sinfo
.rename_information
.in
.new_name
= state
->new_name
;
1123 subreq
= smb2_setinfo_file_send(state
->tree
, &state
->sinfo
);
1124 if (tevent_req_nomem(subreq
, req
)) {
1127 subreq
->async
.fn
= rename_one_dir_cycle_done
;
1128 subreq
->async
.private_data
= req
;
1131 static NTSTATUS
rename_one_dir_cycle_recv(struct tevent_req
*req
)
1133 return tevent_req_simple_recv_ntstatus(req
);
1136 struct rename_dir_bench_state
{
1137 struct tevent_context
*ev
;
1138 struct smb2_tree
*tree
;
1139 const char *base_name
;
1140 unsigned max_renames
;
1141 unsigned *rename_counter
;
1143 struct smb2_create io
;
1144 union smb_setfileinfo sinfo
;
1145 struct smb2_close cl
;
1147 struct smb2_handle file
;
1150 static void rename_dir_bench_opened(struct smb2_request
*subreq
);
1151 static void rename_dir_bench_renamed(struct tevent_req
*subreq
);
1152 static void rename_dir_bench_set_doc(struct smb2_request
*subreq
);
1153 static void rename_dir_bench_closed(struct smb2_request
*subreq
);
1155 static struct tevent_req
*rename_dir_bench_send(TALLOC_CTX
*mem_ctx
,
1156 struct tevent_context
*ev
,
1157 struct smb2_tree
*tree
,
1158 const char *base_name
,
1159 unsigned max_renames
,
1160 unsigned *rename_counter
)
1162 struct tevent_req
*req
;
1163 struct rename_dir_bench_state
*state
;
1164 struct smb2_request
*subreq
;
1166 req
= tevent_req_create(mem_ctx
, &state
,
1167 struct rename_dir_bench_state
);
1173 state
->base_name
= base_name
;
1174 state
->max_renames
= max_renames
;
1175 state
->rename_counter
= rename_counter
;
1177 ZERO_STRUCT(state
->io
);
1178 state
->io
.in
.desired_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
1179 state
->io
.in
.share_access
=
1180 NTCREATEX_SHARE_ACCESS_READ
|
1181 NTCREATEX_SHARE_ACCESS_WRITE
;
1182 state
->io
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
1183 state
->io
.in
.file_attributes
= FILE_ATTRIBUTE_DIRECTORY
;
1184 state
->io
.in
.create_disposition
= NTCREATEX_DISP_OPEN_IF
;
1185 state
->io
.in
.fname
= state
->base_name
;
1187 subreq
= smb2_create_send(state
->tree
, &state
->io
);
1188 if (tevent_req_nomem(subreq
, req
)) {
1189 return tevent_req_post(req
, ev
);
1191 subreq
->async
.fn
= rename_dir_bench_opened
;
1192 subreq
->async
.private_data
= req
;
1196 static void rename_dir_bench_opened(struct smb2_request
*subreq
)
1198 struct tevent_req
*req
= talloc_get_type_abort(
1199 subreq
->async
.private_data
, struct tevent_req
);
1200 struct rename_dir_bench_state
*state
= tevent_req_data(
1201 req
, struct rename_dir_bench_state
);
1202 struct smb2_create
*io
;
1203 struct tevent_req
*subreq2
;
1206 io
= talloc(state
, struct smb2_create
);
1207 if (tevent_req_nomem(io
, req
)) {
1211 status
= smb2_create_recv(subreq
, io
, io
);
1212 if (tevent_req_nterror(req
, status
)) {
1215 state
->file
= io
->out
.file
.handle
;
1218 subreq2
= rename_one_dir_cycle_send(
1219 state
, state
->ev
, state
->tree
, state
->file
,
1220 state
->max_renames
, state
->base_name
,
1221 state
->rename_counter
);
1222 if (tevent_req_nomem(subreq2
, req
)) {
1225 tevent_req_set_callback(subreq2
, rename_dir_bench_renamed
, req
);
1228 static void rename_dir_bench_renamed(struct tevent_req
*subreq
)
1230 struct tevent_req
*req
= tevent_req_callback_data(
1231 subreq
, struct tevent_req
);
1232 struct rename_dir_bench_state
*state
= tevent_req_data(
1233 req
, struct rename_dir_bench_state
);
1234 struct smb2_request
*subreq2
;
1237 status
= rename_one_dir_cycle_recv(subreq
);
1238 TALLOC_FREE(subreq
);
1239 if (tevent_req_nterror(req
, status
)) {
1243 ZERO_STRUCT(state
->sinfo
);
1244 state
->sinfo
.disposition_info
.level
=
1245 RAW_SFILEINFO_DISPOSITION_INFORMATION
;
1246 state
->sinfo
.disposition_info
.in
.file
.handle
= state
->file
;
1247 state
->sinfo
.disposition_info
.in
.delete_on_close
= true;
1249 subreq2
= smb2_setinfo_file_send(state
->tree
, &state
->sinfo
);
1250 if (tevent_req_nomem(subreq2
, req
)) {
1253 subreq2
->async
.fn
= rename_dir_bench_set_doc
;
1254 subreq2
->async
.private_data
= req
;
1257 static void rename_dir_bench_set_doc(struct smb2_request
*subreq
)
1259 struct tevent_req
*req
= talloc_get_type_abort(
1260 subreq
->async
.private_data
, struct tevent_req
);
1261 struct rename_dir_bench_state
*state
= tevent_req_data(
1262 req
, struct rename_dir_bench_state
);
1265 status
= smb2_setinfo_recv(subreq
);
1266 if (tevent_req_nterror(req
, status
)) {
1270 ZERO_STRUCT(state
->cl
);
1271 state
->cl
.in
.file
.handle
= state
->file
;
1273 subreq
= smb2_close_send(state
->tree
, &state
->cl
);
1274 if (tevent_req_nomem(subreq
, req
)) {
1277 subreq
->async
.fn
= rename_dir_bench_closed
;
1278 subreq
->async
.private_data
= req
;
1281 static void rename_dir_bench_closed(struct smb2_request
*subreq
)
1283 struct tevent_req
*req
= talloc_get_type_abort(
1284 subreq
->async
.private_data
, struct tevent_req
);
1285 struct smb2_close cl
;
1288 status
= smb2_close_recv(subreq
, &cl
);
1289 if (tevent_req_nterror(req
, status
)) {
1292 tevent_req_done(req
);
1295 static NTSTATUS
rename_dir_bench_recv(struct tevent_req
*req
)
1297 return tevent_req_simple_recv_ntstatus(req
);
1300 struct rename_dirs_bench_state
{
1305 static void rename_dirs_bench_done(struct tevent_req
*subreq
);
1307 static struct tevent_req
*rename_dirs_bench_send(TALLOC_CTX
*mem_ctx
,
1308 struct tevent_context
*ev
,
1309 struct smb2_tree
*tree
,
1310 const char *base_name
,
1311 unsigned num_parallel
,
1312 unsigned max_renames
,
1313 unsigned *rename_counter
)
1315 struct tevent_req
*req
;
1316 struct rename_dirs_bench_state
*state
;
1319 req
= tevent_req_create(mem_ctx
, &state
,
1320 struct rename_dirs_bench_state
);
1324 state
->num_reqs
= num_parallel
;
1325 state
->num_done
= 0;
1327 for (i
=0; i
<num_parallel
; i
++) {
1328 struct tevent_req
*subreq
;
1331 sub_base
= talloc_asprintf(state
, "%s-%u", base_name
, i
);
1332 if (tevent_req_nomem(sub_base
, req
)) {
1333 return tevent_req_post(req
, ev
);
1336 subreq
= rename_dir_bench_send(state
, ev
, tree
, sub_base
,
1337 max_renames
, rename_counter
);
1338 if (tevent_req_nomem(subreq
, req
)) {
1339 return tevent_req_post(req
, ev
);
1341 tevent_req_set_callback(subreq
, rename_dirs_bench_done
, req
);
1346 static void rename_dirs_bench_done(struct tevent_req
*subreq
)
1348 struct tevent_req
*req
= tevent_req_callback_data(
1349 subreq
, struct tevent_req
);
1350 struct rename_dirs_bench_state
*state
= tevent_req_data(
1351 req
, struct rename_dirs_bench_state
);
1354 status
= rename_dir_bench_recv(subreq
);
1355 TALLOC_FREE(subreq
);
1356 if (tevent_req_nterror(req
, status
)) {
1360 state
->num_done
+= 1;
1361 if (state
->num_done
>= state
->num_reqs
) {
1362 tevent_req_done(req
);
1366 static NTSTATUS
rename_dirs_bench_recv(struct tevent_req
*req
)
1368 return tevent_req_simple_recv_ntstatus(req
);
1371 static bool torture_smb2_rename_dir_bench(struct torture_context
*tctx
,
1372 struct smb2_tree
*tree
)
1374 struct tevent_req
*req
;
1376 unsigned counter
= 0;
1379 req
= rename_dirs_bench_send(tctx
, tctx
->ev
, tree
, "dir", 3, 10,
1381 torture_assert(tctx
, req
!= NULL
, "rename_dirs_bench_send failed");
1383 ret
= tevent_req_poll(req
, tctx
->ev
);
1384 torture_assert(tctx
, ret
, "tevent_req_poll failed");
1386 status
= rename_dirs_bench_recv(req
);
1387 torture_comment(tctx
, "rename_dirs_bench returned %s\n",
1390 torture_assert_ntstatus_ok(tctx
, status
, "bench failed");
1396 basic testing of SMB2 rename
1398 struct torture_suite
*torture_smb2_rename_init(void)
1400 struct torture_suite
*suite
=
1401 torture_suite_create(talloc_autofree_context(), "rename");
1403 torture_suite_add_1smb2_test(suite
, "simple",
1404 torture_smb2_rename_simple
);
1406 torture_suite_add_1smb2_test(suite
, "simple_nodelete)",
1407 torture_smb2_rename_simple2
);
1409 torture_suite_add_1smb2_test(suite
, "no_sharing",
1410 torture_smb2_rename_no_sharemode
);
1412 torture_suite_add_1smb2_test(suite
,
1413 "share_delete_and_delete_access",
1414 torture_smb2_rename_with_delete_access
);
1416 torture_suite_add_1smb2_test(suite
,
1417 "no_share_delete_but_delete_access",
1418 torture_smb2_rename_with_delete_access2
);
1420 torture_suite_add_1smb2_test(suite
,
1421 "share_delete_no_delete_access",
1422 torture_smb2_rename_no_delete_access
);
1424 torture_suite_add_1smb2_test(suite
,
1425 "no_share_delete_no_delete_access",
1426 torture_smb2_rename_no_delete_access2
);
1428 torture_suite_add_1smb2_test(suite
,
1430 torture_smb2_rename_msword
);
1432 torture_suite_add_1smb2_test(
1433 suite
, "rename_dir_openfile",
1434 torture_smb2_rename_dir_openfile
);
1436 torture_suite_add_1smb2_test(suite
,
1438 torture_smb2_rename_dir_bench
);
1440 suite
->description
= talloc_strdup(suite
, "smb2.rename tests");