vfs_ceph_new: Remove unused symbol for ceph_readdir
[Samba.git] / source4 / torture / raw / rename.c
blob16945615587be73c06d3fcc4a61edae01b4e4d6e
1 /*
2 Unix SMB/CIFS implementation.
3 rename test suite
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/>.
20 #include "includes.h"
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)); \
30 ret = false; \
31 goto done; \
32 }} while (0)
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); \
39 ret = false; \
40 }} while (0)
42 #define BASEDIR "\\testrename"
45 test SMBmv ops
47 static bool test_mv(struct torture_context *tctx,
48 struct smbcli_state *cli)
50 union smb_rename io;
51 NTSTATUS status;
52 bool ret = true;
53 int fnum = -1;
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;
58 union smb_open op;
60 torture_comment(tctx, "Testing SMBmv\n");
62 torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
64 torture_comment(tctx, "Trying simple rename\n");
66 op.generic.level = RAW_OPEN_NTCREATEX;
67 op.ntcreatex.in.root_fid.fnum = 0;
68 op.ntcreatex.in.flags = 0;
69 op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
70 op.ntcreatex.in.create_options = 0;
71 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
72 op.ntcreatex.in.share_access =
73 NTCREATEX_SHARE_ACCESS_READ |
74 NTCREATEX_SHARE_ACCESS_WRITE;
75 op.ntcreatex.in.alloc_size = 0;
76 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
77 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
78 op.ntcreatex.in.security_flags = 0;
79 op.ntcreatex.in.fname = fname1;
81 status = smb_raw_open(cli->tree, tctx, &op);
82 CHECK_STATUS(status, NT_STATUS_OK);
83 fnum = op.ntcreatex.out.file.fnum;
85 io.generic.level = RAW_RENAME_RENAME;
86 io.rename.in.pattern1 = fname1;
87 io.rename.in.pattern2 = fname2;
88 io.rename.in.attrib = 0;
90 torture_comment(tctx, "trying rename while first file open\n");
91 status = smb_raw_rename(cli->tree, &io);
92 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
94 smbcli_close(cli->tree, fnum);
96 op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
97 op.ntcreatex.in.share_access =
98 NTCREATEX_SHARE_ACCESS_DELETE |
99 NTCREATEX_SHARE_ACCESS_READ |
100 NTCREATEX_SHARE_ACCESS_WRITE;
101 status = smb_raw_open(cli->tree, tctx, &op);
102 CHECK_STATUS(status, NT_STATUS_OK);
103 fnum = op.ntcreatex.out.file.fnum;
105 torture_comment(tctx, "trying rename while first file open with SHARE_ACCESS_DELETE\n");
106 status = smb_raw_rename(cli->tree, &io);
107 CHECK_STATUS(status, NT_STATUS_OK);
109 io.rename.in.pattern1 = fname2;
110 io.rename.in.pattern2 = fname1;
111 status = smb_raw_rename(cli->tree, &io);
112 CHECK_STATUS(status, NT_STATUS_OK);
114 torture_comment(tctx, "Trying case-changing rename\n");
115 io.rename.in.pattern1 = fname1;
116 io.rename.in.pattern2 = Fname1;
117 status = smb_raw_rename(cli->tree, &io);
118 CHECK_STATUS(status, NT_STATUS_OK);
120 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
121 finfo.all_info.in.file.path = fname1;
122 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
123 CHECK_STATUS(status, NT_STATUS_OK);
124 if (strcmp(finfo.all_info.out.fname.s, Fname1) != 0) {
125 torture_warning(tctx, "(%s) Incorrect filename [%s] after case-changing "
126 "rename, should be [%s]\n", __location__,
127 finfo.all_info.out.fname.s, Fname1);
130 io.rename.in.pattern1 = fname1;
131 io.rename.in.pattern2 = fname2;
133 torture_comment(tctx, "trying rename while not open\n");
134 smb_raw_exit(cli->session);
135 status = smb_raw_rename(cli->tree, &io);
136 CHECK_STATUS(status, NT_STATUS_OK);
138 torture_comment(tctx, "Trying self rename\n");
139 io.rename.in.pattern1 = fname2;
140 io.rename.in.pattern2 = fname2;
141 status = smb_raw_rename(cli->tree, &io);
142 CHECK_STATUS(status, NT_STATUS_OK);
144 io.rename.in.pattern1 = fname1;
145 io.rename.in.pattern2 = fname1;
146 status = smb_raw_rename(cli->tree, &io);
147 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
149 done:
150 smbcli_close(cli->tree, fnum);
151 smb_raw_exit(cli->session);
152 smbcli_deltree(cli->tree, BASEDIR);
153 return ret;
157 static bool test_osxrename(struct torture_context *tctx,
158 struct smbcli_state *cli)
160 union smb_rename io;
161 union smb_unlink io_un;
162 NTSTATUS status;
163 bool ret = true;
164 int fnum = -1;
165 const char *fname1 = BASEDIR "\\test1";
166 const char *FNAME1 = BASEDIR "\\TEST1";
167 union smb_fileinfo finfo;
168 union smb_open op;
170 torture_comment(tctx, "\nTesting OSX Rename\n");
171 torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
172 op.generic.level = RAW_OPEN_NTCREATEX;
173 op.ntcreatex.in.root_fid.fnum = 0;
174 op.ntcreatex.in.flags = 0;
175 op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
176 op.ntcreatex.in.create_options = 0;
177 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
178 op.ntcreatex.in.share_access =
179 NTCREATEX_SHARE_ACCESS_READ |
180 NTCREATEX_SHARE_ACCESS_WRITE;
181 op.ntcreatex.in.alloc_size = 0;
182 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
183 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
184 op.ntcreatex.in.security_flags = 0;
185 op.ntcreatex.in.fname = fname1;
187 status = smb_raw_open(cli->tree, tctx, &op);
188 CHECK_STATUS(status, NT_STATUS_OK);
189 fnum = op.ntcreatex.out.file.fnum;
191 io.generic.level = RAW_RENAME_RENAME;
192 io.rename.in.attrib = 0;
194 smbcli_close(cli->tree, fnum);
196 /* Rename by changing case. First check for the
197 * existence of the file with the "newname".
198 * If we find one and both the output and input are same case,
199 * delete it. */
201 torture_comment(tctx, "Checking os X rename (case changing)\n");
203 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
204 finfo.all_info.in.file.path = FNAME1;
205 torture_comment(tctx, "Looking for file %s \n",FNAME1);
206 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
208 if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
209 torture_comment(tctx, "Name of the file found %s \n", finfo.all_info.out.fname.s);
210 if (strcmp(finfo.all_info.out.fname.s, finfo.all_info.in.file.path) == 0) {
211 /* If file is found with the same case delete it */
212 torture_comment(tctx, "Deleting File %s \n", finfo.all_info.out.fname.s);
213 io_un.unlink.in.pattern = finfo.all_info.out.fname.s;
214 io_un.unlink.in.attrib = 0;
215 status = smb_raw_unlink(cli->tree, &io_un);
216 CHECK_STATUS(status, NT_STATUS_OK);
220 io.rename.in.pattern1 = fname1;
221 io.rename.in.pattern2 = FNAME1;
222 status = smb_raw_rename(cli->tree, &io);
223 CHECK_STATUS(status, NT_STATUS_OK);
225 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
226 finfo.all_info.in.file.path = fname1;
227 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
228 CHECK_STATUS(status, NT_STATUS_OK);
229 torture_comment(tctx, "File name after rename %s \n",finfo.all_info.out.fname.s);
231 done:
232 smbcli_close(cli->tree, fnum);
233 smb_raw_exit(cli->session);
234 smbcli_deltree(cli->tree, BASEDIR);
235 return ret;
239 test SMBntrename ops
241 static bool test_ntrename(struct torture_context *tctx,
242 struct smbcli_state *cli)
244 union smb_rename io;
245 NTSTATUS status;
246 bool ret = true;
247 int fnum, i;
248 const char *fname1 = BASEDIR "\\test1.txt";
249 const char *fname2 = BASEDIR "\\test2.txt";
250 union smb_fileinfo finfo;
252 torture_comment(tctx, "Testing SMBntrename\n");
254 torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
256 torture_comment(tctx, "Trying simple rename\n");
258 fnum = create_complex_file(cli, tctx, fname1);
260 io.generic.level = RAW_RENAME_NTRENAME;
261 io.ntrename.in.old_name = fname1;
262 io.ntrename.in.new_name = fname2;
263 io.ntrename.in.attrib = 0;
264 io.ntrename.in.cluster_size = 0;
265 io.ntrename.in.flags = RENAME_FLAG_RENAME;
267 status = smb_raw_rename(cli->tree, &io);
268 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
270 smbcli_close(cli->tree, fnum);
271 status = smb_raw_rename(cli->tree, &io);
272 CHECK_STATUS(status, NT_STATUS_OK);
274 torture_comment(tctx, "Trying self rename\n");
275 io.ntrename.in.old_name = fname2;
276 io.ntrename.in.new_name = fname2;
277 status = smb_raw_rename(cli->tree, &io);
278 CHECK_STATUS(status, NT_STATUS_OK);
280 io.ntrename.in.old_name = fname1;
281 io.ntrename.in.new_name = fname1;
282 status = smb_raw_rename(cli->tree, &io);
283 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
285 torture_comment(tctx, "trying wildcard rename\n");
286 io.ntrename.in.old_name = BASEDIR "\\*.txt";
287 io.ntrename.in.new_name = fname1;
289 status = smb_raw_rename(cli->tree, &io);
290 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
292 torture_comment(tctx, "Checking attrib handling\n");
293 torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN);
294 io.ntrename.in.old_name = fname2;
295 io.ntrename.in.new_name = fname1;
296 io.ntrename.in.attrib = 0;
297 status = smb_raw_rename(cli->tree, &io);
298 CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
300 io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
301 status = smb_raw_rename(cli->tree, &io);
302 CHECK_STATUS(status, NT_STATUS_OK);
304 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
306 torture_comment(tctx, "Checking hard link\n");
307 io.ntrename.in.old_name = fname1;
308 io.ntrename.in.new_name = fname2;
309 io.ntrename.in.attrib = 0;
310 io.ntrename.in.flags = RENAME_FLAG_HARD_LINK;
311 status = smb_raw_rename(cli->tree, &io);
312 CHECK_STATUS(status, NT_STATUS_OK);
314 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
316 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
317 finfo.generic.in.file.path = fname2;
318 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
319 CHECK_STATUS(status, NT_STATUS_OK);
320 CHECK_VALUE(finfo.all_info.out.nlink, 2);
321 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
323 finfo.generic.in.file.path = fname1;
324 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
325 CHECK_STATUS(status, NT_STATUS_OK);
326 CHECK_VALUE(finfo.all_info.out.nlink, 2);
327 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
329 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
331 smbcli_unlink(cli->tree, fname2);
333 finfo.generic.in.file.path = fname1;
334 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
335 CHECK_STATUS(status, NT_STATUS_OK);
336 CHECK_VALUE(finfo.all_info.out.nlink, 1);
337 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
339 torture_comment(tctx, "Checking copy\n");
340 io.ntrename.in.old_name = fname1;
341 io.ntrename.in.new_name = fname2;
342 io.ntrename.in.attrib = 0;
343 io.ntrename.in.flags = RENAME_FLAG_COPY;
344 status = smb_raw_rename(cli->tree, &io);
345 CHECK_STATUS(status, NT_STATUS_OK);
347 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
348 finfo.generic.in.file.path = fname1;
349 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
350 CHECK_STATUS(status, NT_STATUS_OK);
351 CHECK_VALUE(finfo.all_info.out.nlink, 1);
352 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
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, 1);
359 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
361 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
363 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
364 finfo.generic.in.file.path = fname2;
365 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
366 CHECK_STATUS(status, NT_STATUS_OK);
367 CHECK_VALUE(finfo.all_info.out.nlink, 1);
368 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
370 finfo.generic.in.file.path = fname1;
371 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
372 CHECK_STATUS(status, NT_STATUS_OK);
373 CHECK_VALUE(finfo.all_info.out.nlink, 1);
374 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
376 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
378 smbcli_unlink(cli->tree, fname2);
380 finfo.generic.in.file.path = fname1;
381 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
382 CHECK_STATUS(status, NT_STATUS_OK);
383 CHECK_VALUE(finfo.all_info.out.nlink, 1);
385 torture_comment(tctx, "Checking invalid flags\n");
386 io.ntrename.in.old_name = fname1;
387 io.ntrename.in.new_name = fname2;
388 io.ntrename.in.attrib = 0;
389 io.ntrename.in.flags = 0;
390 status = smb_raw_rename(cli->tree, &io);
391 if (TARGET_IS_WIN7(tctx)) {
392 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
393 } else {
394 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
397 io.ntrename.in.flags = 300;
398 status = smb_raw_rename(cli->tree, &io);
399 if (TARGET_IS_WIN7(tctx)) {
400 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
401 } else {
402 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
405 io.ntrename.in.flags = 0x106;
406 status = smb_raw_rename(cli->tree, &io);
407 if (TARGET_IS_WIN7(tctx)) {
408 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
409 } else {
410 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
413 torture_comment(tctx, "Checking unknown field\n");
414 io.ntrename.in.old_name = fname1;
415 io.ntrename.in.new_name = fname2;
416 io.ntrename.in.attrib = 0;
417 io.ntrename.in.flags = RENAME_FLAG_RENAME;
418 io.ntrename.in.cluster_size = 0xff;
419 status = smb_raw_rename(cli->tree, &io);
420 CHECK_STATUS(status, NT_STATUS_OK);
422 torture_comment(tctx, "Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");
424 io.ntrename.in.old_name = fname2;
425 io.ntrename.in.new_name = fname1;
426 io.ntrename.in.attrib = 0;
427 io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
428 io.ntrename.in.cluster_size = 1;
429 status = smb_raw_rename(cli->tree, &io);
430 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
432 io.ntrename.in.flags = RENAME_FLAG_COPY;
433 status = smb_raw_rename(cli->tree, &io);
434 CHECK_STATUS(status, NT_STATUS_OK);
436 #if 0
438 char buf[16384];
439 fnum = smbcli_open(cli->tree, fname1, O_RDWR, DENY_NONE);
440 memset(buf, 1, sizeof(buf));
441 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
442 smbcli_close(cli->tree, fnum);
444 fnum = smbcli_open(cli->tree, fname2, O_RDWR, DENY_NONE);
445 memset(buf, 1, sizeof(buf));
446 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)-1);
447 smbcli_close(cli->tree, fnum);
449 torture_all_info(cli->tree, fname1);
450 torture_all_info(cli->tree, fname2);
454 io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
455 status = smb_raw_rename(cli->tree, &io);
456 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
458 for (i=0;i<20000;i++) {
459 io.ntrename.in.cluster_size = i;
460 status = smb_raw_rename(cli->tree, &io);
461 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
462 torture_warning(tctx, "i=%d status=%s\n", i, nt_errstr(status));
465 #endif
467 torture_comment(tctx, "Checking other flags\n");
469 for (i=0;i<0xFFF;i++) {
470 if (i == RENAME_FLAG_RENAME ||
471 i == RENAME_FLAG_HARD_LINK ||
472 i == RENAME_FLAG_COPY) {
473 continue;
476 io.ntrename.in.old_name = fname2;
477 io.ntrename.in.new_name = fname1;
478 io.ntrename.in.flags = i;
479 io.ntrename.in.attrib = 0;
480 io.ntrename.in.cluster_size = 0;
481 status = smb_raw_rename(cli->tree, &io);
482 if (TARGET_IS_WIN7(tctx)){
483 if (!NT_STATUS_EQUAL(status,
484 NT_STATUS_INVALID_PARAMETER)) {
485 torture_warning(tctx, "flags=0x%x status=%s\n",
486 i, nt_errstr(status));
488 } else {
489 if (!NT_STATUS_EQUAL(status,
490 NT_STATUS_ACCESS_DENIED)) {
491 torture_warning(tctx, "flags=0x%x status=%s\n",
492 i, nt_errstr(status));
497 done:
498 smb_raw_exit(cli->session);
499 smbcli_deltree(cli->tree, BASEDIR);
500 return ret;
504 test dir rename.
506 static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *cli)
508 union smb_open io;
509 union smb_rename ren_io;
510 NTSTATUS status;
511 const char *dname1 = BASEDIR "\\dir_for_rename";
512 const char *dname2 = BASEDIR "\\renamed_dir";
513 const char *dname1_long = BASEDIR "\\dir_for_rename_long";
514 const char *fname = BASEDIR "\\dir_for_rename\\file.txt";
515 const char *sname = BASEDIR "\\renamed_dir:a stream:$DATA";
516 bool ret = true;
517 int fnum = -1;
519 torture_comment(tctx, "Checking rename on a directory containing an open file.\n");
521 torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
523 /* create a directory */
524 smbcli_rmdir(cli->tree, dname1);
525 smbcli_rmdir(cli->tree, dname2);
526 smbcli_rmdir(cli->tree, dname1_long);
527 smbcli_unlink(cli->tree, dname1);
528 smbcli_unlink(cli->tree, dname2);
529 smbcli_unlink(cli->tree, dname1_long);
531 ZERO_STRUCT(io);
532 io.generic.level = RAW_OPEN_NTCREATEX;
533 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
534 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
535 io.ntcreatex.in.alloc_size = 0;
536 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
537 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
538 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
539 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
540 io.ntcreatex.in.fname = dname1;
541 status = smb_raw_open(cli->tree, tctx, &io);
542 CHECK_STATUS(status, NT_STATUS_OK);
544 fnum = io.ntcreatex.out.file.fnum;
545 smbcli_close(cli->tree, fnum);
547 /* create the longname directory */
548 io.ntcreatex.in.fname = dname1_long;
549 status = smb_raw_open(cli->tree, tctx, &io);
550 CHECK_STATUS(status, NT_STATUS_OK);
552 fnum = io.ntcreatex.out.file.fnum;
553 smbcli_close(cli->tree, fnum);
555 /* Now create and hold open a file. */
556 ZERO_STRUCT(io);
558 io.generic.level = RAW_OPEN_NTCREATEX;
559 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
560 io.ntcreatex.in.root_fid.fnum = 0;
561 io.ntcreatex.in.alloc_size = 0;
562 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
563 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
564 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
565 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
566 io.ntcreatex.in.create_options = 0;
567 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
568 io.ntcreatex.in.security_flags = 0;
569 io.ntcreatex.in.fname = fname;
571 /* Create the file. */
573 status = smb_raw_open(cli->tree, tctx, &io);
574 CHECK_STATUS(status, NT_STATUS_OK);
575 fnum = io.ntcreatex.out.file.fnum;
577 /* Now try and rename the directory. */
579 ZERO_STRUCT(ren_io);
580 ren_io.generic.level = RAW_RENAME_RENAME;
581 ren_io.rename.in.pattern1 = dname1;
582 ren_io.rename.in.pattern2 = dname2;
583 ren_io.rename.in.attrib = 0;
585 status = smb_raw_rename(cli->tree, &ren_io);
586 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
588 /* Close the file and try the rename. */
589 smbcli_close(cli->tree, fnum);
591 status = smb_raw_rename(cli->tree, &ren_io);
592 CHECK_STATUS(status, NT_STATUS_OK);
595 * Now try just holding a second handle on the directory and holding
596 * it open across a rename. This should be allowed.
598 io.ntcreatex.in.fname = dname2;
599 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
601 io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
602 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
604 status = smb_raw_open(cli->tree, tctx, &io);
605 CHECK_STATUS(status, NT_STATUS_OK);
606 fnum = io.ntcreatex.out.file.fnum;
608 ren_io.generic.level = RAW_RENAME_RENAME;
609 ren_io.rename.in.pattern1 = dname2;
610 ren_io.rename.in.pattern2 = dname1;
611 ren_io.rename.in.attrib = 0;
613 status = smb_raw_rename(cli->tree, &ren_io);
614 CHECK_STATUS(status, NT_STATUS_OK);
616 /* close our handle to the directory. */
617 smbcli_close(cli->tree, fnum);
619 /* Open a handle on the long name, and then
620 * try a rename. This would catch a regression
621 * in bug #6781.
623 io.ntcreatex.in.fname = dname1_long;
624 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
626 io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
627 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
629 status = smb_raw_open(cli->tree, tctx, &io);
630 CHECK_STATUS(status, NT_STATUS_OK);
631 fnum = io.ntcreatex.out.file.fnum;
633 ren_io.generic.level = RAW_RENAME_RENAME;
634 ren_io.rename.in.pattern1 = dname1;
635 ren_io.rename.in.pattern2 = dname2;
636 ren_io.rename.in.attrib = 0;
638 status = smb_raw_rename(cli->tree, &ren_io);
639 CHECK_STATUS(status, NT_STATUS_OK);
641 /* close our handle to the longname directory. */
642 smbcli_close(cli->tree, fnum);
645 * Now try opening a stream on the directory and holding it open
646 * across a rename. This should be allowed.
648 io.ntcreatex.in.fname = sname;
650 status = smb_raw_open(cli->tree, tctx, &io);
651 CHECK_STATUS(status, NT_STATUS_OK);
652 fnum = io.ntcreatex.out.file.fnum;
654 ren_io.generic.level = RAW_RENAME_RENAME;
655 ren_io.rename.in.pattern1 = dname2;
656 ren_io.rename.in.pattern2 = dname1;
657 ren_io.rename.in.attrib = 0;
659 status = smb_raw_rename(cli->tree, &ren_io);
660 CHECK_STATUS(status, NT_STATUS_OK);
662 done:
664 if (fnum != -1) {
665 smbcli_close(cli->tree, fnum);
667 smb_raw_exit(cli->session);
668 smbcli_deltree(cli->tree, BASEDIR);
669 return ret;
672 extern bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2);
673 extern bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1);
676 basic testing of rename calls
678 struct torture_suite *torture_raw_rename(TALLOC_CTX *mem_ctx)
680 struct torture_suite *suite = torture_suite_create(mem_ctx, "rename");
682 torture_suite_add_1smb_test(suite, "mv", test_mv);
683 /* test_trans2rename and test_nttransrename are actually in torture/raw/oplock.c to
684 use the handlers and macros there. */
685 torture_suite_add_2smb_test(suite, "trans2rename", test_trans2rename);
686 torture_suite_add_1smb_test(suite, "nttransrename", test_nttransrename);
687 torture_suite_add_1smb_test(suite, "ntrename", test_ntrename);
688 torture_suite_add_1smb_test(suite, "osxrename", test_osxrename);
689 torture_suite_add_1smb_test(suite, "directory rename", test_dir_rename);
691 return suite;