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 "librpc/gen_ndr/ndr_security.h"
24 #define CHECK_STATUS(status, correct) do { \
25 if (!NT_STATUS_EQUAL(status, correct)) { \
26 printf("(%d) Incorrect status %s - should be %s\n", \
27 __LINE__, nt_errstr(status), nt_errstr(correct)); \
32 #define CHECK_VALUE(v, correct) do { \
33 if ((v) != (correct)) { \
34 printf("(%d) Incorrect %s %d - should be %d\n", \
35 __LINE__, #v, (int)v, (int)correct); \
39 #define BASEDIR "\\testrename"
44 static BOOL test_mv(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
50 const char *fname1 = BASEDIR "\\test1.txt";
51 const char *fname2 = BASEDIR "\\test2.txt";
54 printf("Testing SMBmv\n");
56 if (!torture_setup_dir(cli, BASEDIR)) {
60 printf("Trying simple rename\n");
62 op.generic.level = RAW_OPEN_NTCREATEX;
63 op.ntcreatex.in.root_fid = 0;
64 op.ntcreatex.in.flags = 0;
65 op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
66 op.ntcreatex.in.create_options = 0;
67 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
68 op.ntcreatex.in.share_access =
69 NTCREATEX_SHARE_ACCESS_READ |
70 NTCREATEX_SHARE_ACCESS_WRITE;
71 op.ntcreatex.in.alloc_size = 0;
72 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
73 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
74 op.ntcreatex.in.security_flags = 0;
75 op.ntcreatex.in.fname = fname1;
77 status = smb_raw_open(cli->tree, mem_ctx, &op);
78 CHECK_STATUS(status, NT_STATUS_OK);
79 fnum = op.ntcreatex.out.fnum;
81 io.generic.level = RAW_RENAME_RENAME;
82 io.rename.in.pattern1 = fname1;
83 io.rename.in.pattern2 = fname2;
84 io.rename.in.attrib = 0;
86 printf("trying rename while first file open\n");
87 status = smb_raw_rename(cli->tree, &io);
88 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
90 smbcli_close(cli->tree, fnum);
92 op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
93 op.ntcreatex.in.share_access =
94 NTCREATEX_SHARE_ACCESS_DELETE |
95 NTCREATEX_SHARE_ACCESS_READ |
96 NTCREATEX_SHARE_ACCESS_WRITE;
97 status = smb_raw_open(cli->tree, mem_ctx, &op);
98 CHECK_STATUS(status, NT_STATUS_OK);
99 fnum = op.ntcreatex.out.fnum;
101 printf("trying rename while first file open with SHARE_ACCESS_DELETE\n");
102 status = smb_raw_rename(cli->tree, &io);
103 CHECK_STATUS(status, NT_STATUS_OK);
105 io.rename.in.pattern1 = fname2;
106 io.rename.in.pattern2 = fname1;
107 status = smb_raw_rename(cli->tree, &io);
108 CHECK_STATUS(status, NT_STATUS_OK);
110 io.rename.in.pattern1 = fname1;
111 io.rename.in.pattern2 = fname2;
113 printf("trying rename while not open\n");
114 smb_raw_exit(cli->session);
115 status = smb_raw_rename(cli->tree, &io);
116 CHECK_STATUS(status, NT_STATUS_OK);
118 printf("Trying self rename\n");
119 io.rename.in.pattern1 = fname2;
120 io.rename.in.pattern2 = fname2;
121 status = smb_raw_rename(cli->tree, &io);
122 CHECK_STATUS(status, NT_STATUS_OK);
124 io.rename.in.pattern1 = fname1;
125 io.rename.in.pattern2 = fname1;
126 status = smb_raw_rename(cli->tree, &io);
127 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
130 printf("trying wildcard rename\n");
131 io.rename.in.pattern1 = BASEDIR "\\*.txt";
132 io.rename.in.pattern2 = fname1;
134 status = smb_raw_rename(cli->tree, &io);
135 CHECK_STATUS(status, NT_STATUS_OK);
137 printf("and again\n");
138 status = smb_raw_rename(cli->tree, &io);
139 CHECK_STATUS(status, NT_STATUS_OK);
141 printf("Trying extension change\n");
142 io.rename.in.pattern1 = BASEDIR "\\*.txt";
143 io.rename.in.pattern2 = BASEDIR "\\*.bak";
144 status = smb_raw_rename(cli->tree, &io);
145 CHECK_STATUS(status, NT_STATUS_OK);
147 status = smb_raw_rename(cli->tree, &io);
148 CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
150 printf("Checking attrib handling\n");
151 torture_set_file_attribute(cli->tree, BASEDIR "\\test1.bak", FILE_ATTRIBUTE_HIDDEN);
152 io.rename.in.pattern1 = BASEDIR "\\test1.bak";
153 io.rename.in.pattern2 = BASEDIR "\\*.txt";
154 io.rename.in.attrib = 0;
155 status = smb_raw_rename(cli->tree, &io);
156 CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
158 io.rename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
159 status = smb_raw_rename(cli->tree, &io);
160 CHECK_STATUS(status, NT_STATUS_OK);
163 smbcli_close(cli->tree, fnum);
164 smb_raw_exit(cli->session);
165 smbcli_deltree(cli->tree, BASEDIR);
174 static BOOL test_ntrename(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
180 const char *fname1 = BASEDIR "\\test1.txt";
181 const char *fname2 = BASEDIR "\\test2.txt";
182 union smb_fileinfo finfo;
184 printf("Testing SMBntrename\n");
186 if (!torture_setup_dir(cli, BASEDIR)) {
190 printf("Trying simple rename\n");
192 fnum = create_complex_file(cli, mem_ctx, fname1);
194 io.generic.level = RAW_RENAME_NTRENAME;
195 io.ntrename.in.old_name = fname1;
196 io.ntrename.in.new_name = fname2;
197 io.ntrename.in.attrib = 0;
198 io.ntrename.in.cluster_size = 0;
199 io.ntrename.in.flags = RENAME_FLAG_RENAME;
201 status = smb_raw_rename(cli->tree, &io);
202 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
204 smb_raw_exit(cli->session);
205 status = smb_raw_rename(cli->tree, &io);
206 CHECK_STATUS(status, NT_STATUS_OK);
208 printf("Trying self rename\n");
209 io.ntrename.in.old_name = fname2;
210 io.ntrename.in.new_name = fname2;
211 status = smb_raw_rename(cli->tree, &io);
212 CHECK_STATUS(status, NT_STATUS_OK);
214 io.ntrename.in.old_name = fname1;
215 io.ntrename.in.new_name = fname1;
216 status = smb_raw_rename(cli->tree, &io);
217 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
219 printf("trying wildcard rename\n");
220 io.ntrename.in.old_name = BASEDIR "\\*.txt";
221 io.ntrename.in.new_name = fname1;
223 status = smb_raw_rename(cli->tree, &io);
224 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
226 printf("Checking attrib handling\n");
227 torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN);
228 io.ntrename.in.old_name = fname2;
229 io.ntrename.in.new_name = fname1;
230 io.ntrename.in.attrib = 0;
231 status = smb_raw_rename(cli->tree, &io);
232 CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
234 io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
235 status = smb_raw_rename(cli->tree, &io);
236 CHECK_STATUS(status, NT_STATUS_OK);
238 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
240 printf("Checking hard link\n");
241 io.ntrename.in.old_name = fname1;
242 io.ntrename.in.new_name = fname2;
243 io.ntrename.in.attrib = 0;
244 io.ntrename.in.flags = RENAME_FLAG_HARD_LINK;
245 status = smb_raw_rename(cli->tree, &io);
246 CHECK_STATUS(status, NT_STATUS_OK);
248 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
250 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
251 finfo.generic.in.fname = fname2;
252 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
253 CHECK_STATUS(status, NT_STATUS_OK);
254 CHECK_VALUE(finfo.all_info.out.nlink, 2);
255 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
257 finfo.generic.in.fname = fname1;
258 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
259 CHECK_STATUS(status, NT_STATUS_OK);
260 CHECK_VALUE(finfo.all_info.out.nlink, 2);
261 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
263 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
265 smbcli_unlink(cli->tree, fname2);
267 finfo.generic.in.fname = fname1;
268 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
269 CHECK_STATUS(status, NT_STATUS_OK);
270 CHECK_VALUE(finfo.all_info.out.nlink, 1);
272 printf("Checking copy\n");
273 io.ntrename.in.old_name = fname1;
274 io.ntrename.in.new_name = fname2;
275 io.ntrename.in.attrib = 0;
276 io.ntrename.in.flags = RENAME_FLAG_COPY;
277 status = smb_raw_rename(cli->tree, &io);
278 CHECK_STATUS(status, NT_STATUS_OK);
280 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
282 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
283 finfo.generic.in.fname = fname2;
284 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
285 CHECK_STATUS(status, NT_STATUS_OK);
286 CHECK_VALUE(finfo.all_info.out.nlink, 1);
287 CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
289 finfo.generic.in.fname = fname1;
290 status = smb_raw_pathinfo(cli->tree, mem_ctx, &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_SYSTEM);
295 torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
297 smbcli_unlink(cli->tree, fname2);
299 finfo.generic.in.fname = fname1;
300 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
301 CHECK_STATUS(status, NT_STATUS_OK);
302 CHECK_VALUE(finfo.all_info.out.nlink, 1);
304 printf("Checking invalid flags\n");
305 io.ntrename.in.old_name = fname1;
306 io.ntrename.in.new_name = fname2;
307 io.ntrename.in.attrib = 0;
308 io.ntrename.in.flags = 0;
309 status = smb_raw_rename(cli->tree, &io);
310 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
312 io.ntrename.in.flags = 300;
313 status = smb_raw_rename(cli->tree, &io);
314 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
316 io.ntrename.in.flags = 0x106;
317 status = smb_raw_rename(cli->tree, &io);
318 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
320 printf("Checking unknown field\n");
321 io.ntrename.in.old_name = fname1;
322 io.ntrename.in.new_name = fname2;
323 io.ntrename.in.attrib = 0;
324 io.ntrename.in.flags = RENAME_FLAG_RENAME;
325 io.ntrename.in.cluster_size = 0xff;
326 status = smb_raw_rename(cli->tree, &io);
327 CHECK_STATUS(status, NT_STATUS_OK);
329 printf("Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");
331 io.ntrename.in.old_name = fname2;
332 io.ntrename.in.new_name = fname1;
333 io.ntrename.in.attrib = 0;
334 io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
335 io.ntrename.in.cluster_size = 1;
336 status = smb_raw_rename(cli->tree, &io);
337 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
339 io.ntrename.in.flags = RENAME_FLAG_COPY;
340 status = smb_raw_rename(cli->tree, &io);
341 CHECK_STATUS(status, NT_STATUS_OK);
346 fnum = smbcli_open(cli->tree, fname1, O_RDWR, DENY_NONE);
347 memset(buf, 1, sizeof(buf));
348 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
349 smbcli_close(cli->tree, fnum);
351 fnum = smbcli_open(cli->tree, fname2, O_RDWR, DENY_NONE);
352 memset(buf, 1, sizeof(buf));
353 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)-1);
354 smbcli_close(cli->tree, fnum);
356 torture_all_info(cli->tree, fname1);
357 torture_all_info(cli->tree, fname2);
361 io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
362 status = smb_raw_rename(cli->tree, &io);
363 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
365 for (i=0;i<20000;i++) {
366 io.ntrename.in.cluster_size = i;
367 status = smb_raw_rename(cli->tree, &io);
368 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
369 printf("i=%d status=%s\n", i, nt_errstr(status));
374 printf("Checking other flags\n");
376 for (i=0;i<0xFFF;i++) {
377 if (i == RENAME_FLAG_RENAME ||
378 i == RENAME_FLAG_HARD_LINK ||
379 i == RENAME_FLAG_COPY) {
383 io.ntrename.in.old_name = fname2;
384 io.ntrename.in.new_name = fname1;
385 io.ntrename.in.flags = i;
386 io.ntrename.in.attrib = 0;
387 io.ntrename.in.cluster_size = 0;
388 status = smb_raw_rename(cli->tree, &io);
389 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
390 printf("flags=0x%x status=%s\n", i, nt_errstr(status));
395 smb_raw_exit(cli->session);
396 smbcli_deltree(cli->tree, BASEDIR);
402 basic testing of rename calls
404 BOOL torture_raw_rename(void)
406 struct smbcli_state *cli;
410 if (!torture_open_connection(&cli)) {
414 mem_ctx = talloc_init("torture_raw_rename");
416 if (!test_mv(cli, mem_ctx)) {
420 if (!test_ntrename(cli, mem_ctx)) {
424 torture_close_connection(cli);
425 talloc_destroy(mem_ctx);