r14173: change smb interface structures to always use
[gd/samba-autobuild/.git] / source4 / 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 #include "torture/torture.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/libcli.h"
25
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)); \
30                 ret = False; \
31                 goto done; \
32         }} while (0)
33
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); \
38                 ret = False; \
39         }} while (0)
40
41 #define BASEDIR "\\testrename"
42
43 /*
44   test SMBmv ops
45 */
46 static BOOL test_mv(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
47 {
48         union smb_rename io;
49         NTSTATUS status;
50         BOOL ret = True;
51         int fnum = -1;
52         const char *fname1 = BASEDIR "\\test1.txt";
53         const char *fname2 = BASEDIR "\\test2.txt";
54         union smb_open op;
55
56         printf("Testing SMBmv\n");
57
58         if (!torture_setup_dir(cli, BASEDIR)) {
59                 return False;
60         }
61
62         printf("Trying simple rename\n");
63
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;
78
79         status = smb_raw_open(cli->tree, mem_ctx, &op);
80         CHECK_STATUS(status, NT_STATUS_OK);
81         fnum = op.ntcreatex.file.fnum;
82
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;
87         
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);
91
92         smbcli_close(cli->tree, fnum);
93
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;
102
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);
106
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);
111
112         io.rename.in.pattern1 = fname1;
113         io.rename.in.pattern2 = fname2;
114
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);
119         
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);
125
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);
130
131
132         printf("trying wildcard rename\n");
133         io.rename.in.pattern1 = BASEDIR "\\*.txt";
134         io.rename.in.pattern2 = fname1;
135         
136         status = smb_raw_rename(cli->tree, &io);
137         CHECK_STATUS(status, NT_STATUS_OK);
138
139         printf("and again\n");
140         status = smb_raw_rename(cli->tree, &io);
141         CHECK_STATUS(status, NT_STATUS_OK);
142
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);
148
149         status = smb_raw_rename(cli->tree, &io);
150         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
151
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);
159
160         io.rename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
161         status = smb_raw_rename(cli->tree, &io);
162         CHECK_STATUS(status, NT_STATUS_OK);
163
164 done:
165         smbcli_close(cli->tree, fnum);
166         smb_raw_exit(cli->session);
167         smbcli_deltree(cli->tree, BASEDIR);
168         return ret;
169 }
170
171
172
173 /*
174   test SMBntrename ops
175 */
176 static BOOL test_ntrename(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
177 {
178         union smb_rename io;
179         NTSTATUS status;
180         BOOL ret = True;
181         int fnum, i;
182         const char *fname1 = BASEDIR "\\test1.txt";
183         const char *fname2 = BASEDIR "\\test2.txt";
184         union smb_fileinfo finfo;
185
186         printf("Testing SMBntrename\n");
187
188         if (!torture_setup_dir(cli, BASEDIR)) {
189                 return False;
190         }
191
192         printf("Trying simple rename\n");
193
194         fnum = create_complex_file(cli, mem_ctx, fname1);
195         
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;
202         
203         status = smb_raw_rename(cli->tree, &io);
204         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
205         
206         smb_raw_exit(cli->session);
207         status = smb_raw_rename(cli->tree, &io);
208         CHECK_STATUS(status, NT_STATUS_OK);
209
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);
215
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);
220
221         printf("trying wildcard rename\n");
222         io.ntrename.in.old_name = BASEDIR "\\*.txt";
223         io.ntrename.in.new_name = fname1;
224         
225         status = smb_raw_rename(cli->tree, &io);
226         CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
227
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);
235
236         io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
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_NORMAL);
241
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);
249
250         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
251
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);
258
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);
264
265         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
266
267         smbcli_unlink(cli->tree, fname2);
268
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);
274
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);
282
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);
289
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);
296
297         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
298
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);
305
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);
311
312         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
313
314         smbcli_unlink(cli->tree, fname2);
315
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);
320
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);
328
329         io.ntrename.in.flags = 300;
330         status = smb_raw_rename(cli->tree, &io);
331         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
332
333         io.ntrename.in.flags = 0x106;
334         status = smb_raw_rename(cli->tree, &io);
335         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
336
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);
345
346         printf("Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");
347
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);
355
356         io.ntrename.in.flags = RENAME_FLAG_COPY;
357         status = smb_raw_rename(cli->tree, &io);
358         CHECK_STATUS(status, NT_STATUS_OK);
359
360 #if 0
361         {
362                 char buf[16384];
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);
367
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);
372
373                 torture_all_info(cli->tree, fname1);
374                 torture_all_info(cli->tree, fname2);
375         }
376         
377
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);
381
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));
387                 }
388         }
389 #endif
390
391         printf("Checking other flags\n");
392
393         for (i=0;i<0xFFF;i++) {
394                 if (i == RENAME_FLAG_RENAME ||
395                     i == RENAME_FLAG_HARD_LINK ||
396                     i == RENAME_FLAG_COPY) {
397                         continue;
398                 }
399
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));
408                 }
409         }
410         
411 done:
412         smb_raw_exit(cli->session);
413         smbcli_deltree(cli->tree, BASEDIR);
414         return ret;
415 }
416
417
418 /* 
419    basic testing of rename calls
420 */
421 BOOL torture_raw_rename(void)
422 {
423         struct smbcli_state *cli;
424         BOOL ret = True;
425         TALLOC_CTX *mem_ctx;
426
427         if (!torture_open_connection(&cli)) {
428                 return False;
429         }
430
431         mem_ctx = talloc_init("torture_raw_rename");
432
433         if (!test_mv(cli, mem_ctx)) {
434                 ret = False;
435         }
436
437         if (!test_ntrename(cli, mem_ctx)) {
438                 ret = False;
439         }
440
441         torture_close_connection(cli);
442         talloc_free(mem_ctx);
443         return ret;
444 }