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"
24 #define CHECK_STATUS(status, correct) do { \
25 if (!NT_STATUS_EQUAL(status, correct)) { \
26 torture_result(tctx, TORTURE_FAIL, \
27 "(%s) Incorrect status %s - should be %s\n", \
28 __location__, nt_errstr(status), nt_errstr(correct)); \
33 #define CHECK_VALUE(v, correct) do { \
34 if ((v) != (correct)) { \
35 torture_result(tctx, TORTURE_FAIL, \
36 "(%s) Incorrect %s %d - should be %d\n", \
37 __location__, #v, (int)v, (int)correct); \
41 #define BASEDIR "\\testrename"
46 static bool test_mv(struct torture_context *tctx,
47 struct smbcli_state *cli)
53 const char *fname1 = BASEDIR "\\test1.txt";
54 const char *fname2 = BASEDIR "\\test2.txt";
55 const char *Fname1 = BASEDIR "\\Test1.txt";
56 union smb_fileinfo finfo;
59 torture_comment(tctx, "Testing SMBmv\n");
61 if (!torture_setup_dir(cli, BASEDIR)) {
65 torture_comment(tctx, "Trying simple rename\n");
67 op.generic.level = RAW_OPEN_NTCREATEX;
68 op.ntcreatex.in.root_fid.fnum = 0;
69 op.ntcreatex.in.flags = 0;
70 op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
71 op.ntcreatex.in.create_options = 0;
72 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
73 op.ntcreatex.in.share_access =
74 NTCREATEX_SHARE_ACCESS_READ |
75 NTCREATEX_SHARE_ACCESS_WRITE;
76 op.ntcreatex.in.alloc_size = 0;
77 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
78 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
79 op.ntcreatex.in.security_flags = 0;
80 op.ntcreatex.in.fname = fname1;
82 status = smb_raw_open(cli->tree, tctx, &op);
83 CHECK_STATUS(status, NT_STATUS_OK);
84 fnum = op.ntcreatex.out.file.fnum;
86 io.generic.level = RAW_RENAME_RENAME;
87 io.rename.in.pattern1 = fname1;
88 io.rename.in.pattern2 = fname2;
89 io.rename.in.attrib = 0;
91 torture_comment(tctx, "trying rename while first file open\n");
92 status = smb_raw_rename(cli->tree, &io);
93 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
95 smbcli_close(cli->tree, fnum);
97 op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
98 op.ntcreatex.in.share_access =
99 NTCREATEX_SHARE_ACCESS_DELETE |
100 NTCREATEX_SHARE_ACCESS_READ |
101 NTCREATEX_SHARE_ACCESS_WRITE;
102 status = smb_raw_open(cli->tree, tctx, &op);
103 CHECK_STATUS(status, NT_STATUS_OK);
104 fnum = op.ntcreatex.out.file.fnum;
106 torture_comment(tctx, "trying rename while first file open with SHARE_ACCESS_DELETE\n");
107 status = smb_raw_rename(cli->tree, &io);
108 CHECK_STATUS(status, NT_STATUS_OK);
110 io.rename.in.pattern1 = fname2;
111 io.rename.in.pattern2 = fname1;
112 status = smb_raw_rename(cli->tree, &io);
113 CHECK_STATUS(status, NT_STATUS_OK);
115 torture_comment(tctx, "Trying case-changing rename\n");
116 io.rename.in.pattern1 = fname1;
117 io.rename.in.pattern2 = Fname1;
118 status = smb_raw_rename(cli->tree, &io);
119 CHECK_STATUS(status, NT_STATUS_OK);
121 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
122 finfo.all_info.in.file.path = fname1;
123 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
124 CHECK_STATUS(status, NT_STATUS_OK);
125 if (strcmp(finfo.all_info.out.fname.s, Fname1) != 0) {
126 torture_warning(tctx, "(%s) Incorrect filename [%s] after case-changing "
127 "rename, should be [%s]\n", __location__,
128 finfo.all_info.out.fname.s, Fname1);
131 io.rename.in.pattern1 = fname1;
132 io.rename.in.pattern2 = fname2;
134 torture_comment(tctx, "trying rename while not open\n");
135 smb_raw_exit(cli->session);
136 status = smb_raw_rename(cli->tree, &io);
137 CHECK_STATUS(status, NT_STATUS_OK);
139 torture_comment(tctx, "Trying self rename\n");
140 io.rename.in.pattern1 = fname2;
141 io.rename.in.pattern2 = fname2;
142 status = smb_raw_rename(cli->tree, &io);
143 CHECK_STATUS(status, NT_STATUS_OK);
145 io.rename.in.pattern1 = fname1;
146 io.rename.in.pattern2 = fname1;
147 status = smb_raw_rename(cli->tree, &io);
148 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
151 torture_comment(tctx, "trying wildcard rename\n");
152 io.rename.in.pattern1 = BASEDIR "\\*.txt";
153 io.rename.in.pattern2 = fname1;
155 status = smb_raw_rename(cli->tree, &io);
156 CHECK_STATUS(status, NT_STATUS_OK);
158 torture_comment(tctx, "and again\n");
159 status = smb_raw_rename(cli->tree, &io);
160 CHECK_STATUS(status, NT_STATUS_OK);
162 torture_comment(tctx, "Trying extension change\n");
163 io.rename.in.pattern1 = BASEDIR "\\*.txt";
164 io.rename.in.pattern2 = BASEDIR "\\*.bak";
165 status = smb_raw_rename(cli->tree, &io);
166 CHECK_STATUS(status, NT_STATUS_OK);
168 status = smb_raw_rename(cli->tree, &io);
169 CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
171 torture_comment(tctx, "Checking attrib handling\n");
172 torture_set_file_attribute(cli->tree, BASEDIR "\\test1.bak", FILE_ATTRIBUTE_HIDDEN);
173 io.rename.in.pattern1 = BASEDIR "\\test1.bak";
174 io.rename.in.pattern2 = BASEDIR "\\*.txt";
175 io.rename.in.attrib = 0;
176 status = smb_raw_rename(cli->tree, &io);
177 CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
179 io.rename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
180 status = smb_raw_rename(cli->tree, &io);
181 CHECK_STATUS(status, NT_STATUS_OK);
184 smbcli_close(cli->tree, fnum);
185 smb_raw_exit(cli->session);
186 smbcli_deltree(cli->tree, BASEDIR);
191 static bool test_osxrename(struct torture_context *tctx,
192 struct smbcli_state *cli)
195 union smb_unlink io_un;
199 const char *fname1 = BASEDIR "\\test1";
200 const char *FNAME1 = BASEDIR "\\TEST1";
201 union smb_fileinfo finfo;
204 torture_comment(tctx, "\nTesting OSX Rename\n");
205 if (!torture_setup_dir(cli, BASEDIR)) {
208 op.generic.level = RAW_OPEN_NTCREATEX;
209 op.ntcreatex.in.root_fid.fnum = 0;
210 op.ntcreatex.in.flags = 0;
211 op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
212 op.ntcreatex.in.create_options = 0;
213 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
214 op.ntcreatex.in.share_access =
215 NTCREATEX_SHARE_ACCESS_READ |
216 NTCREATEX_SHARE_ACCESS_WRITE;
217 op.ntcreatex.in.alloc_size = 0;
218 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
219 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
220 op.ntcreatex.in.security_flags = 0;
221 op.ntcreatex.in.fname = fname1;
223 status = smb_raw_open(cli->tree, tctx, &op);
224 CHECK_STATUS(status, NT_STATUS_OK);
225 fnum = op.ntcreatex.out.file.fnum;
227 io.generic.level = RAW_RENAME_RENAME;
228 io.rename.in.attrib = 0;
230 smbcli_close(cli->tree, fnum);
232 /* Rename by changing case. First check for the
233 * existence of the file with the "newname".
234 * If we find one and both the output and input are same case,
237 torture_comment(tctx, "Checking os X rename (case changing)\n");
239 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
240 finfo.all_info.in.file.path = FNAME1;
241 torture_comment(tctx, "Looking for file %s \n",FNAME1);
242 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
244 if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
245 torture_comment(tctx, "Name of the file found %s \n", finfo.all_info.out.fname.s);
246 if (strcmp(finfo.all_info.out.fname.s, finfo.all_info.in.file.path) == 0) {
247 /* If file is found with the same case delete it */
248 torture_comment(tctx, "Deleting File %s \n", finfo.all_info.out.fname.s);
249 io_un.unlink.in.pattern = finfo.all_info.out.fname.s;
250 io_un.unlink.in.attrib = 0;
251 status = smb_raw_unlink(cli->tree, &io_un);
252 CHECK_STATUS(status, NT_STATUS_OK);
256 io.rename.in.pattern1 = fname1;
257 io.rename.in.pattern2 = FNAME1;
258 status = smb_raw_rename(cli->tree, &io);
259 CHECK_STATUS(status, NT_STATUS_OK);
261 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
262 finfo.all_info.in.file.path = fname1;
263 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
264 CHECK_STATUS(status, NT_STATUS_OK);
265 torture_comment(tctx, "File name after rename %s \n",finfo.all_info.out.fname.s);
268 smbcli_close(cli->tree, fnum);
269 smb_raw_exit(cli->session);
270 smbcli_deltree(cli->tree, BASEDIR);
277 static bool test_ntrename(struct torture_context *tctx,
278 struct smbcli_state *cli)
284 const char *fname1 = BASEDIR "\\test1.txt";
285 const char *fname2 = BASEDIR "\\test2.txt";
286 union smb_fileinfo finfo;
288 torture_comment(tctx, "Testing SMBntrename\n");
290 if (!torture_setup_dir(cli, BASEDIR)) {
294 torture_comment(tctx, "Trying simple rename\n");
296 fnum = create_complex_file(cli, tctx, fname1);
298 io.generic.level = RAW_RENAME_NTRENAME;
299 io.ntrename.in.old_name = fname1;
300 io.ntrename.in.new_name = fname2;
301 io.ntrename.in.attrib = 0;
302 io.ntrename.in.cluster_size = 0;
303 io.ntrename.in.flags = RENAME_FLAG_RENAME;
305 status = smb_raw_rename(cli->tree, &io);
306 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
308 smbcli_close(cli->tree, fnum);
309 status = smb_raw_rename(cli->tree, &io);
310 CHECK_STATUS(status, NT_STATUS_OK);
312 torture_comment(tctx, "Trying self rename\n");
313 io.ntrename.in.old_name = fname2;
314 io.ntrename.in.new_name = fname2;
315 status = smb_raw_rename(cli->tree, &io);
316 CHECK_STATUS(status, NT_STATUS_OK);
318 io.ntrename.in.old_name = fname1;
319 io.ntrename.in.new_name = fname1;
320 status = smb_raw_rename(cli->tree, &io);
321 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
323 torture_comment(tctx, "trying wildcard rename\n");
324 io.ntrename.in.old_name = BASEDIR "\\*.txt";
325 io.ntrename.in.new_name = fname1;
327 status = smb_raw_rename(cli->tree, &io);
328 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
330 torture_comment(tctx, "Checking attrib handling\n");
331 torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN);
332 io.ntrename.in.old_name = fname2;
333 io.ntrename.in.new_name = fname1;
334 io.ntrename.in.attrib = 0;
335 status = smb_raw_rename(cli->tree, &io);
336 CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
338 io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
339 status = smb_raw_rename(cli->tree, &io);
340 CHECK_STATUS(status, NT_STATUS_OK);
342 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
344 torture_comment(tctx, "Checking hard link\n");
345 io.ntrename.in.old_name = fname1;
346 io.ntrename.in.new_name = fname2;
347 io.ntrename.in.attrib = 0;
348 io.ntrename.in.flags = RENAME_FLAG_HARD_LINK;
349 status = smb_raw_rename(cli->tree, &io);
350 CHECK_STATUS(status, NT_STATUS_OK);
352 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
354 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
355 finfo.generic.in.file.path = fname2;
356 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
357 CHECK_STATUS(status, NT_STATUS_OK);
358 CHECK_VALUE(finfo.all_info.out.nlink, 2);
359 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
361 finfo.generic.in.file.path = fname1;
362 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
363 CHECK_STATUS(status, NT_STATUS_OK);
364 CHECK_VALUE(finfo.all_info.out.nlink, 2);
365 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
367 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
369 smbcli_unlink(cli->tree, fname2);
371 finfo.generic.in.file.path = fname1;
372 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
373 CHECK_STATUS(status, NT_STATUS_OK);
374 CHECK_VALUE(finfo.all_info.out.nlink, 1);
375 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
377 torture_comment(tctx, "Checking copy\n");
378 io.ntrename.in.old_name = fname1;
379 io.ntrename.in.new_name = fname2;
380 io.ntrename.in.attrib = 0;
381 io.ntrename.in.flags = RENAME_FLAG_COPY;
382 status = smb_raw_rename(cli->tree, &io);
383 CHECK_STATUS(status, NT_STATUS_OK);
385 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
386 finfo.generic.in.file.path = fname1;
387 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
388 CHECK_STATUS(status, NT_STATUS_OK);
389 CHECK_VALUE(finfo.all_info.out.nlink, 1);
390 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
392 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
393 finfo.generic.in.file.path = fname2;
394 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
395 CHECK_STATUS(status, NT_STATUS_OK);
396 CHECK_VALUE(finfo.all_info.out.nlink, 1);
397 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
399 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
401 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
402 finfo.generic.in.file.path = fname2;
403 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
404 CHECK_STATUS(status, NT_STATUS_OK);
405 CHECK_VALUE(finfo.all_info.out.nlink, 1);
406 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
408 finfo.generic.in.file.path = fname1;
409 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
410 CHECK_STATUS(status, NT_STATUS_OK);
411 CHECK_VALUE(finfo.all_info.out.nlink, 1);
412 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
414 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
416 smbcli_unlink(cli->tree, fname2);
418 finfo.generic.in.file.path = fname1;
419 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
420 CHECK_STATUS(status, NT_STATUS_OK);
421 CHECK_VALUE(finfo.all_info.out.nlink, 1);
423 torture_comment(tctx, "Checking invalid flags\n");
424 io.ntrename.in.old_name = fname1;
425 io.ntrename.in.new_name = fname2;
426 io.ntrename.in.attrib = 0;
427 io.ntrename.in.flags = 0;
428 status = smb_raw_rename(cli->tree, &io);
429 if (TARGET_IS_WIN7(tctx)) {
430 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
432 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
435 io.ntrename.in.flags = 300;
436 status = smb_raw_rename(cli->tree, &io);
437 if (TARGET_IS_WIN7(tctx)) {
438 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
440 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
443 io.ntrename.in.flags = 0x106;
444 status = smb_raw_rename(cli->tree, &io);
445 if (TARGET_IS_WIN7(tctx)) {
446 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
448 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
451 torture_comment(tctx, "Checking unknown field\n");
452 io.ntrename.in.old_name = fname1;
453 io.ntrename.in.new_name = fname2;
454 io.ntrename.in.attrib = 0;
455 io.ntrename.in.flags = RENAME_FLAG_RENAME;
456 io.ntrename.in.cluster_size = 0xff;
457 status = smb_raw_rename(cli->tree, &io);
458 CHECK_STATUS(status, NT_STATUS_OK);
460 torture_comment(tctx, "Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");
462 io.ntrename.in.old_name = fname2;
463 io.ntrename.in.new_name = fname1;
464 io.ntrename.in.attrib = 0;
465 io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
466 io.ntrename.in.cluster_size = 1;
467 status = smb_raw_rename(cli->tree, &io);
468 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
470 io.ntrename.in.flags = RENAME_FLAG_COPY;
471 status = smb_raw_rename(cli->tree, &io);
472 CHECK_STATUS(status, NT_STATUS_OK);
477 fnum = smbcli_open(cli->tree, fname1, O_RDWR, DENY_NONE);
478 memset(buf, 1, sizeof(buf));
479 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
480 smbcli_close(cli->tree, fnum);
482 fnum = smbcli_open(cli->tree, fname2, O_RDWR, DENY_NONE);
483 memset(buf, 1, sizeof(buf));
484 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)-1);
485 smbcli_close(cli->tree, fnum);
487 torture_all_info(cli->tree, fname1);
488 torture_all_info(cli->tree, fname2);
492 io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
493 status = smb_raw_rename(cli->tree, &io);
494 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
496 for (i=0;i<20000;i++) {
497 io.ntrename.in.cluster_size = i;
498 status = smb_raw_rename(cli->tree, &io);
499 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
500 torture_warning(tctx, "i=%d status=%s\n", i, nt_errstr(status));
505 torture_comment(tctx, "Checking other flags\n");
507 for (i=0;i<0xFFF;i++) {
508 if (i == RENAME_FLAG_RENAME ||
509 i == RENAME_FLAG_HARD_LINK ||
510 i == RENAME_FLAG_COPY) {
514 io.ntrename.in.old_name = fname2;
515 io.ntrename.in.new_name = fname1;
516 io.ntrename.in.flags = i;
517 io.ntrename.in.attrib = 0;
518 io.ntrename.in.cluster_size = 0;
519 status = smb_raw_rename(cli->tree, &io);
520 if (TARGET_IS_WIN7(tctx)){
521 if (!NT_STATUS_EQUAL(status,
522 NT_STATUS_INVALID_PARAMETER)) {
523 torture_warning(tctx, "flags=0x%x status=%s\n",
524 i, nt_errstr(status));
527 if (!NT_STATUS_EQUAL(status,
528 NT_STATUS_ACCESS_DENIED)) {
529 torture_warning(tctx, "flags=0x%x status=%s\n",
530 i, nt_errstr(status));
536 smb_raw_exit(cli->session);
537 smbcli_deltree(cli->tree, BASEDIR);
544 static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *cli)
547 union smb_rename ren_io;
549 const char *dname1 = BASEDIR "\\dir_for_rename";
550 const char *dname2 = BASEDIR "\\renamed_dir";
551 const char *dname1_long = BASEDIR "\\dir_for_rename_long";
552 const char *fname = BASEDIR "\\dir_for_rename\\file.txt";
553 const char *sname = BASEDIR "\\renamed_dir:a stream:$DATA";
557 torture_comment(tctx, "Checking rename on a directory containing an open file.\n");
559 if (!torture_setup_dir(cli, BASEDIR)) {
563 /* create a directory */
564 smbcli_rmdir(cli->tree, dname1);
565 smbcli_rmdir(cli->tree, dname2);
566 smbcli_rmdir(cli->tree, dname1_long);
567 smbcli_unlink(cli->tree, dname1);
568 smbcli_unlink(cli->tree, dname2);
569 smbcli_unlink(cli->tree, dname1_long);
572 io.generic.level = RAW_OPEN_NTCREATEX;
573 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
574 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
575 io.ntcreatex.in.alloc_size = 0;
576 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
577 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
578 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
579 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
580 io.ntcreatex.in.fname = dname1;
581 status = smb_raw_open(cli->tree, tctx, &io);
582 CHECK_STATUS(status, NT_STATUS_OK);
584 fnum = io.ntcreatex.out.file.fnum;
585 smbcli_close(cli->tree, fnum);
587 /* create the longname directory */
588 io.ntcreatex.in.fname = dname1_long;
589 status = smb_raw_open(cli->tree, tctx, &io);
590 CHECK_STATUS(status, NT_STATUS_OK);
592 fnum = io.ntcreatex.out.file.fnum;
593 smbcli_close(cli->tree, fnum);
595 /* Now create and hold open a file. */
598 io.generic.level = RAW_OPEN_NTCREATEX;
599 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
600 io.ntcreatex.in.root_fid.fnum = 0;
601 io.ntcreatex.in.alloc_size = 0;
602 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
603 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
604 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
605 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
606 io.ntcreatex.in.create_options = 0;
607 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
608 io.ntcreatex.in.security_flags = 0;
609 io.ntcreatex.in.fname = fname;
611 /* Create the file. */
613 status = smb_raw_open(cli->tree, tctx, &io);
614 CHECK_STATUS(status, NT_STATUS_OK);
615 fnum = io.ntcreatex.out.file.fnum;
617 /* Now try and rename the directory. */
620 ren_io.generic.level = RAW_RENAME_RENAME;
621 ren_io.rename.in.pattern1 = dname1;
622 ren_io.rename.in.pattern2 = dname2;
623 ren_io.rename.in.attrib = 0;
625 status = smb_raw_rename(cli->tree, &ren_io);
626 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
628 /* Close the file and try the rename. */
629 smbcli_close(cli->tree, fnum);
631 status = smb_raw_rename(cli->tree, &ren_io);
632 CHECK_STATUS(status, NT_STATUS_OK);
635 * Now try just holding a second handle on the directory and holding
636 * it open across a rename. This should be allowed.
638 io.ntcreatex.in.fname = dname2;
639 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
641 io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
642 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
644 status = smb_raw_open(cli->tree, tctx, &io);
645 CHECK_STATUS(status, NT_STATUS_OK);
646 fnum = io.ntcreatex.out.file.fnum;
648 ren_io.generic.level = RAW_RENAME_RENAME;
649 ren_io.rename.in.pattern1 = dname2;
650 ren_io.rename.in.pattern2 = dname1;
651 ren_io.rename.in.attrib = 0;
653 status = smb_raw_rename(cli->tree, &ren_io);
654 CHECK_STATUS(status, NT_STATUS_OK);
656 /* close our handle to the directory. */
657 smbcli_close(cli->tree, fnum);
659 /* Open a handle on the long name, and then
660 * try a rename. This would catch a regression
663 io.ntcreatex.in.fname = dname1_long;
664 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
666 io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
667 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
669 status = smb_raw_open(cli->tree, tctx, &io);
670 CHECK_STATUS(status, NT_STATUS_OK);
671 fnum = io.ntcreatex.out.file.fnum;
673 ren_io.generic.level = RAW_RENAME_RENAME;
674 ren_io.rename.in.pattern1 = dname1;
675 ren_io.rename.in.pattern2 = dname2;
676 ren_io.rename.in.attrib = 0;
678 status = smb_raw_rename(cli->tree, &ren_io);
679 CHECK_STATUS(status, NT_STATUS_OK);
681 /* close our handle to the longname directory. */
682 smbcli_close(cli->tree, fnum);
685 * Now try opening a stream on the directory and holding it open
686 * across a rename. This should be allowed.
688 io.ntcreatex.in.fname = sname;
690 status = smb_raw_open(cli->tree, tctx, &io);
691 CHECK_STATUS(status, NT_STATUS_OK);
692 fnum = io.ntcreatex.out.file.fnum;
694 ren_io.generic.level = RAW_RENAME_RENAME;
695 ren_io.rename.in.pattern1 = dname2;
696 ren_io.rename.in.pattern2 = dname1;
697 ren_io.rename.in.attrib = 0;
699 status = smb_raw_rename(cli->tree, &ren_io);
700 CHECK_STATUS(status, NT_STATUS_OK);
705 smbcli_close(cli->tree, fnum);
707 smb_raw_exit(cli->session);
708 smbcli_deltree(cli->tree, BASEDIR);
712 extern bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2);
713 extern bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1);
716 basic testing of rename calls
718 struct torture_suite *torture_raw_rename(TALLOC_CTX *mem_ctx)
720 struct torture_suite *suite = torture_suite_create(mem_ctx, "RENAME");
722 torture_suite_add_1smb_test(suite, "mv", test_mv);
723 /* test_trans2rename and test_nttransrename are actually in torture/raw/oplock.c to
724 use the handlers and macros there. */
725 torture_suite_add_2smb_test(suite, "trans2rename", test_trans2rename);
726 torture_suite_add_1smb_test(suite, "nttransrename", test_nttransrename);
727 torture_suite_add_1smb_test(suite, "ntrename", test_ntrename);
728 torture_suite_add_1smb_test(suite, "osxrename", test_osxrename);
729 torture_suite_add_1smb_test(suite, "directory rename", test_dir_rename);