2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "libcli/libcli.h"
22 #include "torture/util.h"
23 #include "torture/raw/proto.h"
25 #define CHECK_STATUS(status, correct) do { \
26 if (!NT_STATUS_EQUAL(status, correct)) { \
27 torture_result(tctx, TORTURE_FAIL, \
28 "(%s) Incorrect status %s - should be %s\n", \
29 __location__, nt_errstr(status), nt_errstr(correct)); \
34 #define CHECK_VALUE(v, correct) do { \
35 if ((v) != (correct)) { \
36 torture_result(tctx, TORTURE_FAIL, \
37 "(%s) Incorrect %s %d - should be %d\n", \
38 __location__, #v, (int)v, (int)correct); \
42 #define BASEDIR "\\testrename"
47 static bool test_mv(struct torture_context
*tctx
,
48 struct smbcli_state
*cli
)
54 const char *fname1
= BASEDIR
"\\test1.txt";
55 const char *fname2
= BASEDIR
"\\test2.txt";
56 const char *Fname1
= BASEDIR
"\\Test1.txt";
57 union smb_fileinfo finfo
;
60 torture_comment(tctx
, "Testing SMBmv\n");
62 if (!torture_setup_dir(cli
, BASEDIR
)) {
66 torture_comment(tctx
, "Trying simple rename\n");
68 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
69 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
70 op
.ntcreatex
.in
.flags
= 0;
71 op
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
72 op
.ntcreatex
.in
.create_options
= 0;
73 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
74 op
.ntcreatex
.in
.share_access
=
75 NTCREATEX_SHARE_ACCESS_READ
|
76 NTCREATEX_SHARE_ACCESS_WRITE
;
77 op
.ntcreatex
.in
.alloc_size
= 0;
78 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
79 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
80 op
.ntcreatex
.in
.security_flags
= 0;
81 op
.ntcreatex
.in
.fname
= fname1
;
83 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
84 CHECK_STATUS(status
, NT_STATUS_OK
);
85 fnum
= op
.ntcreatex
.out
.file
.fnum
;
87 io
.generic
.level
= RAW_RENAME_RENAME
;
88 io
.rename
.in
.pattern1
= fname1
;
89 io
.rename
.in
.pattern2
= fname2
;
90 io
.rename
.in
.attrib
= 0;
92 torture_comment(tctx
, "trying rename while first file open\n");
93 status
= smb_raw_rename(cli
->tree
, &io
);
94 CHECK_STATUS(status
, NT_STATUS_SHARING_VIOLATION
);
96 smbcli_close(cli
->tree
, fnum
);
98 op
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_DATA
;
99 op
.ntcreatex
.in
.share_access
=
100 NTCREATEX_SHARE_ACCESS_DELETE
|
101 NTCREATEX_SHARE_ACCESS_READ
|
102 NTCREATEX_SHARE_ACCESS_WRITE
;
103 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
104 CHECK_STATUS(status
, NT_STATUS_OK
);
105 fnum
= op
.ntcreatex
.out
.file
.fnum
;
107 torture_comment(tctx
, "trying rename while first file open with SHARE_ACCESS_DELETE\n");
108 status
= smb_raw_rename(cli
->tree
, &io
);
109 CHECK_STATUS(status
, NT_STATUS_OK
);
111 io
.rename
.in
.pattern1
= fname2
;
112 io
.rename
.in
.pattern2
= fname1
;
113 status
= smb_raw_rename(cli
->tree
, &io
);
114 CHECK_STATUS(status
, NT_STATUS_OK
);
116 torture_comment(tctx
, "Trying case-changing rename\n");
117 io
.rename
.in
.pattern1
= fname1
;
118 io
.rename
.in
.pattern2
= Fname1
;
119 status
= smb_raw_rename(cli
->tree
, &io
);
120 CHECK_STATUS(status
, NT_STATUS_OK
);
122 finfo
.generic
.level
= RAW_FILEINFO_ALL_INFO
;
123 finfo
.all_info
.in
.file
.path
= fname1
;
124 status
= smb_raw_pathinfo(cli
->tree
, tctx
, &finfo
);
125 CHECK_STATUS(status
, NT_STATUS_OK
);
126 if (strcmp(finfo
.all_info
.out
.fname
.s
, Fname1
) != 0) {
127 torture_warning(tctx
, "(%s) Incorrect filename [%s] after case-changing "
128 "rename, should be [%s]\n", __location__
,
129 finfo
.all_info
.out
.fname
.s
, Fname1
);
132 io
.rename
.in
.pattern1
= fname1
;
133 io
.rename
.in
.pattern2
= fname2
;
135 torture_comment(tctx
, "trying rename while not open\n");
136 smb_raw_exit(cli
->session
);
137 status
= smb_raw_rename(cli
->tree
, &io
);
138 CHECK_STATUS(status
, NT_STATUS_OK
);
140 torture_comment(tctx
, "Trying self rename\n");
141 io
.rename
.in
.pattern1
= fname2
;
142 io
.rename
.in
.pattern2
= fname2
;
143 status
= smb_raw_rename(cli
->tree
, &io
);
144 CHECK_STATUS(status
, NT_STATUS_OK
);
146 io
.rename
.in
.pattern1
= fname1
;
147 io
.rename
.in
.pattern2
= fname1
;
148 status
= smb_raw_rename(cli
->tree
, &io
);
149 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
152 torture_comment(tctx
, "trying wildcard rename\n");
153 io
.rename
.in
.pattern1
= BASEDIR
"\\*.txt";
154 io
.rename
.in
.pattern2
= fname1
;
156 status
= smb_raw_rename(cli
->tree
, &io
);
157 CHECK_STATUS(status
, NT_STATUS_OK
);
159 torture_comment(tctx
, "and again\n");
160 status
= smb_raw_rename(cli
->tree
, &io
);
161 CHECK_STATUS(status
, NT_STATUS_OK
);
163 torture_comment(tctx
, "Trying extension change\n");
164 io
.rename
.in
.pattern1
= BASEDIR
"\\*.txt";
165 io
.rename
.in
.pattern2
= BASEDIR
"\\*.bak";
166 status
= smb_raw_rename(cli
->tree
, &io
);
167 CHECK_STATUS(status
, NT_STATUS_OK
);
169 status
= smb_raw_rename(cli
->tree
, &io
);
170 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
172 torture_comment(tctx
, "Checking attrib handling\n");
173 torture_set_file_attribute(cli
->tree
, BASEDIR
"\\test1.bak", FILE_ATTRIBUTE_HIDDEN
);
174 io
.rename
.in
.pattern1
= BASEDIR
"\\test1.bak";
175 io
.rename
.in
.pattern2
= BASEDIR
"\\*.txt";
176 io
.rename
.in
.attrib
= 0;
177 status
= smb_raw_rename(cli
->tree
, &io
);
178 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
180 io
.rename
.in
.attrib
= FILE_ATTRIBUTE_HIDDEN
;
181 status
= smb_raw_rename(cli
->tree
, &io
);
182 CHECK_STATUS(status
, NT_STATUS_OK
);
185 smbcli_close(cli
->tree
, fnum
);
186 smb_raw_exit(cli
->session
);
187 smbcli_deltree(cli
->tree
, BASEDIR
);
192 static bool test_osxrename(struct torture_context
*tctx
,
193 struct smbcli_state
*cli
)
196 union smb_unlink io_un
;
200 const char *fname1
= BASEDIR
"\\test1";
201 const char *FNAME1
= BASEDIR
"\\TEST1";
202 union smb_fileinfo finfo
;
205 torture_comment(tctx
, "\nTesting OSX Rename\n");
206 if (!torture_setup_dir(cli
, BASEDIR
)) {
209 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
210 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
211 op
.ntcreatex
.in
.flags
= 0;
212 op
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
213 op
.ntcreatex
.in
.create_options
= 0;
214 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
215 op
.ntcreatex
.in
.share_access
=
216 NTCREATEX_SHARE_ACCESS_READ
|
217 NTCREATEX_SHARE_ACCESS_WRITE
;
218 op
.ntcreatex
.in
.alloc_size
= 0;
219 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
220 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
221 op
.ntcreatex
.in
.security_flags
= 0;
222 op
.ntcreatex
.in
.fname
= fname1
;
224 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
225 CHECK_STATUS(status
, NT_STATUS_OK
);
226 fnum
= op
.ntcreatex
.out
.file
.fnum
;
228 io
.generic
.level
= RAW_RENAME_RENAME
;
229 io
.rename
.in
.attrib
= 0;
231 smbcli_close(cli
->tree
, fnum
);
233 /* Rename by changing case. First check for the
234 * existence of the file with the "newname".
235 * If we find one and both the output and input are same case,
238 torture_comment(tctx
, "Checking os X rename (case changing)\n");
240 finfo
.generic
.level
= RAW_FILEINFO_ALL_INFO
;
241 finfo
.all_info
.in
.file
.path
= FNAME1
;
242 torture_comment(tctx
, "Looking for file %s \n",FNAME1
);
243 status
= smb_raw_pathinfo(cli
->tree
, tctx
, &finfo
);
245 if (NT_STATUS_EQUAL(status
, NT_STATUS_OK
)) {
246 torture_comment(tctx
, "Name of the file found %s \n", finfo
.all_info
.out
.fname
.s
);
247 if (strcmp(finfo
.all_info
.out
.fname
.s
, finfo
.all_info
.in
.file
.path
) == 0) {
248 /* If file is found with the same case delete it */
249 torture_comment(tctx
, "Deleting File %s \n", finfo
.all_info
.out
.fname
.s
);
250 io_un
.unlink
.in
.pattern
= finfo
.all_info
.out
.fname
.s
;
251 io_un
.unlink
.in
.attrib
= 0;
252 status
= smb_raw_unlink(cli
->tree
, &io_un
);
253 CHECK_STATUS(status
, NT_STATUS_OK
);
257 io
.rename
.in
.pattern1
= fname1
;
258 io
.rename
.in
.pattern2
= FNAME1
;
259 status
= smb_raw_rename(cli
->tree
, &io
);
260 CHECK_STATUS(status
, NT_STATUS_OK
);
262 finfo
.generic
.level
= RAW_FILEINFO_ALL_INFO
;
263 finfo
.all_info
.in
.file
.path
= fname1
;
264 status
= smb_raw_pathinfo(cli
->tree
, tctx
, &finfo
);
265 CHECK_STATUS(status
, NT_STATUS_OK
);
266 torture_comment(tctx
, "File name after rename %s \n",finfo
.all_info
.out
.fname
.s
);
269 smbcli_close(cli
->tree
, fnum
);
270 smb_raw_exit(cli
->session
);
271 smbcli_deltree(cli
->tree
, BASEDIR
);
278 static bool test_ntrename(struct torture_context
*tctx
,
279 struct smbcli_state
*cli
)
285 const char *fname1
= BASEDIR
"\\test1.txt";
286 const char *fname2
= BASEDIR
"\\test2.txt";
287 union smb_fileinfo finfo
;
289 torture_comment(tctx
, "Testing SMBntrename\n");
291 if (!torture_setup_dir(cli
, BASEDIR
)) {
295 torture_comment(tctx
, "Trying simple rename\n");
297 fnum
= create_complex_file(cli
, tctx
, fname1
);
299 io
.generic
.level
= RAW_RENAME_NTRENAME
;
300 io
.ntrename
.in
.old_name
= fname1
;
301 io
.ntrename
.in
.new_name
= fname2
;
302 io
.ntrename
.in
.attrib
= 0;
303 io
.ntrename
.in
.cluster_size
= 0;
304 io
.ntrename
.in
.flags
= RENAME_FLAG_RENAME
;
306 status
= smb_raw_rename(cli
->tree
, &io
);
307 CHECK_STATUS(status
, NT_STATUS_SHARING_VIOLATION
);
309 smbcli_close(cli
->tree
, fnum
);
310 status
= smb_raw_rename(cli
->tree
, &io
);
311 CHECK_STATUS(status
, NT_STATUS_OK
);
313 torture_comment(tctx
, "Trying self rename\n");
314 io
.ntrename
.in
.old_name
= fname2
;
315 io
.ntrename
.in
.new_name
= fname2
;
316 status
= smb_raw_rename(cli
->tree
, &io
);
317 CHECK_STATUS(status
, NT_STATUS_OK
);
319 io
.ntrename
.in
.old_name
= fname1
;
320 io
.ntrename
.in
.new_name
= fname1
;
321 status
= smb_raw_rename(cli
->tree
, &io
);
322 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
324 torture_comment(tctx
, "trying wildcard rename\n");
325 io
.ntrename
.in
.old_name
= BASEDIR
"\\*.txt";
326 io
.ntrename
.in
.new_name
= fname1
;
328 status
= smb_raw_rename(cli
->tree
, &io
);
329 CHECK_STATUS(status
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
331 torture_comment(tctx
, "Checking attrib handling\n");
332 torture_set_file_attribute(cli
->tree
, fname2
, FILE_ATTRIBUTE_HIDDEN
);
333 io
.ntrename
.in
.old_name
= fname2
;
334 io
.ntrename
.in
.new_name
= fname1
;
335 io
.ntrename
.in
.attrib
= 0;
336 status
= smb_raw_rename(cli
->tree
, &io
);
337 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
339 io
.ntrename
.in
.attrib
= FILE_ATTRIBUTE_HIDDEN
;
340 status
= smb_raw_rename(cli
->tree
, &io
);
341 CHECK_STATUS(status
, NT_STATUS_OK
);
343 torture_set_file_attribute(cli
->tree
, fname1
, FILE_ATTRIBUTE_NORMAL
);
345 torture_comment(tctx
, "Checking hard link\n");
346 io
.ntrename
.in
.old_name
= fname1
;
347 io
.ntrename
.in
.new_name
= fname2
;
348 io
.ntrename
.in
.attrib
= 0;
349 io
.ntrename
.in
.flags
= RENAME_FLAG_HARD_LINK
;
350 status
= smb_raw_rename(cli
->tree
, &io
);
351 CHECK_STATUS(status
, NT_STATUS_OK
);
353 torture_set_file_attribute(cli
->tree
, fname1
, FILE_ATTRIBUTE_SYSTEM
);
355 finfo
.generic
.level
= RAW_FILEINFO_ALL_INFO
;
356 finfo
.generic
.in
.file
.path
= fname2
;
357 status
= smb_raw_pathinfo(cli
->tree
, tctx
, &finfo
);
358 CHECK_STATUS(status
, NT_STATUS_OK
);
359 CHECK_VALUE(finfo
.all_info
.out
.nlink
, 2);
360 CHECK_VALUE(finfo
.all_info
.out
.attrib
, FILE_ATTRIBUTE_SYSTEM
);
362 finfo
.generic
.in
.file
.path
= fname1
;
363 status
= smb_raw_pathinfo(cli
->tree
, tctx
, &finfo
);
364 CHECK_STATUS(status
, NT_STATUS_OK
);
365 CHECK_VALUE(finfo
.all_info
.out
.nlink
, 2);
366 CHECK_VALUE(finfo
.all_info
.out
.attrib
, FILE_ATTRIBUTE_SYSTEM
);
368 torture_set_file_attribute(cli
->tree
, fname1
, FILE_ATTRIBUTE_NORMAL
);
370 smbcli_unlink(cli
->tree
, fname2
);
372 finfo
.generic
.in
.file
.path
= fname1
;
373 status
= smb_raw_pathinfo(cli
->tree
, tctx
, &finfo
);
374 CHECK_STATUS(status
, NT_STATUS_OK
);
375 CHECK_VALUE(finfo
.all_info
.out
.nlink
, 1);
376 CHECK_VALUE(finfo
.all_info
.out
.attrib
, FILE_ATTRIBUTE_NORMAL
);
378 torture_comment(tctx
, "Checking copy\n");
379 io
.ntrename
.in
.old_name
= fname1
;
380 io
.ntrename
.in
.new_name
= fname2
;
381 io
.ntrename
.in
.attrib
= 0;
382 io
.ntrename
.in
.flags
= RENAME_FLAG_COPY
;
383 status
= smb_raw_rename(cli
->tree
, &io
);
384 CHECK_STATUS(status
, NT_STATUS_OK
);
386 finfo
.generic
.level
= RAW_FILEINFO_ALL_INFO
;
387 finfo
.generic
.in
.file
.path
= fname1
;
388 status
= smb_raw_pathinfo(cli
->tree
, tctx
, &finfo
);
389 CHECK_STATUS(status
, NT_STATUS_OK
);
390 CHECK_VALUE(finfo
.all_info
.out
.nlink
, 1);
391 CHECK_VALUE(finfo
.all_info
.out
.attrib
, FILE_ATTRIBUTE_NORMAL
);
393 finfo
.generic
.level
= RAW_FILEINFO_ALL_INFO
;
394 finfo
.generic
.in
.file
.path
= fname2
;
395 status
= smb_raw_pathinfo(cli
->tree
, tctx
, &finfo
);
396 CHECK_STATUS(status
, NT_STATUS_OK
);
397 CHECK_VALUE(finfo
.all_info
.out
.nlink
, 1);
398 CHECK_VALUE(finfo
.all_info
.out
.attrib
, FILE_ATTRIBUTE_NORMAL
);
400 torture_set_file_attribute(cli
->tree
, fname1
, FILE_ATTRIBUTE_SYSTEM
);
402 finfo
.generic
.level
= RAW_FILEINFO_ALL_INFO
;
403 finfo
.generic
.in
.file
.path
= fname2
;
404 status
= smb_raw_pathinfo(cli
->tree
, tctx
, &finfo
);
405 CHECK_STATUS(status
, NT_STATUS_OK
);
406 CHECK_VALUE(finfo
.all_info
.out
.nlink
, 1);
407 CHECK_VALUE(finfo
.all_info
.out
.attrib
, FILE_ATTRIBUTE_NORMAL
);
409 finfo
.generic
.in
.file
.path
= fname1
;
410 status
= smb_raw_pathinfo(cli
->tree
, tctx
, &finfo
);
411 CHECK_STATUS(status
, NT_STATUS_OK
);
412 CHECK_VALUE(finfo
.all_info
.out
.nlink
, 1);
413 CHECK_VALUE(finfo
.all_info
.out
.attrib
, FILE_ATTRIBUTE_SYSTEM
);
415 torture_set_file_attribute(cli
->tree
, fname1
, FILE_ATTRIBUTE_NORMAL
);
417 smbcli_unlink(cli
->tree
, fname2
);
419 finfo
.generic
.in
.file
.path
= fname1
;
420 status
= smb_raw_pathinfo(cli
->tree
, tctx
, &finfo
);
421 CHECK_STATUS(status
, NT_STATUS_OK
);
422 CHECK_VALUE(finfo
.all_info
.out
.nlink
, 1);
424 torture_comment(tctx
, "Checking invalid flags\n");
425 io
.ntrename
.in
.old_name
= fname1
;
426 io
.ntrename
.in
.new_name
= fname2
;
427 io
.ntrename
.in
.attrib
= 0;
428 io
.ntrename
.in
.flags
= 0;
429 status
= smb_raw_rename(cli
->tree
, &io
);
430 if (TARGET_IS_WIN7(tctx
)) {
431 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
433 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
436 io
.ntrename
.in
.flags
= 300;
437 status
= smb_raw_rename(cli
->tree
, &io
);
438 if (TARGET_IS_WIN7(tctx
)) {
439 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
441 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
444 io
.ntrename
.in
.flags
= 0x106;
445 status
= smb_raw_rename(cli
->tree
, &io
);
446 if (TARGET_IS_WIN7(tctx
)) {
447 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
449 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
452 torture_comment(tctx
, "Checking unknown field\n");
453 io
.ntrename
.in
.old_name
= fname1
;
454 io
.ntrename
.in
.new_name
= fname2
;
455 io
.ntrename
.in
.attrib
= 0;
456 io
.ntrename
.in
.flags
= RENAME_FLAG_RENAME
;
457 io
.ntrename
.in
.cluster_size
= 0xff;
458 status
= smb_raw_rename(cli
->tree
, &io
);
459 CHECK_STATUS(status
, NT_STATUS_OK
);
461 torture_comment(tctx
, "Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");
463 io
.ntrename
.in
.old_name
= fname2
;
464 io
.ntrename
.in
.new_name
= fname1
;
465 io
.ntrename
.in
.attrib
= 0;
466 io
.ntrename
.in
.flags
= RENAME_FLAG_MOVE_CLUSTER_INFORMATION
;
467 io
.ntrename
.in
.cluster_size
= 1;
468 status
= smb_raw_rename(cli
->tree
, &io
);
469 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
471 io
.ntrename
.in
.flags
= RENAME_FLAG_COPY
;
472 status
= smb_raw_rename(cli
->tree
, &io
);
473 CHECK_STATUS(status
, NT_STATUS_OK
);
478 fnum
= smbcli_open(cli
->tree
, fname1
, O_RDWR
, DENY_NONE
);
479 memset(buf
, 1, sizeof(buf
));
480 smbcli_write(cli
->tree
, fnum
, 0, buf
, 0, sizeof(buf
));
481 smbcli_close(cli
->tree
, fnum
);
483 fnum
= smbcli_open(cli
->tree
, fname2
, O_RDWR
, DENY_NONE
);
484 memset(buf
, 1, sizeof(buf
));
485 smbcli_write(cli
->tree
, fnum
, 0, buf
, 0, sizeof(buf
)-1);
486 smbcli_close(cli
->tree
, fnum
);
488 torture_all_info(cli
->tree
, fname1
);
489 torture_all_info(cli
->tree
, fname2
);
493 io
.ntrename
.in
.flags
= RENAME_FLAG_MOVE_CLUSTER_INFORMATION
;
494 status
= smb_raw_rename(cli
->tree
, &io
);
495 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
497 for (i
=0;i
<20000;i
++) {
498 io
.ntrename
.in
.cluster_size
= i
;
499 status
= smb_raw_rename(cli
->tree
, &io
);
500 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
501 torture_warning(tctx
, "i=%d status=%s\n", i
, nt_errstr(status
));
506 torture_comment(tctx
, "Checking other flags\n");
508 for (i
=0;i
<0xFFF;i
++) {
509 if (i
== RENAME_FLAG_RENAME
||
510 i
== RENAME_FLAG_HARD_LINK
||
511 i
== RENAME_FLAG_COPY
) {
515 io
.ntrename
.in
.old_name
= fname2
;
516 io
.ntrename
.in
.new_name
= fname1
;
517 io
.ntrename
.in
.flags
= i
;
518 io
.ntrename
.in
.attrib
= 0;
519 io
.ntrename
.in
.cluster_size
= 0;
520 status
= smb_raw_rename(cli
->tree
, &io
);
521 if (TARGET_IS_WIN7(tctx
)){
522 if (!NT_STATUS_EQUAL(status
,
523 NT_STATUS_INVALID_PARAMETER
)) {
524 torture_warning(tctx
, "flags=0x%x status=%s\n",
525 i
, nt_errstr(status
));
528 if (!NT_STATUS_EQUAL(status
,
529 NT_STATUS_ACCESS_DENIED
)) {
530 torture_warning(tctx
, "flags=0x%x status=%s\n",
531 i
, nt_errstr(status
));
537 smb_raw_exit(cli
->session
);
538 smbcli_deltree(cli
->tree
, BASEDIR
);
545 static bool test_dir_rename(struct torture_context
*tctx
, struct smbcli_state
*cli
)
548 union smb_rename ren_io
;
550 const char *dname1
= BASEDIR
"\\dir_for_rename";
551 const char *dname2
= BASEDIR
"\\renamed_dir";
552 const char *dname1_long
= BASEDIR
"\\dir_for_rename_long";
553 const char *fname
= BASEDIR
"\\dir_for_rename\\file.txt";
554 const char *sname
= BASEDIR
"\\renamed_dir:a stream:$DATA";
558 torture_comment(tctx
, "Checking rename on a directory containing an open file.\n");
560 if (!torture_setup_dir(cli
, BASEDIR
)) {
564 /* create a directory */
565 smbcli_rmdir(cli
->tree
, dname1
);
566 smbcli_rmdir(cli
->tree
, dname2
);
567 smbcli_rmdir(cli
->tree
, dname1_long
);
568 smbcli_unlink(cli
->tree
, dname1
);
569 smbcli_unlink(cli
->tree
, dname2
);
570 smbcli_unlink(cli
->tree
, dname1_long
);
573 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
574 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
575 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
576 io
.ntcreatex
.in
.alloc_size
= 0;
577 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
578 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
579 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
580 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
581 io
.ntcreatex
.in
.fname
= dname1
;
582 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
583 CHECK_STATUS(status
, NT_STATUS_OK
);
585 fnum
= io
.ntcreatex
.out
.file
.fnum
;
586 smbcli_close(cli
->tree
, fnum
);
588 /* create the longname directory */
589 io
.ntcreatex
.in
.fname
= dname1_long
;
590 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
591 CHECK_STATUS(status
, NT_STATUS_OK
);
593 fnum
= io
.ntcreatex
.out
.file
.fnum
;
594 smbcli_close(cli
->tree
, fnum
);
596 /* Now create and hold open a file. */
599 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
600 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
601 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
602 io
.ntcreatex
.in
.alloc_size
= 0;
603 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
604 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
605 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
| NTCREATEX_SHARE_ACCESS_DELETE
;
606 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
607 io
.ntcreatex
.in
.create_options
= 0;
608 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
609 io
.ntcreatex
.in
.security_flags
= 0;
610 io
.ntcreatex
.in
.fname
= fname
;
612 /* Create the file. */
614 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
615 CHECK_STATUS(status
, NT_STATUS_OK
);
616 fnum
= io
.ntcreatex
.out
.file
.fnum
;
618 /* Now try and rename the directory. */
621 ren_io
.generic
.level
= RAW_RENAME_RENAME
;
622 ren_io
.rename
.in
.pattern1
= dname1
;
623 ren_io
.rename
.in
.pattern2
= dname2
;
624 ren_io
.rename
.in
.attrib
= 0;
626 status
= smb_raw_rename(cli
->tree
, &ren_io
);
627 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
629 /* Close the file and try the rename. */
630 smbcli_close(cli
->tree
, fnum
);
632 status
= smb_raw_rename(cli
->tree
, &ren_io
);
633 CHECK_STATUS(status
, NT_STATUS_OK
);
636 * Now try just holding a second handle on the directory and holding
637 * it open across a rename. This should be allowed.
639 io
.ntcreatex
.in
.fname
= dname2
;
640 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
642 io
.ntcreatex
.in
.access_mask
= SEC_STD_READ_CONTROL
|
643 SEC_FILE_READ_ATTRIBUTE
| SEC_FILE_READ_EA
| SEC_FILE_READ_DATA
;
645 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
646 CHECK_STATUS(status
, NT_STATUS_OK
);
647 fnum
= io
.ntcreatex
.out
.file
.fnum
;
649 ren_io
.generic
.level
= RAW_RENAME_RENAME
;
650 ren_io
.rename
.in
.pattern1
= dname2
;
651 ren_io
.rename
.in
.pattern2
= dname1
;
652 ren_io
.rename
.in
.attrib
= 0;
654 status
= smb_raw_rename(cli
->tree
, &ren_io
);
655 CHECK_STATUS(status
, NT_STATUS_OK
);
657 /* close our handle to the directory. */
658 smbcli_close(cli
->tree
, fnum
);
660 /* Open a handle on the long name, and then
661 * try a rename. This would catch a regression
664 io
.ntcreatex
.in
.fname
= dname1_long
;
665 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
667 io
.ntcreatex
.in
.access_mask
= SEC_STD_READ_CONTROL
|
668 SEC_FILE_READ_ATTRIBUTE
| SEC_FILE_READ_EA
| SEC_FILE_READ_DATA
;
670 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
671 CHECK_STATUS(status
, NT_STATUS_OK
);
672 fnum
= io
.ntcreatex
.out
.file
.fnum
;
674 ren_io
.generic
.level
= RAW_RENAME_RENAME
;
675 ren_io
.rename
.in
.pattern1
= dname1
;
676 ren_io
.rename
.in
.pattern2
= dname2
;
677 ren_io
.rename
.in
.attrib
= 0;
679 status
= smb_raw_rename(cli
->tree
, &ren_io
);
680 CHECK_STATUS(status
, NT_STATUS_OK
);
682 /* close our handle to the longname directory. */
683 smbcli_close(cli
->tree
, fnum
);
686 * Now try opening a stream on the directory and holding it open
687 * across a rename. This should be allowed.
689 io
.ntcreatex
.in
.fname
= sname
;
691 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
692 CHECK_STATUS(status
, NT_STATUS_OK
);
693 fnum
= io
.ntcreatex
.out
.file
.fnum
;
695 ren_io
.generic
.level
= RAW_RENAME_RENAME
;
696 ren_io
.rename
.in
.pattern1
= dname2
;
697 ren_io
.rename
.in
.pattern2
= dname1
;
698 ren_io
.rename
.in
.attrib
= 0;
700 status
= smb_raw_rename(cli
->tree
, &ren_io
);
701 CHECK_STATUS(status
, NT_STATUS_OK
);
706 smbcli_close(cli
->tree
, fnum
);
708 smb_raw_exit(cli
->session
);
709 smbcli_deltree(cli
->tree
, BASEDIR
);
713 extern bool test_trans2rename(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
);
714 extern bool test_nttransrename(struct torture_context
*tctx
, struct smbcli_state
*cli1
);
717 basic testing of rename calls
719 struct torture_suite
*torture_raw_rename(TALLOC_CTX
*mem_ctx
)
721 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "rename");
723 torture_suite_add_1smb_test(suite
, "mv", test_mv
);
724 /* test_trans2rename and test_nttransrename are actually in torture/raw/oplock.c to
725 use the handlers and macros there. */
726 torture_suite_add_2smb_test(suite
, "trans2rename", test_trans2rename
);
727 torture_suite_add_1smb_test(suite
, "nttransrename", test_nttransrename
);
728 torture_suite_add_1smb_test(suite
, "ntrename", test_ntrename
);
729 torture_suite_add_1smb_test(suite
, "osxrename", test_osxrename
);
730 torture_suite_add_1smb_test(suite
, "directory rename", test_dir_rename
);