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