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