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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "torture/torture.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/libcli.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 smbcli_state *cli, TALLOC_CTX *mem_ctx)
52 const char *fname1 = BASEDIR "\\test1.txt";
53 const char *fname2 = BASEDIR "\\test2.txt";
56 printf("Testing SMBmv\n");
58 if (!torture_setup_dir(cli, BASEDIR)) {
62 printf("Trying simple rename\n");
64 op.generic.level = RAW_OPEN_NTCREATEX;
65 op.ntcreatex.in.root_fid = 0;
66 op.ntcreatex.in.flags = 0;
67 op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
68 op.ntcreatex.in.create_options = 0;
69 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
70 op.ntcreatex.in.share_access =
71 NTCREATEX_SHARE_ACCESS_READ |
72 NTCREATEX_SHARE_ACCESS_WRITE;
73 op.ntcreatex.in.alloc_size = 0;
74 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
75 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
76 op.ntcreatex.in.security_flags = 0;
77 op.ntcreatex.in.fname = fname1;
79 status = smb_raw_open(cli->tree, mem_ctx, &op);
80 CHECK_STATUS(status, NT_STATUS_OK);
81 fnum = op.ntcreatex.file.fnum;
83 io.generic.level = RAW_RENAME_RENAME;
84 io.rename.in.pattern1 = fname1;
85 io.rename.in.pattern2 = fname2;
86 io.rename.in.attrib = 0;
88 printf("trying rename while first file open\n");
89 status = smb_raw_rename(cli->tree, &io);
90 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
92 smbcli_close(cli->tree, fnum);
94 op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
95 op.ntcreatex.in.share_access =
96 NTCREATEX_SHARE_ACCESS_DELETE |
97 NTCREATEX_SHARE_ACCESS_READ |
98 NTCREATEX_SHARE_ACCESS_WRITE;
99 status = smb_raw_open(cli->tree, mem_ctx, &op);
100 CHECK_STATUS(status, NT_STATUS_OK);
101 fnum = op.ntcreatex.file.fnum;
103 printf("trying rename while first file open with SHARE_ACCESS_DELETE\n");
104 status = smb_raw_rename(cli->tree, &io);
105 CHECK_STATUS(status, NT_STATUS_OK);
107 io.rename.in.pattern1 = fname2;
108 io.rename.in.pattern2 = fname1;
109 status = smb_raw_rename(cli->tree, &io);
110 CHECK_STATUS(status, NT_STATUS_OK);
112 io.rename.in.pattern1 = fname1;
113 io.rename.in.pattern2 = fname2;
115 printf("trying rename while not open\n");
116 smb_raw_exit(cli->session);
117 status = smb_raw_rename(cli->tree, &io);
118 CHECK_STATUS(status, NT_STATUS_OK);
120 printf("Trying self rename\n");
121 io.rename.in.pattern1 = fname2;
122 io.rename.in.pattern2 = fname2;
123 status = smb_raw_rename(cli->tree, &io);
124 CHECK_STATUS(status, NT_STATUS_OK);
126 io.rename.in.pattern1 = fname1;
127 io.rename.in.pattern2 = fname1;
128 status = smb_raw_rename(cli->tree, &io);
129 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
132 printf("trying wildcard rename\n");
133 io.rename.in.pattern1 = BASEDIR "\\*.txt";
134 io.rename.in.pattern2 = fname1;
136 status = smb_raw_rename(cli->tree, &io);
137 CHECK_STATUS(status, NT_STATUS_OK);
139 printf("and again\n");
140 status = smb_raw_rename(cli->tree, &io);
141 CHECK_STATUS(status, NT_STATUS_OK);
143 printf("Trying extension change\n");
144 io.rename.in.pattern1 = BASEDIR "\\*.txt";
145 io.rename.in.pattern2 = BASEDIR "\\*.bak";
146 status = smb_raw_rename(cli->tree, &io);
147 CHECK_STATUS(status, NT_STATUS_OK);
149 status = smb_raw_rename(cli->tree, &io);
150 CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
152 printf("Checking attrib handling\n");
153 torture_set_file_attribute(cli->tree, BASEDIR "\\test1.bak", FILE_ATTRIBUTE_HIDDEN);
154 io.rename.in.pattern1 = BASEDIR "\\test1.bak";
155 io.rename.in.pattern2 = BASEDIR "\\*.txt";
156 io.rename.in.attrib = 0;
157 status = smb_raw_rename(cli->tree, &io);
158 CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
160 io.rename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
161 status = smb_raw_rename(cli->tree, &io);
162 CHECK_STATUS(status, NT_STATUS_OK);
165 smbcli_close(cli->tree, fnum);
166 smb_raw_exit(cli->session);
167 smbcli_deltree(cli->tree, BASEDIR);
176 static BOOL test_ntrename(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
182 const char *fname1 = BASEDIR "\\test1.txt";
183 const char *fname2 = BASEDIR "\\test2.txt";
184 union smb_fileinfo finfo;
186 printf("Testing SMBntrename\n");
188 if (!torture_setup_dir(cli, BASEDIR)) {
192 printf("Trying simple rename\n");
194 fnum = create_complex_file(cli, mem_ctx, fname1);
196 io.generic.level = RAW_RENAME_NTRENAME;
197 io.ntrename.in.old_name = fname1;
198 io.ntrename.in.new_name = fname2;
199 io.ntrename.in.attrib = 0;
200 io.ntrename.in.cluster_size = 0;
201 io.ntrename.in.flags = RENAME_FLAG_RENAME;
203 status = smb_raw_rename(cli->tree, &io);
204 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
206 smb_raw_exit(cli->session);
207 status = smb_raw_rename(cli->tree, &io);
208 CHECK_STATUS(status, NT_STATUS_OK);
210 printf("Trying self rename\n");
211 io.ntrename.in.old_name = fname2;
212 io.ntrename.in.new_name = fname2;
213 status = smb_raw_rename(cli->tree, &io);
214 CHECK_STATUS(status, NT_STATUS_OK);
216 io.ntrename.in.old_name = fname1;
217 io.ntrename.in.new_name = fname1;
218 status = smb_raw_rename(cli->tree, &io);
219 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
221 printf("trying wildcard rename\n");
222 io.ntrename.in.old_name = BASEDIR "\\*.txt";
223 io.ntrename.in.new_name = fname1;
225 status = smb_raw_rename(cli->tree, &io);
226 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
228 printf("Checking attrib handling\n");
229 torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN);
230 io.ntrename.in.old_name = fname2;
231 io.ntrename.in.new_name = fname1;
232 io.ntrename.in.attrib = 0;
233 status = smb_raw_rename(cli->tree, &io);
234 CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
236 io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
237 status = smb_raw_rename(cli->tree, &io);
238 CHECK_STATUS(status, NT_STATUS_OK);
240 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
242 printf("Checking hard link\n");
243 io.ntrename.in.old_name = fname1;
244 io.ntrename.in.new_name = fname2;
245 io.ntrename.in.attrib = 0;
246 io.ntrename.in.flags = RENAME_FLAG_HARD_LINK;
247 status = smb_raw_rename(cli->tree, &io);
248 CHECK_STATUS(status, NT_STATUS_OK);
250 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
252 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
253 finfo.generic.file.path = fname2;
254 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
255 CHECK_STATUS(status, NT_STATUS_OK);
256 CHECK_VALUE(finfo.all_info.out.nlink, 2);
257 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
259 finfo.generic.file.path = fname1;
260 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
261 CHECK_STATUS(status, NT_STATUS_OK);
262 CHECK_VALUE(finfo.all_info.out.nlink, 2);
263 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
265 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
267 smbcli_unlink(cli->tree, fname2);
269 finfo.generic.file.path = fname1;
270 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
271 CHECK_STATUS(status, NT_STATUS_OK);
272 CHECK_VALUE(finfo.all_info.out.nlink, 1);
273 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
275 printf("Checking copy\n");
276 io.ntrename.in.old_name = fname1;
277 io.ntrename.in.new_name = fname2;
278 io.ntrename.in.attrib = 0;
279 io.ntrename.in.flags = RENAME_FLAG_COPY;
280 status = smb_raw_rename(cli->tree, &io);
281 CHECK_STATUS(status, NT_STATUS_OK);
283 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
284 finfo.generic.file.path = fname1;
285 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
286 CHECK_STATUS(status, NT_STATUS_OK);
287 CHECK_VALUE(finfo.all_info.out.nlink, 1);
288 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
290 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
291 finfo.generic.file.path = fname2;
292 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
293 CHECK_STATUS(status, NT_STATUS_OK);
294 CHECK_VALUE(finfo.all_info.out.nlink, 1);
295 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
297 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
299 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
300 finfo.generic.file.path = fname2;
301 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
302 CHECK_STATUS(status, NT_STATUS_OK);
303 CHECK_VALUE(finfo.all_info.out.nlink, 1);
304 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
306 finfo.generic.file.path = fname1;
307 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
308 CHECK_STATUS(status, NT_STATUS_OK);
309 CHECK_VALUE(finfo.all_info.out.nlink, 1);
310 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
312 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
314 smbcli_unlink(cli->tree, fname2);
316 finfo.generic.file.path = fname1;
317 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
318 CHECK_STATUS(status, NT_STATUS_OK);
319 CHECK_VALUE(finfo.all_info.out.nlink, 1);
321 printf("Checking invalid flags\n");
322 io.ntrename.in.old_name = fname1;
323 io.ntrename.in.new_name = fname2;
324 io.ntrename.in.attrib = 0;
325 io.ntrename.in.flags = 0;
326 status = smb_raw_rename(cli->tree, &io);
327 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
329 io.ntrename.in.flags = 300;
330 status = smb_raw_rename(cli->tree, &io);
331 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
333 io.ntrename.in.flags = 0x106;
334 status = smb_raw_rename(cli->tree, &io);
335 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
337 printf("Checking unknown field\n");
338 io.ntrename.in.old_name = fname1;
339 io.ntrename.in.new_name = fname2;
340 io.ntrename.in.attrib = 0;
341 io.ntrename.in.flags = RENAME_FLAG_RENAME;
342 io.ntrename.in.cluster_size = 0xff;
343 status = smb_raw_rename(cli->tree, &io);
344 CHECK_STATUS(status, NT_STATUS_OK);
346 printf("Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");
348 io.ntrename.in.old_name = fname2;
349 io.ntrename.in.new_name = fname1;
350 io.ntrename.in.attrib = 0;
351 io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
352 io.ntrename.in.cluster_size = 1;
353 status = smb_raw_rename(cli->tree, &io);
354 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
356 io.ntrename.in.flags = RENAME_FLAG_COPY;
357 status = smb_raw_rename(cli->tree, &io);
358 CHECK_STATUS(status, NT_STATUS_OK);
363 fnum = smbcli_open(cli->tree, fname1, O_RDWR, DENY_NONE);
364 memset(buf, 1, sizeof(buf));
365 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
366 smbcli_close(cli->tree, fnum);
368 fnum = smbcli_open(cli->tree, fname2, O_RDWR, DENY_NONE);
369 memset(buf, 1, sizeof(buf));
370 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)-1);
371 smbcli_close(cli->tree, fnum);
373 torture_all_info(cli->tree, fname1);
374 torture_all_info(cli->tree, fname2);
378 io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
379 status = smb_raw_rename(cli->tree, &io);
380 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
382 for (i=0;i<20000;i++) {
383 io.ntrename.in.cluster_size = i;
384 status = smb_raw_rename(cli->tree, &io);
385 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
386 printf("i=%d status=%s\n", i, nt_errstr(status));
391 printf("Checking other flags\n");
393 for (i=0;i<0xFFF;i++) {
394 if (i == RENAME_FLAG_RENAME ||
395 i == RENAME_FLAG_HARD_LINK ||
396 i == RENAME_FLAG_COPY) {
400 io.ntrename.in.old_name = fname2;
401 io.ntrename.in.new_name = fname1;
402 io.ntrename.in.flags = i;
403 io.ntrename.in.attrib = 0;
404 io.ntrename.in.cluster_size = 0;
405 status = smb_raw_rename(cli->tree, &io);
406 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
407 printf("flags=0x%x status=%s\n", i, nt_errstr(status));
412 smb_raw_exit(cli->session);
413 smbcli_deltree(cli->tree, BASEDIR);
419 basic testing of rename calls
421 BOOL torture_raw_rename(void)
423 struct smbcli_state *cli;
427 if (!torture_open_connection(&cli)) {
431 mem_ctx = talloc_init("torture_raw_rename");
433 if (!test_mv(cli, mem_ctx)) {
437 if (!test_ntrename(cli, mem_ctx)) {
441 torture_close_connection(cli);
442 talloc_free(mem_ctx);