Convert libcli routines to use cli_tree instead of cli_state. Port
[jelmer/samba4-debian.git] / source / torture / raw / rename.c
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 2 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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 #define CHECK_STATUS(status, correct) do { \
24         if (!NT_STATUS_EQUAL(status, correct)) { \
25                 printf("(%d) Incorrect status %s - should be %s\n", \
26                        __LINE__, nt_errstr(status), nt_errstr(correct)); \
27                 ret = False; \
28                 goto done; \
29         }} while (0)
30
31 #define CHECK_VALUE(v, correct) do { \
32         if ((v) != (correct)) { \
33                 printf("(%d) Incorrect %s %d - should be %d\n", \
34                        __LINE__, #v, (int)v, (int)correct); \
35                 ret = False; \
36         }} while (0)
37
38 #define BASEDIR "\\testrename"
39
40 /*
41   test SMBmv ops
42 */
43 static BOOL test_mv(struct cli_state *cli, TALLOC_CTX *mem_ctx)
44 {
45         union smb_rename io;
46         NTSTATUS status;
47         BOOL ret = True;
48         int fnum;
49         const char *fname1 = BASEDIR "\\test1.txt";
50         const char *fname2 = BASEDIR "\\test2.txt";
51
52         printf("Testing SMBmv\n");
53
54         if (cli_deltree(cli->tree, BASEDIR) == -1 ||
55             !cli_mkdir(cli->tree, BASEDIR)) {
56                 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli->tree));
57                 return False;
58         }
59
60         printf("Trying simple rename\n");
61
62         fnum = create_complex_file(cli, mem_ctx, fname1);
63         
64         io.generic.level = RAW_RENAME_RENAME;
65         io.rename.in.pattern1 = fname1;
66         io.rename.in.pattern2 = fname2;
67         io.rename.in.attrib = 0;
68         
69         status = smb_raw_rename(cli->tree, &io);
70         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
71         
72         smb_raw_exit(cli->session);
73         status = smb_raw_rename(cli->tree, &io);
74         CHECK_STATUS(status, NT_STATUS_OK);
75         
76         printf("Trying self rename\n");
77         io.rename.in.pattern1 = fname2;
78         io.rename.in.pattern2 = fname2;
79         status = smb_raw_rename(cli->tree, &io);
80         CHECK_STATUS(status, NT_STATUS_OK);
81
82         io.rename.in.pattern1 = fname1;
83         io.rename.in.pattern2 = fname1;
84         status = smb_raw_rename(cli->tree, &io);
85         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
86
87
88         printf("trying wildcard rename\n");
89         io.rename.in.pattern1 = BASEDIR "\\*.txt";
90         io.rename.in.pattern2 = fname1;
91         
92         status = smb_raw_rename(cli->tree, &io);
93         CHECK_STATUS(status, NT_STATUS_OK);
94
95         printf("and again\n");
96         status = smb_raw_rename(cli->tree, &io);
97         CHECK_STATUS(status, NT_STATUS_OK);
98
99         printf("Trying extension change\n");
100         io.rename.in.pattern1 = BASEDIR "\\*.txt";
101         io.rename.in.pattern2 = BASEDIR "\\*.bak";
102         status = smb_raw_rename(cli->tree, &io);
103         CHECK_STATUS(status, NT_STATUS_OK);
104
105         status = smb_raw_rename(cli->tree, &io);
106         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
107
108         printf("Checking attrib handling\n");
109         torture_set_file_attribute(cli->tree, BASEDIR "\\test1.bak", FILE_ATTRIBUTE_HIDDEN);
110         io.rename.in.pattern1 = BASEDIR "\\test1.bak";
111         io.rename.in.pattern2 = BASEDIR "\\*.txt";
112         io.rename.in.attrib = 0;
113         status = smb_raw_rename(cli->tree, &io);
114         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
115
116         io.rename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
117         status = smb_raw_rename(cli->tree, &io);
118         CHECK_STATUS(status, NT_STATUS_OK);
119
120 done:
121         cli_close(cli->tree, fnum);
122         smb_raw_exit(cli->session);
123         cli_deltree(cli->tree, BASEDIR);
124         return ret;
125 }
126
127
128
129 /*
130   test SMBntrename ops
131 */
132 static BOOL test_ntrename(struct cli_state *cli, TALLOC_CTX *mem_ctx)
133 {
134         union smb_rename io;
135         NTSTATUS status;
136         BOOL ret = True;
137         int fnum, i;
138         const char *fname1 = BASEDIR "\\test1.txt";
139         const char *fname2 = BASEDIR "\\test2.txt";
140         union smb_fileinfo finfo;
141
142         printf("Testing SMBntrename\n");
143
144         if (cli_deltree(cli->tree, BASEDIR) == -1 ||
145             !cli_mkdir(cli->tree, BASEDIR)) {
146                 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli->tree));
147                 return False;
148         }
149
150         printf("Trying simple rename\n");
151
152         fnum = create_complex_file(cli, mem_ctx, fname1);
153         
154         io.generic.level = RAW_RENAME_NTRENAME;
155         io.ntrename.in.old_name = fname1;
156         io.ntrename.in.new_name = fname2;
157         io.ntrename.in.attrib = 0;
158         io.ntrename.in.cluster_size = 0;
159         io.ntrename.in.flags = RENAME_FLAG_RENAME;
160         
161         status = smb_raw_rename(cli->tree, &io);
162         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
163         
164         smb_raw_exit(cli->session);
165         status = smb_raw_rename(cli->tree, &io);
166         CHECK_STATUS(status, NT_STATUS_OK);
167
168         printf("Trying self rename\n");
169         io.ntrename.in.old_name = fname2;
170         io.ntrename.in.new_name = fname2;
171         status = smb_raw_rename(cli->tree, &io);
172         CHECK_STATUS(status, NT_STATUS_OK);
173
174         io.ntrename.in.old_name = fname1;
175         io.ntrename.in.new_name = fname1;
176         status = smb_raw_rename(cli->tree, &io);
177         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
178
179         printf("trying wildcard rename\n");
180         io.ntrename.in.old_name = BASEDIR "\\*.txt";
181         io.ntrename.in.new_name = fname1;
182         
183         status = smb_raw_rename(cli->tree, &io);
184         CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
185
186         printf("Checking attrib handling\n");
187         torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN);
188         io.ntrename.in.old_name = fname2;
189         io.ntrename.in.new_name = fname1;
190         io.ntrename.in.attrib = 0;
191         status = smb_raw_rename(cli->tree, &io);
192         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
193
194         io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
195         status = smb_raw_rename(cli->tree, &io);
196         CHECK_STATUS(status, NT_STATUS_OK);
197
198         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
199
200         printf("Checking hard link\n");
201         io.ntrename.in.old_name = fname1;
202         io.ntrename.in.new_name = fname2;
203         io.ntrename.in.attrib = 0;
204         io.ntrename.in.flags = RENAME_FLAG_HARD_LINK;
205         status = smb_raw_rename(cli->tree, &io);
206         CHECK_STATUS(status, NT_STATUS_OK);
207
208         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
209
210         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
211         finfo.generic.in.fname = fname2;
212         status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
213         CHECK_STATUS(status, NT_STATUS_OK);
214         CHECK_VALUE(finfo.all_info.out.nlink, 2);
215         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
216
217         finfo.generic.in.fname = fname1;
218         status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
219         CHECK_STATUS(status, NT_STATUS_OK);
220         CHECK_VALUE(finfo.all_info.out.nlink, 2);
221         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
222
223         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
224
225         cli_unlink(cli->tree, fname2);
226
227         finfo.generic.in.fname = fname1;
228         status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
229         CHECK_STATUS(status, NT_STATUS_OK);
230         CHECK_VALUE(finfo.all_info.out.nlink, 1);
231
232         printf("Checking copy\n");
233         io.ntrename.in.old_name = fname1;
234         io.ntrename.in.new_name = fname2;
235         io.ntrename.in.attrib = 0;
236         io.ntrename.in.flags = RENAME_FLAG_COPY;
237         status = smb_raw_rename(cli->tree, &io);
238         CHECK_STATUS(status, NT_STATUS_OK);
239
240         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
241
242         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
243         finfo.generic.in.fname = fname2;
244         status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
245         CHECK_STATUS(status, NT_STATUS_OK);
246         CHECK_VALUE(finfo.all_info.out.nlink, 1);
247         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
248
249         finfo.generic.in.fname = fname1;
250         status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
251         CHECK_STATUS(status, NT_STATUS_OK);
252         CHECK_VALUE(finfo.all_info.out.nlink, 1);
253         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
254
255         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
256
257         cli_unlink(cli->tree, fname2);
258
259         finfo.generic.in.fname = 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, 1);
263
264         printf("Checking invalid flags\n");
265         io.ntrename.in.old_name = fname1;
266         io.ntrename.in.new_name = fname2;
267         io.ntrename.in.attrib = 0;
268         io.ntrename.in.flags = 0;
269         status = smb_raw_rename(cli->tree, &io);
270         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
271
272         io.ntrename.in.flags = 300;
273         status = smb_raw_rename(cli->tree, &io);
274         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
275
276         io.ntrename.in.flags = 0x106;
277         status = smb_raw_rename(cli->tree, &io);
278         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
279
280         printf("Checking unknown field\n");
281         io.ntrename.in.old_name = fname1;
282         io.ntrename.in.new_name = fname2;
283         io.ntrename.in.attrib = 0;
284         io.ntrename.in.flags = RENAME_FLAG_RENAME;
285         io.ntrename.in.cluster_size = 0xff;
286         status = smb_raw_rename(cli->tree, &io);
287         CHECK_STATUS(status, NT_STATUS_OK);
288
289         printf("Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");
290
291         io.ntrename.in.old_name = fname2;
292         io.ntrename.in.new_name = fname1;
293         io.ntrename.in.attrib = 0;
294         io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
295         io.ntrename.in.cluster_size = 1;
296         status = smb_raw_rename(cli->tree, &io);
297         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
298
299         io.ntrename.in.flags = RENAME_FLAG_COPY;
300         status = smb_raw_rename(cli->tree, &io);
301         CHECK_STATUS(status, NT_STATUS_OK);
302
303 #if 0
304         {
305                 char buf[16384];
306                 fnum = cli_open(cli->tree, fname1, O_RDWR, DENY_NONE);
307                 memset(buf, 1, sizeof(buf));
308                 cli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
309                 cli_close(cli->tree, fnum);
310
311                 fnum = cli_open(cli->tree, fname2, O_RDWR, DENY_NONE);
312                 memset(buf, 1, sizeof(buf));
313                 cli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)-1);
314                 cli_close(cli->tree, fnum);
315
316                 torture_all_info(cli->tree, fname1);
317                 torture_all_info(cli->tree, fname2);
318         }
319         
320
321         io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
322         status = smb_raw_rename(cli->tree, &io);
323         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
324
325         for (i=0;i<20000;i++) {
326                 io.ntrename.in.cluster_size = i;
327                 status = smb_raw_rename(cli->tree, &io);
328                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
329                         printf("i=%d status=%s\n", i, nt_errstr(status));
330                 }
331         }
332 #endif
333
334         printf("Checking other flags\n");
335
336         for (i=0;i<0xFFF;i++) {
337                 if (i == RENAME_FLAG_RENAME ||
338                     i == RENAME_FLAG_HARD_LINK ||
339                     i == RENAME_FLAG_COPY) {
340                         continue;
341                 }
342
343                 io.ntrename.in.old_name = fname2;
344                 io.ntrename.in.new_name = fname1;
345                 io.ntrename.in.flags = i;
346                 io.ntrename.in.attrib = 0;
347                 io.ntrename.in.cluster_size = 0;
348                 status = smb_raw_rename(cli->tree, &io);
349                 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
350                         printf("flags=0x%x status=%s\n", i, nt_errstr(status));
351                 }
352         }
353         
354 done:
355         smb_raw_exit(cli->session);
356         cli_deltree(cli->tree, BASEDIR);
357         return ret;
358 }
359
360
361 /* 
362    basic testing of rename calls
363 */
364 BOOL torture_raw_rename(int dummy)
365 {
366         struct cli_state *cli;
367         BOOL ret = True;
368         TALLOC_CTX *mem_ctx;
369
370         if (!torture_open_connection(&cli)) {
371                 return False;
372         }
373
374         mem_ctx = talloc_init("torture_raw_rename");
375
376         if (!test_mv(cli, mem_ctx)) {
377                 ret = False;
378         }
379
380         if (!test_ntrename(cli, mem_ctx)) {
381                 ret = False;
382         }
383
384         torture_close_connection(cli);
385         talloc_destroy(mem_ctx);
386         return ret;
387 }