Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : rename test suite
4 : Copyright (C) Andrew Tridgell 2003
5 :
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.
10 :
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.
15 :
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/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "libcli/libcli.h"
22 : #include "torture/util.h"
23 : #include "torture/raw/proto.h"
24 :
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)
33 :
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)
41 :
42 : #define BASEDIR "\\testrename"
43 :
44 : /*
45 : test SMBmv ops
46 : */
47 6 : static bool test_mv(struct torture_context *tctx,
48 : struct smbcli_state *cli)
49 : {
50 1 : union smb_rename io;
51 1 : NTSTATUS status;
52 6 : bool ret = true;
53 6 : int fnum = -1;
54 6 : const char *fname1 = BASEDIR "\\test1.txt";
55 6 : const char *fname2 = BASEDIR "\\test2.txt";
56 6 : const char *Fname1 = BASEDIR "\\Test1.txt";
57 1 : union smb_fileinfo finfo;
58 1 : union smb_open op;
59 :
60 6 : torture_comment(tctx, "Testing SMBmv\n");
61 :
62 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
63 :
64 6 : torture_comment(tctx, "Trying simple rename\n");
65 :
66 6 : op.generic.level = RAW_OPEN_NTCREATEX;
67 6 : op.ntcreatex.in.root_fid.fnum = 0;
68 6 : op.ntcreatex.in.flags = 0;
69 6 : op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
70 6 : op.ntcreatex.in.create_options = 0;
71 6 : op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
72 6 : op.ntcreatex.in.share_access =
73 : NTCREATEX_SHARE_ACCESS_READ |
74 : NTCREATEX_SHARE_ACCESS_WRITE;
75 6 : op.ntcreatex.in.alloc_size = 0;
76 6 : op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
77 6 : op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
78 6 : op.ntcreatex.in.security_flags = 0;
79 6 : op.ntcreatex.in.fname = fname1;
80 :
81 6 : status = smb_raw_open(cli->tree, tctx, &op);
82 6 : CHECK_STATUS(status, NT_STATUS_OK);
83 6 : fnum = op.ntcreatex.out.file.fnum;
84 :
85 6 : io.generic.level = RAW_RENAME_RENAME;
86 6 : io.rename.in.pattern1 = fname1;
87 6 : io.rename.in.pattern2 = fname2;
88 6 : io.rename.in.attrib = 0;
89 :
90 6 : torture_comment(tctx, "trying rename while first file open\n");
91 6 : status = smb_raw_rename(cli->tree, &io);
92 6 : CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
93 :
94 6 : smbcli_close(cli->tree, fnum);
95 :
96 6 : op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
97 6 : op.ntcreatex.in.share_access =
98 : NTCREATEX_SHARE_ACCESS_DELETE |
99 : NTCREATEX_SHARE_ACCESS_READ |
100 : NTCREATEX_SHARE_ACCESS_WRITE;
101 6 : status = smb_raw_open(cli->tree, tctx, &op);
102 6 : CHECK_STATUS(status, NT_STATUS_OK);
103 6 : fnum = op.ntcreatex.out.file.fnum;
104 :
105 6 : torture_comment(tctx, "trying rename while first file open with SHARE_ACCESS_DELETE\n");
106 6 : status = smb_raw_rename(cli->tree, &io);
107 6 : CHECK_STATUS(status, NT_STATUS_OK);
108 :
109 6 : io.rename.in.pattern1 = fname2;
110 6 : io.rename.in.pattern2 = fname1;
111 6 : status = smb_raw_rename(cli->tree, &io);
112 6 : CHECK_STATUS(status, NT_STATUS_OK);
113 :
114 6 : torture_comment(tctx, "Trying case-changing rename\n");
115 6 : io.rename.in.pattern1 = fname1;
116 6 : io.rename.in.pattern2 = Fname1;
117 6 : status = smb_raw_rename(cli->tree, &io);
118 6 : CHECK_STATUS(status, NT_STATUS_OK);
119 :
120 6 : finfo.generic.level = RAW_FILEINFO_ALL_INFO;
121 6 : finfo.all_info.in.file.path = fname1;
122 6 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
123 6 : CHECK_STATUS(status, NT_STATUS_OK);
124 6 : if (strcmp(finfo.all_info.out.fname.s, Fname1) != 0) {
125 1 : 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);
128 : }
129 :
130 6 : io.rename.in.pattern1 = fname1;
131 6 : io.rename.in.pattern2 = fname2;
132 :
133 6 : torture_comment(tctx, "trying rename while not open\n");
134 6 : smb_raw_exit(cli->session);
135 6 : status = smb_raw_rename(cli->tree, &io);
136 6 : CHECK_STATUS(status, NT_STATUS_OK);
137 :
138 6 : torture_comment(tctx, "Trying self rename\n");
139 6 : io.rename.in.pattern1 = fname2;
140 6 : io.rename.in.pattern2 = fname2;
141 6 : status = smb_raw_rename(cli->tree, &io);
142 6 : CHECK_STATUS(status, NT_STATUS_OK);
143 :
144 6 : io.rename.in.pattern1 = fname1;
145 6 : io.rename.in.pattern2 = fname1;
146 6 : status = smb_raw_rename(cli->tree, &io);
147 6 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
148 :
149 6 : done:
150 6 : smbcli_close(cli->tree, fnum);
151 6 : smb_raw_exit(cli->session);
152 6 : smbcli_deltree(cli->tree, BASEDIR);
153 6 : return ret;
154 : }
155 :
156 :
157 6 : static bool test_osxrename(struct torture_context *tctx,
158 : struct smbcli_state *cli)
159 : {
160 1 : union smb_rename io;
161 1 : union smb_unlink io_un;
162 1 : NTSTATUS status;
163 6 : bool ret = true;
164 6 : int fnum = -1;
165 6 : const char *fname1 = BASEDIR "\\test1";
166 6 : const char *FNAME1 = BASEDIR "\\TEST1";
167 1 : union smb_fileinfo finfo;
168 1 : union smb_open op;
169 :
170 6 : torture_comment(tctx, "\nTesting OSX Rename\n");
171 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
172 6 : op.generic.level = RAW_OPEN_NTCREATEX;
173 6 : op.ntcreatex.in.root_fid.fnum = 0;
174 6 : op.ntcreatex.in.flags = 0;
175 6 : op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
176 6 : op.ntcreatex.in.create_options = 0;
177 6 : op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
178 6 : op.ntcreatex.in.share_access =
179 : NTCREATEX_SHARE_ACCESS_READ |
180 : NTCREATEX_SHARE_ACCESS_WRITE;
181 6 : op.ntcreatex.in.alloc_size = 0;
182 6 : op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
183 6 : op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
184 6 : op.ntcreatex.in.security_flags = 0;
185 6 : op.ntcreatex.in.fname = fname1;
186 :
187 6 : status = smb_raw_open(cli->tree, tctx, &op);
188 6 : CHECK_STATUS(status, NT_STATUS_OK);
189 6 : fnum = op.ntcreatex.out.file.fnum;
190 :
191 6 : io.generic.level = RAW_RENAME_RENAME;
192 6 : io.rename.in.attrib = 0;
193 :
194 6 : smbcli_close(cli->tree, fnum);
195 :
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. */
200 :
201 6 : torture_comment(tctx, "Checking os X rename (case changing)\n");
202 :
203 6 : finfo.generic.level = RAW_FILEINFO_ALL_INFO;
204 6 : finfo.all_info.in.file.path = FNAME1;
205 6 : torture_comment(tctx, "Looking for file %s \n",FNAME1);
206 6 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
207 :
208 6 : if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
209 6 : torture_comment(tctx, "Name of the file found %s \n", finfo.all_info.out.fname.s);
210 6 : 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 1 : torture_comment(tctx, "Deleting File %s \n", finfo.all_info.out.fname.s);
213 1 : io_un.unlink.in.pattern = finfo.all_info.out.fname.s;
214 1 : io_un.unlink.in.attrib = 0;
215 1 : status = smb_raw_unlink(cli->tree, &io_un);
216 1 : CHECK_STATUS(status, NT_STATUS_OK);
217 : }
218 : }
219 :
220 6 : io.rename.in.pattern1 = fname1;
221 6 : io.rename.in.pattern2 = FNAME1;
222 6 : status = smb_raw_rename(cli->tree, &io);
223 6 : CHECK_STATUS(status, NT_STATUS_OK);
224 :
225 5 : finfo.generic.level = RAW_FILEINFO_ALL_INFO;
226 5 : finfo.all_info.in.file.path = fname1;
227 5 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
228 5 : CHECK_STATUS(status, NT_STATUS_OK);
229 5 : torture_comment(tctx, "File name after rename %s \n",finfo.all_info.out.fname.s);
230 :
231 6 : done:
232 6 : smbcli_close(cli->tree, fnum);
233 6 : smb_raw_exit(cli->session);
234 6 : smbcli_deltree(cli->tree, BASEDIR);
235 6 : return ret;
236 : }
237 :
238 : /*
239 : test SMBntrename ops
240 : */
241 6 : static bool test_ntrename(struct torture_context *tctx,
242 : struct smbcli_state *cli)
243 : {
244 1 : union smb_rename io;
245 1 : NTSTATUS status;
246 6 : bool ret = true;
247 1 : int fnum, i;
248 6 : const char *fname1 = BASEDIR "\\test1.txt";
249 6 : const char *fname2 = BASEDIR "\\test2.txt";
250 1 : union smb_fileinfo finfo;
251 :
252 6 : torture_comment(tctx, "Testing SMBntrename\n");
253 :
254 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
255 :
256 6 : torture_comment(tctx, "Trying simple rename\n");
257 :
258 6 : fnum = create_complex_file(cli, tctx, fname1);
259 :
260 6 : io.generic.level = RAW_RENAME_NTRENAME;
261 6 : io.ntrename.in.old_name = fname1;
262 6 : io.ntrename.in.new_name = fname2;
263 6 : io.ntrename.in.attrib = 0;
264 6 : io.ntrename.in.cluster_size = 0;
265 6 : io.ntrename.in.flags = RENAME_FLAG_RENAME;
266 :
267 6 : status = smb_raw_rename(cli->tree, &io);
268 6 : CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
269 :
270 6 : smbcli_close(cli->tree, fnum);
271 6 : status = smb_raw_rename(cli->tree, &io);
272 6 : CHECK_STATUS(status, NT_STATUS_OK);
273 :
274 6 : torture_comment(tctx, "Trying self rename\n");
275 6 : io.ntrename.in.old_name = fname2;
276 6 : io.ntrename.in.new_name = fname2;
277 6 : status = smb_raw_rename(cli->tree, &io);
278 6 : CHECK_STATUS(status, NT_STATUS_OK);
279 :
280 6 : io.ntrename.in.old_name = fname1;
281 6 : io.ntrename.in.new_name = fname1;
282 6 : status = smb_raw_rename(cli->tree, &io);
283 6 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
284 :
285 6 : torture_comment(tctx, "trying wildcard rename\n");
286 6 : io.ntrename.in.old_name = BASEDIR "\\*.txt";
287 6 : io.ntrename.in.new_name = fname1;
288 :
289 6 : status = smb_raw_rename(cli->tree, &io);
290 6 : CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
291 :
292 6 : torture_comment(tctx, "Checking attrib handling\n");
293 6 : torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN);
294 6 : io.ntrename.in.old_name = fname2;
295 6 : io.ntrename.in.new_name = fname1;
296 6 : io.ntrename.in.attrib = 0;
297 6 : status = smb_raw_rename(cli->tree, &io);
298 6 : CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
299 :
300 6 : io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
301 6 : status = smb_raw_rename(cli->tree, &io);
302 6 : CHECK_STATUS(status, NT_STATUS_OK);
303 :
304 6 : torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
305 :
306 6 : torture_comment(tctx, "Checking hard link\n");
307 6 : io.ntrename.in.old_name = fname1;
308 6 : io.ntrename.in.new_name = fname2;
309 6 : io.ntrename.in.attrib = 0;
310 6 : io.ntrename.in.flags = RENAME_FLAG_HARD_LINK;
311 6 : status = smb_raw_rename(cli->tree, &io);
312 6 : CHECK_STATUS(status, NT_STATUS_OK);
313 :
314 6 : torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
315 :
316 6 : finfo.generic.level = RAW_FILEINFO_ALL_INFO;
317 6 : finfo.generic.in.file.path = fname2;
318 6 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
319 6 : CHECK_STATUS(status, NT_STATUS_OK);
320 6 : CHECK_VALUE(finfo.all_info.out.nlink, 2);
321 6 : CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
322 :
323 6 : finfo.generic.in.file.path = fname1;
324 6 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
325 6 : CHECK_STATUS(status, NT_STATUS_OK);
326 6 : CHECK_VALUE(finfo.all_info.out.nlink, 2);
327 6 : CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
328 :
329 6 : torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
330 :
331 6 : smbcli_unlink(cli->tree, fname2);
332 :
333 6 : finfo.generic.in.file.path = fname1;
334 6 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
335 6 : CHECK_STATUS(status, NT_STATUS_OK);
336 6 : CHECK_VALUE(finfo.all_info.out.nlink, 1);
337 6 : CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
338 :
339 6 : torture_comment(tctx, "Checking copy\n");
340 6 : io.ntrename.in.old_name = fname1;
341 6 : io.ntrename.in.new_name = fname2;
342 6 : io.ntrename.in.attrib = 0;
343 6 : io.ntrename.in.flags = RENAME_FLAG_COPY;
344 6 : status = smb_raw_rename(cli->tree, &io);
345 6 : CHECK_STATUS(status, NT_STATUS_OK);
346 :
347 6 : finfo.generic.level = RAW_FILEINFO_ALL_INFO;
348 6 : finfo.generic.in.file.path = fname1;
349 6 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
350 6 : CHECK_STATUS(status, NT_STATUS_OK);
351 6 : CHECK_VALUE(finfo.all_info.out.nlink, 1);
352 6 : CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
353 :
354 6 : finfo.generic.level = RAW_FILEINFO_ALL_INFO;
355 6 : finfo.generic.in.file.path = fname2;
356 6 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
357 6 : CHECK_STATUS(status, NT_STATUS_OK);
358 6 : CHECK_VALUE(finfo.all_info.out.nlink, 1);
359 6 : CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
360 :
361 6 : torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
362 :
363 6 : finfo.generic.level = RAW_FILEINFO_ALL_INFO;
364 6 : finfo.generic.in.file.path = fname2;
365 6 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
366 6 : CHECK_STATUS(status, NT_STATUS_OK);
367 6 : CHECK_VALUE(finfo.all_info.out.nlink, 1);
368 6 : CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
369 :
370 6 : finfo.generic.in.file.path = fname1;
371 6 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
372 6 : CHECK_STATUS(status, NT_STATUS_OK);
373 6 : CHECK_VALUE(finfo.all_info.out.nlink, 1);
374 6 : CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
375 :
376 6 : torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
377 :
378 6 : smbcli_unlink(cli->tree, fname2);
379 :
380 6 : finfo.generic.in.file.path = fname1;
381 6 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
382 6 : CHECK_STATUS(status, NT_STATUS_OK);
383 6 : CHECK_VALUE(finfo.all_info.out.nlink, 1);
384 :
385 6 : torture_comment(tctx, "Checking invalid flags\n");
386 6 : io.ntrename.in.old_name = fname1;
387 6 : io.ntrename.in.new_name = fname2;
388 6 : io.ntrename.in.attrib = 0;
389 6 : io.ntrename.in.flags = 0;
390 6 : status = smb_raw_rename(cli->tree, &io);
391 6 : if (TARGET_IS_WIN7(tctx)) {
392 0 : CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
393 : } else {
394 6 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
395 : }
396 :
397 6 : io.ntrename.in.flags = 300;
398 6 : status = smb_raw_rename(cli->tree, &io);
399 6 : if (TARGET_IS_WIN7(tctx)) {
400 0 : CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
401 : } else {
402 6 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
403 : }
404 :
405 6 : io.ntrename.in.flags = 0x106;
406 6 : status = smb_raw_rename(cli->tree, &io);
407 6 : if (TARGET_IS_WIN7(tctx)) {
408 0 : CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
409 : } else {
410 6 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
411 : }
412 :
413 6 : torture_comment(tctx, "Checking unknown field\n");
414 6 : io.ntrename.in.old_name = fname1;
415 6 : io.ntrename.in.new_name = fname2;
416 6 : io.ntrename.in.attrib = 0;
417 6 : io.ntrename.in.flags = RENAME_FLAG_RENAME;
418 6 : io.ntrename.in.cluster_size = 0xff;
419 6 : status = smb_raw_rename(cli->tree, &io);
420 6 : CHECK_STATUS(status, NT_STATUS_OK);
421 :
422 6 : torture_comment(tctx, "Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");
423 :
424 6 : io.ntrename.in.old_name = fname2;
425 6 : io.ntrename.in.new_name = fname1;
426 6 : io.ntrename.in.attrib = 0;
427 6 : io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
428 6 : io.ntrename.in.cluster_size = 1;
429 6 : status = smb_raw_rename(cli->tree, &io);
430 6 : CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
431 :
432 6 : io.ntrename.in.flags = RENAME_FLAG_COPY;
433 6 : status = smb_raw_rename(cli->tree, &io);
434 6 : CHECK_STATUS(status, NT_STATUS_OK);
435 :
436 : #if 0
437 : {
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);
443 :
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);
448 :
449 : torture_all_info(cli->tree, fname1);
450 : torture_all_info(cli->tree, fname2);
451 : }
452 :
453 :
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);
457 :
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));
463 : }
464 : }
465 : #endif
466 :
467 6 : torture_comment(tctx, "Checking other flags\n");
468 :
469 24577 : for (i=0;i<0xFFF;i++) {
470 24573 : if (i == RENAME_FLAG_RENAME ||
471 24560 : i == RENAME_FLAG_HARD_LINK ||
472 : i == RENAME_FLAG_COPY) {
473 18 : continue;
474 : }
475 :
476 24552 : io.ntrename.in.old_name = fname2;
477 24552 : io.ntrename.in.new_name = fname1;
478 24552 : io.ntrename.in.flags = i;
479 24552 : io.ntrename.in.attrib = 0;
480 24552 : io.ntrename.in.cluster_size = 0;
481 24552 : status = smb_raw_rename(cli->tree, &io);
482 24552 : if (TARGET_IS_WIN7(tctx)){
483 0 : if (!NT_STATUS_EQUAL(status,
484 : NT_STATUS_INVALID_PARAMETER)) {
485 0 : torture_warning(tctx, "flags=0x%x status=%s\n",
486 : i, nt_errstr(status));
487 : }
488 : } else {
489 24552 : if (!NT_STATUS_EQUAL(status,
490 : NT_STATUS_ACCESS_DENIED)) {
491 6 : torture_warning(tctx, "flags=0x%x status=%s\n",
492 : i, nt_errstr(status));
493 : }
494 : }
495 : }
496 :
497 6 : done:
498 6 : smb_raw_exit(cli->session);
499 6 : smbcli_deltree(cli->tree, BASEDIR);
500 6 : return ret;
501 : }
502 :
503 : /*
504 : test dir rename.
505 : */
506 6 : static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *cli)
507 : {
508 1 : union smb_open io;
509 1 : union smb_rename ren_io;
510 1 : NTSTATUS status;
511 6 : const char *dname1 = BASEDIR "\\dir_for_rename";
512 6 : const char *dname2 = BASEDIR "\\renamed_dir";
513 6 : const char *dname1_long = BASEDIR "\\dir_for_rename_long";
514 6 : const char *fname = BASEDIR "\\dir_for_rename\\file.txt";
515 6 : const char *sname = BASEDIR "\\renamed_dir:a stream:$DATA";
516 6 : bool ret = true;
517 6 : int fnum = -1;
518 :
519 6 : torture_comment(tctx, "Checking rename on a directory containing an open file.\n");
520 :
521 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
522 :
523 : /* create a directory */
524 6 : smbcli_rmdir(cli->tree, dname1);
525 6 : smbcli_rmdir(cli->tree, dname2);
526 6 : smbcli_rmdir(cli->tree, dname1_long);
527 6 : smbcli_unlink(cli->tree, dname1);
528 6 : smbcli_unlink(cli->tree, dname2);
529 6 : smbcli_unlink(cli->tree, dname1_long);
530 :
531 6 : ZERO_STRUCT(io);
532 6 : io.generic.level = RAW_OPEN_NTCREATEX;
533 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
534 6 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
535 6 : io.ntcreatex.in.alloc_size = 0;
536 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
537 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
538 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
539 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
540 6 : io.ntcreatex.in.fname = dname1;
541 6 : status = smb_raw_open(cli->tree, tctx, &io);
542 6 : CHECK_STATUS(status, NT_STATUS_OK);
543 :
544 6 : fnum = io.ntcreatex.out.file.fnum;
545 6 : smbcli_close(cli->tree, fnum);
546 :
547 : /* create the longname directory */
548 6 : io.ntcreatex.in.fname = dname1_long;
549 6 : status = smb_raw_open(cli->tree, tctx, &io);
550 6 : CHECK_STATUS(status, NT_STATUS_OK);
551 :
552 6 : fnum = io.ntcreatex.out.file.fnum;
553 6 : smbcli_close(cli->tree, fnum);
554 :
555 : /* Now create and hold open a file. */
556 6 : ZERO_STRUCT(io);
557 :
558 6 : io.generic.level = RAW_OPEN_NTCREATEX;
559 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
560 6 : io.ntcreatex.in.root_fid.fnum = 0;
561 6 : io.ntcreatex.in.alloc_size = 0;
562 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
563 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
564 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
565 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
566 6 : io.ntcreatex.in.create_options = 0;
567 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
568 6 : io.ntcreatex.in.security_flags = 0;
569 6 : io.ntcreatex.in.fname = fname;
570 :
571 : /* Create the file. */
572 :
573 6 : status = smb_raw_open(cli->tree, tctx, &io);
574 6 : CHECK_STATUS(status, NT_STATUS_OK);
575 6 : fnum = io.ntcreatex.out.file.fnum;
576 :
577 : /* Now try and rename the directory. */
578 :
579 6 : ZERO_STRUCT(ren_io);
580 6 : ren_io.generic.level = RAW_RENAME_RENAME;
581 6 : ren_io.rename.in.pattern1 = dname1;
582 6 : ren_io.rename.in.pattern2 = dname2;
583 6 : ren_io.rename.in.attrib = 0;
584 :
585 6 : status = smb_raw_rename(cli->tree, &ren_io);
586 6 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
587 :
588 : /* Close the file and try the rename. */
589 5 : smbcli_close(cli->tree, fnum);
590 :
591 5 : status = smb_raw_rename(cli->tree, &ren_io);
592 5 : CHECK_STATUS(status, NT_STATUS_OK);
593 :
594 : /*
595 : * Now try just holding a second handle on the directory and holding
596 : * it open across a rename. This should be allowed.
597 : */
598 5 : io.ntcreatex.in.fname = dname2;
599 5 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
600 :
601 5 : io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
602 : SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
603 :
604 5 : status = smb_raw_open(cli->tree, tctx, &io);
605 5 : CHECK_STATUS(status, NT_STATUS_OK);
606 5 : fnum = io.ntcreatex.out.file.fnum;
607 :
608 5 : ren_io.generic.level = RAW_RENAME_RENAME;
609 5 : ren_io.rename.in.pattern1 = dname2;
610 5 : ren_io.rename.in.pattern2 = dname1;
611 5 : ren_io.rename.in.attrib = 0;
612 :
613 5 : status = smb_raw_rename(cli->tree, &ren_io);
614 5 : CHECK_STATUS(status, NT_STATUS_OK);
615 :
616 : /* close our handle to the directory. */
617 5 : smbcli_close(cli->tree, fnum);
618 :
619 : /* Open a handle on the long name, and then
620 : * try a rename. This would catch a regression
621 : * in bug #6781.
622 : */
623 5 : io.ntcreatex.in.fname = dname1_long;
624 5 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
625 :
626 5 : io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
627 : SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
628 :
629 5 : status = smb_raw_open(cli->tree, tctx, &io);
630 5 : CHECK_STATUS(status, NT_STATUS_OK);
631 5 : fnum = io.ntcreatex.out.file.fnum;
632 :
633 5 : ren_io.generic.level = RAW_RENAME_RENAME;
634 5 : ren_io.rename.in.pattern1 = dname1;
635 5 : ren_io.rename.in.pattern2 = dname2;
636 5 : ren_io.rename.in.attrib = 0;
637 :
638 5 : status = smb_raw_rename(cli->tree, &ren_io);
639 5 : CHECK_STATUS(status, NT_STATUS_OK);
640 :
641 : /* close our handle to the longname directory. */
642 5 : smbcli_close(cli->tree, fnum);
643 :
644 : /*
645 : * Now try opening a stream on the directory and holding it open
646 : * across a rename. This should be allowed.
647 : */
648 5 : io.ntcreatex.in.fname = sname;
649 :
650 5 : status = smb_raw_open(cli->tree, tctx, &io);
651 5 : CHECK_STATUS(status, NT_STATUS_OK);
652 5 : fnum = io.ntcreatex.out.file.fnum;
653 :
654 5 : ren_io.generic.level = RAW_RENAME_RENAME;
655 5 : ren_io.rename.in.pattern1 = dname2;
656 5 : ren_io.rename.in.pattern2 = dname1;
657 5 : ren_io.rename.in.attrib = 0;
658 :
659 5 : status = smb_raw_rename(cli->tree, &ren_io);
660 5 : CHECK_STATUS(status, NT_STATUS_OK);
661 :
662 6 : done:
663 :
664 5 : if (fnum != -1) {
665 6 : smbcli_close(cli->tree, fnum);
666 : }
667 6 : smb_raw_exit(cli->session);
668 6 : smbcli_deltree(cli->tree, BASEDIR);
669 6 : return ret;
670 : }
671 :
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);
674 :
675 : /*
676 : basic testing of rename calls
677 : */
678 2354 : struct torture_suite *torture_raw_rename(TALLOC_CTX *mem_ctx)
679 : {
680 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "rename");
681 :
682 2354 : 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 2354 : torture_suite_add_2smb_test(suite, "trans2rename", test_trans2rename);
686 2354 : torture_suite_add_1smb_test(suite, "nttransrename", test_nttransrename);
687 2354 : torture_suite_add_1smb_test(suite, "ntrename", test_ntrename);
688 2354 : torture_suite_add_1smb_test(suite, "osxrename", test_osxrename);
689 2354 : torture_suite_add_1smb_test(suite, "directory rename", test_dir_rename);
690 :
691 2354 : return suite;
692 : }
|