r8494: fixed a bug in RAW-SFILEINFO that caused inconsistent results on different...
[sfrench/samba-autobuild/.git] / source / torture / raw / setfileinfo.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RAW_SFILEINFO_* individual 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 "system/time.h"
23
24 #define BASEDIR "\\testsfileinfo"
25
26 /* basic testing of all RAW_SFILEINFO_* calls 
27    for each call we test that it succeeds, and where possible test 
28    for consistency between the calls. 
29 */
30 BOOL torture_raw_sfileinfo(void)
31 {
32         struct smbcli_state *cli;
33         BOOL ret = True;
34         TALLOC_CTX *mem_ctx;
35         int fnum_saved, d_fnum, fnum2, fnum = -1;
36         char *fnum_fname;
37         char *fnum_fname_new;
38         char *path_fname;
39         char *path_fname_new;
40         union smb_fileinfo finfo1, finfo2;
41         union smb_setfileinfo sfinfo;
42         NTSTATUS status, status2;
43         const char *call_name;
44         time_t basetime = (time(NULL) - 86400) & ~1;
45         BOOL check_fnum;
46         int n = time(NULL) % 100;
47         
48         asprintf(&path_fname, BASEDIR "\\fname_test_%d.txt", n);
49         asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n);
50         asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n);
51         asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n);
52
53         if (!torture_open_connection(&cli)) {
54                 return False;
55         }
56
57         mem_ctx = talloc_init("torture_sfileinfo");
58
59         if (!torture_setup_dir(cli, BASEDIR)) {
60                 return False;
61         }
62
63 #define RECREATE_FILE(fname) do { \
64         if (fnum != -1) smbcli_close(cli->tree, fnum); \
65         fnum = create_complex_file(cli, mem_ctx, fname); \
66         if (fnum == -1) { \
67                 printf("(%s) ERROR: open of %s failed (%s)\n", \
68                        __location__, fname, smbcli_errstr(cli->tree)); \
69                 ret = False; \
70                 goto done; \
71         }} while (0)
72
73 #define RECREATE_BOTH do { \
74                 RECREATE_FILE(path_fname); \
75                 smbcli_close(cli->tree, fnum); \
76                 RECREATE_FILE(fnum_fname); \
77         } while (0)
78
79         RECREATE_BOTH;
80         
81 #define CHECK_CALL_FNUM(call, rightstatus) do { \
82         check_fnum = True; \
83         call_name = #call; \
84         sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
85         sfinfo.generic.file.fnum = fnum; \
86         status = smb_raw_setfileinfo(cli->tree, &sfinfo); \
87         if (!NT_STATUS_EQUAL(status, rightstatus)) { \
88                 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
89                         nt_errstr(status), nt_errstr(rightstatus)); \
90                 ret = False; \
91         } \
92         finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
93         finfo1.generic.in.fnum = fnum; \
94         status2 = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo1); \
95         if (!NT_STATUS_IS_OK(status2)) { \
96                 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status)); \
97                 ret = False; \
98         }} while (0)
99
100 #define CHECK_CALL_PATH(call, rightstatus) do { \
101         check_fnum = False; \
102         call_name = #call; \
103         sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
104         sfinfo.generic.file.fname = path_fname; \
105         status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
106         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
107                 sfinfo.generic.file.fname = path_fname_new; \
108                 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
109         } \
110         if (!NT_STATUS_EQUAL(status, rightstatus)) { \
111                 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
112                         nt_errstr(status), nt_errstr(rightstatus)); \
113                 ret = False; \
114         } \
115         finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
116         finfo1.generic.in.fname = path_fname; \
117         status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo1); \
118         if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
119                 finfo1.generic.in.fname = path_fname_new; \
120                 status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo1); \
121         } \
122         if (!NT_STATUS_IS_OK(status2)) { \
123                 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status2)); \
124                 ret = False; \
125         }} while (0)
126
127 #define CHECK1(call) \
128         do { if (NT_STATUS_IS_OK(status)) { \
129                 finfo2.generic.level = RAW_FILEINFO_ ## call; \
130                 if (check_fnum) { \
131                         finfo2.generic.in.fnum = fnum; \
132                         status2 = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo2); \
133                 } else { \
134                         finfo2.generic.in.fname = path_fname; \
135                         status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo2); \
136                         if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
137                                 finfo2.generic.in.fname = path_fname_new; \
138                                 status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo2); \
139                         } \
140                 } \
141                 if (!NT_STATUS_IS_OK(status2)) { \
142                         printf("%s - %s\n", #call, nt_errstr(status2)); \
143                 } \
144         }} while (0)
145
146 #define CHECK_VALUE(call, stype, field, value) do { \
147         CHECK1(call); \
148         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
149                 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
150                        call_name, #stype, #field, \
151                        (uint_t)value, (uint_t)finfo2.stype.out.field); \
152                 dump_all_info(mem_ctx, &finfo1); \
153         }} while (0)
154
155 #define CHECK_TIME(call, stype, field, value) do { \
156         CHECK1(call); \
157         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
158                 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
159                         call_name, #stype, #field, \
160                         (uint_t)value, \
161                         (uint_t)nt_time_to_unix(finfo2.stype.out.field)); \
162                 printf("\t%s", timestring(mem_ctx, value)); \
163                 printf("\t%s\n", nt_time_string(mem_ctx, finfo2.stype.out.field)); \
164                 dump_all_info(mem_ctx, &finfo1); \
165         }} while (0)
166
167 #define CHECK_STR(call, stype, field, value) do { \
168         CHECK1(call); \
169         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && strcmp(finfo2.stype.out.field, value) != 0) { \
170                 printf("(%s) %s - %s/%s should be '%s' - '%s'\n", __location__, \
171                         call_name, #stype, #field, \
172                         value, \
173                         finfo2.stype.out.field); \
174                 dump_all_info(mem_ctx, &finfo1); \
175         }} while (0)
176
177         
178         printf("test setattr\n");
179         sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_READONLY;
180         sfinfo.setattr.in.write_time = basetime;
181         CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
182         CHECK_VALUE  (ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
183         CHECK_TIME   (ALL_INFO, all_info, write_time, basetime);
184
185         printf("setting to NORMAL doesn't do anything\n");
186         sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_NORMAL;
187         sfinfo.setattr.in.write_time = 0;
188         CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
189         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
190         CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
191
192         printf("a zero write_time means don't change\n");
193         sfinfo.setattr.in.attrib = 0;
194         sfinfo.setattr.in.write_time = 0;
195         CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
196         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
197         CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
198
199         printf("test setattre\n");
200         sfinfo.setattre.in.create_time = basetime + 20;
201         sfinfo.setattre.in.access_time = basetime + 30;
202         sfinfo.setattre.in.write_time  = basetime + 40;
203         CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
204         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
205         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
206         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 40);
207
208         sfinfo.setattre.in.create_time = 0;
209         sfinfo.setattre.in.access_time = 0;
210         sfinfo.setattre.in.write_time  = 0;
211         CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
212         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
213         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
214         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 40);
215
216         printf("test standard level\n");
217         sfinfo.standard.in.create_time = basetime + 100;
218         sfinfo.standard.in.access_time = basetime + 200;
219         sfinfo.standard.in.write_time  = basetime + 300;
220         CHECK_CALL_FNUM(STANDARD, NT_STATUS_OK);
221         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
222         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
223         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
224
225         printf("test basic_info level\n");
226         basetime += 86400;
227         unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
228         unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
229         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
230         unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
231         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
232         CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
233         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
234         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
235         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
236         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
237         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
238
239         printf("a zero time means don't change\n");
240         unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
241         unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
242         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
243         unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
244         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
245         CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
246         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
247         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
248         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
249         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
250         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
251
252         printf("test basic_information level\n");
253         basetime += 86400;
254         unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
255         unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
256         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
257         unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
258         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
259         CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
260         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
261         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
262         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
263         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
264         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
265
266         CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
267         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
268         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
269         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
270         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
271         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
272
273         printf("a zero time means don't change\n");
274         unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
275         unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
276         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
277         unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
278         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
279         CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
280         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
281         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
282         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
283         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
284         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
285
286         CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
287         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
288         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
289         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
290
291         /* interesting - w2k3 leaves change_time as current time for 0 change time
292            in setpathinfo
293           CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
294         */
295         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
296
297         printf("test disposition_info level\n");
298         sfinfo.disposition_info.in.delete_on_close = 1;
299         CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
300         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
301         CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
302
303         sfinfo.disposition_info.in.delete_on_close = 0;
304         CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
305         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
306         CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
307
308         printf("test disposition_information level\n");
309         sfinfo.disposition_info.in.delete_on_close = 1;
310         CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
311         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
312         CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
313
314         /* this would delete the file! */
315         /*
316           CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
317           CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
318           CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
319         */
320
321         sfinfo.disposition_info.in.delete_on_close = 0;
322         CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
323         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
324         CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
325
326         CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
327         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
328         CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
329
330         printf("test allocation_info level\n");
331         sfinfo.allocation_info.in.alloc_size = 0;
332         CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
333         CHECK_VALUE(ALL_INFO, all_info, size, 0);
334         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
335
336         sfinfo.allocation_info.in.alloc_size = 4096;
337         CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
338         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
339         CHECK_VALUE(ALL_INFO, all_info, size, 0);
340
341         RECREATE_BOTH;
342         sfinfo.allocation_info.in.alloc_size = 0;
343         CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
344         CHECK_VALUE(ALL_INFO, all_info, size, 0);
345         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
346
347         CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
348         CHECK_VALUE(ALL_INFO, all_info, size, 0);
349         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
350
351         sfinfo.allocation_info.in.alloc_size = 4096;
352         CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
353         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
354         CHECK_VALUE(ALL_INFO, all_info, size, 0);
355
356         /* setting the allocation size up via setpathinfo seems
357            to be broken in w2k3 */
358         CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
359         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
360         CHECK_VALUE(ALL_INFO, all_info, size, 0);
361
362         printf("test end_of_file_info level\n");
363         sfinfo.end_of_file_info.in.size = 37;
364         CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
365         CHECK_VALUE(ALL_INFO, all_info, size, 37);
366
367         sfinfo.end_of_file_info.in.size = 7;
368         CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
369         CHECK_VALUE(ALL_INFO, all_info, size, 7);
370
371         sfinfo.end_of_file_info.in.size = 37;
372         CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
373         CHECK_VALUE(ALL_INFO, all_info, size, 37);
374
375         CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
376         CHECK_VALUE(ALL_INFO, all_info, size, 37);
377
378         sfinfo.end_of_file_info.in.size = 7;
379         CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
380         CHECK_VALUE(ALL_INFO, all_info, size, 7);
381
382         CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
383         CHECK_VALUE(ALL_INFO, all_info, size, 7);
384
385         printf("test position_information level\n");
386         sfinfo.position_information.in.position = 123456;
387         CHECK_CALL_FNUM(POSITION_INFORMATION, NT_STATUS_OK);
388         CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);
389
390         CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
391         CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);
392
393         printf("test mode_information level\n");
394         sfinfo.mode_information.in.mode = 2;
395         CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
396         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);
397
398         CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
399         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
400
401         sfinfo.mode_information.in.mode = 1;
402         CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
403         CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
404
405         sfinfo.mode_information.in.mode = 0;
406         CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
407         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
408
409         CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
410         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
411 #if 1
412         printf("finally the rename_information level\n");
413         smbcli_close(cli->tree, create_complex_file(cli, mem_ctx, fnum_fname_new));
414         smbcli_close(cli->tree, create_complex_file(cli, mem_ctx, path_fname_new));
415
416         sfinfo.rename_information.in.overwrite = 0;
417         sfinfo.rename_information.in.root_fid  = 0;
418         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
419         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
420
421         sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
422         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
423
424         sfinfo.rename_information.in.new_name  = fnum_fname_new;
425         sfinfo.rename_information.in.overwrite = 1;
426         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_NOT_SUPPORTED);
427
428         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
429         sfinfo.rename_information.in.overwrite = 1;
430         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
431         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
432
433         printf("Trying rename with dest file open\n");
434         fnum2 = create_complex_file(cli, mem_ctx, fnum_fname);
435         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
436         sfinfo.rename_information.in.overwrite = 1;
437         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
438         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
439
440         fnum_saved = fnum;
441         fnum = fnum2;
442         sfinfo.disposition_info.in.delete_on_close = 1;
443         CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
444         fnum = fnum_saved;
445
446         printf("Trying rename with dest file open and delete_on_close\n");
447         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
448         sfinfo.rename_information.in.overwrite = 1;
449         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
450
451         smbcli_close(cli->tree, fnum2);
452         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
453         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
454
455         printf("Trying rename with source file open twice\n");
456         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
457         sfinfo.rename_information.in.overwrite = 1;
458         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
459         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
460
461         fnum2 = create_complex_file(cli, mem_ctx, fnum_fname);
462         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
463         sfinfo.rename_information.in.overwrite = 0;
464         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
465         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
466         smbcli_close(cli->tree, fnum2);
467
468         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
469         sfinfo.rename_information.in.overwrite = 0;
470         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
471         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
472
473         sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
474         sfinfo.rename_information.in.overwrite = 1;
475         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
476         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
477
478         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
479         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
480         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
481
482         sfinfo.rename_information.in.new_name  = path_fname+strlen(BASEDIR)+1;
483         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
484         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
485
486         printf("Trying rename with a root fid\n");
487         d_fnum = create_directory_handle(cli->tree, BASEDIR);
488         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
489         sfinfo.rename_information.in.root_fid = d_fnum;
490         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER);
491         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
492 #endif
493
494 #if 0
495         printf("test unix_basic level\n");
496         CHECK_CALL_FNUM(UNIX_BASIC, NT_STATUS_OK);
497         CHECK_CALL_PATH(UNIX_BASIC, NT_STATUS_OK);
498
499         printf("test unix_link level\n");
500         CHECK_CALL_FNUM(UNIX_LINK, NT_STATUS_OK);
501         CHECK_CALL_PATH(UNIX_LINK, NT_STATUS_OK);
502 #endif
503
504 done:
505         smb_raw_exit(cli->session);
506         smbcli_close(cli->tree, fnum);
507         if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fnum_fname))) {
508                 printf("Failed to delete %s - %s\n", fnum_fname, smbcli_errstr(cli->tree));
509         }
510         if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, path_fname))) {
511                 printf("Failed to delete %s - %s\n", path_fname, smbcli_errstr(cli->tree));
512         }
513
514         torture_close_connection(cli);
515         talloc_free(mem_ctx);
516         return ret;
517 }
518
519
520 /* 
521    look for the w2k3 setpathinfo STANDARD bug
522 */
523 BOOL torture_raw_sfileinfo_bug(void)
524 {
525         struct smbcli_state *cli;
526         TALLOC_CTX *mem_ctx;
527         const char *fname = "\\bug3.txt";
528         union smb_setfileinfo sfinfo;
529         NTSTATUS status;
530         int fnum;
531
532         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
533                 printf("torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n");
534                 return True;
535         }
536
537         if (!torture_open_connection(&cli)) {
538                 return False;
539         }
540
541         mem_ctx = talloc_init("torture_sfileinfo");
542
543         fnum = create_complex_file(cli, mem_ctx, fname);
544         smbcli_close(cli->tree, fnum);
545
546         sfinfo.generic.level = RAW_SFILEINFO_STANDARD;
547         sfinfo.generic.file.fname = fname;
548
549         sfinfo.standard.in.create_time = 0;
550         sfinfo.standard.in.access_time = 0;
551         sfinfo.standard.in.write_time  = 0;
552
553         status = smb_raw_setpathinfo(cli->tree, &sfinfo);
554         printf("%s - %s\n", fname, nt_errstr(status));
555
556         printf("now try and delete %s\n", fname);
557
558         return True;
559 }