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 "torture/torture.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "libcli/libcli.h"
24 #include "torture/util.h"
26 #define CHECK_STATUS(status, correct) do { \
27 if (!NT_STATUS_EQUAL(status, correct)) { \
28 printf("(%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 printf("(%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 printf("Testing SMBmv\n");
61 if (!torture_setup_dir(cli, BASEDIR)) {
65 printf("Trying simple rename\n");
67 op.generic.level = RAW_OPEN_NTCREATEX;
68 op.ntcreatex.in.root_fid = 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 printf("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 printf("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 printf("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 printf("(%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 printf("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 printf("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 printf("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 printf("and again\n");
159 status = smb_raw_rename(cli->tree, &io);
160 CHECK_STATUS(status, NT_STATUS_OK);
162 printf("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 printf("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);
195 static bool test_ntrename(struct torture_context *tctx,
196 struct smbcli_state *cli)
202 const char *fname1 = BASEDIR "\\test1.txt";
203 const char *fname2 = BASEDIR "\\test2.txt";
204 union smb_fileinfo finfo;
206 printf("Testing SMBntrename\n");
208 if (!torture_setup_dir(cli, BASEDIR)) {
212 printf("Trying simple rename\n");
214 fnum = create_complex_file(cli, tctx, fname1);
216 io.generic.level = RAW_RENAME_NTRENAME;
217 io.ntrename.in.old_name = fname1;
218 io.ntrename.in.new_name = fname2;
219 io.ntrename.in.attrib = 0;
220 io.ntrename.in.cluster_size = 0;
221 io.ntrename.in.flags = RENAME_FLAG_RENAME;
223 status = smb_raw_rename(cli->tree, &io);
224 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
226 smb_raw_exit(cli->session);
227 status = smb_raw_rename(cli->tree, &io);
228 CHECK_STATUS(status, NT_STATUS_OK);
230 printf("Trying self rename\n");
231 io.ntrename.in.old_name = fname2;
232 io.ntrename.in.new_name = fname2;
233 status = smb_raw_rename(cli->tree, &io);
234 CHECK_STATUS(status, NT_STATUS_OK);
236 io.ntrename.in.old_name = fname1;
237 io.ntrename.in.new_name = fname1;
238 status = smb_raw_rename(cli->tree, &io);
239 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
241 printf("trying wildcard rename\n");
242 io.ntrename.in.old_name = BASEDIR "\\*.txt";
243 io.ntrename.in.new_name = fname1;
245 status = smb_raw_rename(cli->tree, &io);
246 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
248 printf("Checking attrib handling\n");
249 torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN);
250 io.ntrename.in.old_name = fname2;
251 io.ntrename.in.new_name = fname1;
252 io.ntrename.in.attrib = 0;
253 status = smb_raw_rename(cli->tree, &io);
254 CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
256 io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
257 status = smb_raw_rename(cli->tree, &io);
258 CHECK_STATUS(status, NT_STATUS_OK);
260 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
262 printf("Checking hard link\n");
263 io.ntrename.in.old_name = fname1;
264 io.ntrename.in.new_name = fname2;
265 io.ntrename.in.attrib = 0;
266 io.ntrename.in.flags = RENAME_FLAG_HARD_LINK;
267 status = smb_raw_rename(cli->tree, &io);
268 CHECK_STATUS(status, NT_STATUS_OK);
270 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
272 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
273 finfo.generic.in.file.path = fname2;
274 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
275 CHECK_STATUS(status, NT_STATUS_OK);
276 CHECK_VALUE(finfo.all_info.out.nlink, 2);
277 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
279 finfo.generic.in.file.path = fname1;
280 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
281 CHECK_STATUS(status, NT_STATUS_OK);
282 CHECK_VALUE(finfo.all_info.out.nlink, 2);
283 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
285 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
287 smbcli_unlink(cli->tree, fname2);
289 finfo.generic.in.file.path = fname1;
290 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
291 CHECK_STATUS(status, NT_STATUS_OK);
292 CHECK_VALUE(finfo.all_info.out.nlink, 1);
293 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
295 printf("Checking copy\n");
296 io.ntrename.in.old_name = fname1;
297 io.ntrename.in.new_name = fname2;
298 io.ntrename.in.attrib = 0;
299 io.ntrename.in.flags = RENAME_FLAG_COPY;
300 status = smb_raw_rename(cli->tree, &io);
301 CHECK_STATUS(status, NT_STATUS_OK);
303 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
304 finfo.generic.in.file.path = fname1;
305 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
306 CHECK_STATUS(status, NT_STATUS_OK);
307 CHECK_VALUE(finfo.all_info.out.nlink, 1);
308 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
310 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
311 finfo.generic.in.file.path = fname2;
312 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
313 CHECK_STATUS(status, NT_STATUS_OK);
314 CHECK_VALUE(finfo.all_info.out.nlink, 1);
315 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
317 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
319 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
320 finfo.generic.in.file.path = fname2;
321 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
322 CHECK_STATUS(status, NT_STATUS_OK);
323 CHECK_VALUE(finfo.all_info.out.nlink, 1);
324 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
326 finfo.generic.in.file.path = fname1;
327 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
328 CHECK_STATUS(status, NT_STATUS_OK);
329 CHECK_VALUE(finfo.all_info.out.nlink, 1);
330 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
332 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
334 smbcli_unlink(cli->tree, fname2);
336 finfo.generic.in.file.path = fname1;
337 status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
338 CHECK_STATUS(status, NT_STATUS_OK);
339 CHECK_VALUE(finfo.all_info.out.nlink, 1);
341 printf("Checking invalid flags\n");
342 io.ntrename.in.old_name = fname1;
343 io.ntrename.in.new_name = fname2;
344 io.ntrename.in.attrib = 0;
345 io.ntrename.in.flags = 0;
346 status = smb_raw_rename(cli->tree, &io);
347 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
349 io.ntrename.in.flags = 300;
350 status = smb_raw_rename(cli->tree, &io);
351 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
353 io.ntrename.in.flags = 0x106;
354 status = smb_raw_rename(cli->tree, &io);
355 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
357 printf("Checking unknown field\n");
358 io.ntrename.in.old_name = fname1;
359 io.ntrename.in.new_name = fname2;
360 io.ntrename.in.attrib = 0;
361 io.ntrename.in.flags = RENAME_FLAG_RENAME;
362 io.ntrename.in.cluster_size = 0xff;
363 status = smb_raw_rename(cli->tree, &io);
364 CHECK_STATUS(status, NT_STATUS_OK);
366 printf("Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");
368 io.ntrename.in.old_name = fname2;
369 io.ntrename.in.new_name = fname1;
370 io.ntrename.in.attrib = 0;
371 io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
372 io.ntrename.in.cluster_size = 1;
373 status = smb_raw_rename(cli->tree, &io);
374 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
376 io.ntrename.in.flags = RENAME_FLAG_COPY;
377 status = smb_raw_rename(cli->tree, &io);
378 CHECK_STATUS(status, NT_STATUS_OK);
383 fnum = smbcli_open(cli->tree, fname1, O_RDWR, DENY_NONE);
384 memset(buf, 1, sizeof(buf));
385 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
386 smbcli_close(cli->tree, fnum);
388 fnum = smbcli_open(cli->tree, fname2, O_RDWR, DENY_NONE);
389 memset(buf, 1, sizeof(buf));
390 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)-1);
391 smbcli_close(cli->tree, fnum);
393 torture_all_info(cli->tree, fname1);
394 torture_all_info(cli->tree, fname2);
398 io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
399 status = smb_raw_rename(cli->tree, &io);
400 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
402 for (i=0;i<20000;i++) {
403 io.ntrename.in.cluster_size = i;
404 status = smb_raw_rename(cli->tree, &io);
405 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
406 printf("i=%d status=%s\n", i, nt_errstr(status));
411 printf("Checking other flags\n");
413 for (i=0;i<0xFFF;i++) {
414 if (i == RENAME_FLAG_RENAME ||
415 i == RENAME_FLAG_HARD_LINK ||
416 i == RENAME_FLAG_COPY) {
420 io.ntrename.in.old_name = fname2;
421 io.ntrename.in.new_name = fname1;
422 io.ntrename.in.flags = i;
423 io.ntrename.in.attrib = 0;
424 io.ntrename.in.cluster_size = 0;
425 status = smb_raw_rename(cli->tree, &io);
426 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
427 printf("flags=0x%x status=%s\n", i, nt_errstr(status));
432 smb_raw_exit(cli->session);
433 smbcli_deltree(cli->tree, BASEDIR);
439 basic testing of rename calls
441 struct torture_suite *torture_raw_rename(TALLOC_CTX *mem_ctx)
443 struct torture_suite *suite = torture_suite_create(mem_ctx, "RENAME");
445 torture_suite_add_1smb_test(suite, "mv", test_mv);
446 torture_suite_add_1smb_test(suite, "ntrename", test_ntrename);