s4-torture: ran minimal_includes.pl over source4/torture
[ira/wip.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 3 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, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "system/time.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "libcli/libcli.h"
24 #include "torture/util.h"
25
26 #define BASEDIR "\\testsfileinfo"
27
28 /* basic testing of all RAW_SFILEINFO_* calls 
29    for each call we test that it succeeds, and where possible test 
30    for consistency between the calls. 
31 */
32 bool torture_raw_sfileinfo(struct torture_context *torture, 
33                            struct smbcli_state *cli)
34 {
35         bool ret = true;
36         int fnum = -1;
37         char *fnum_fname;
38         char *fnum_fname_new;
39         char *path_fname;
40         char *path_fname_new;
41         union smb_fileinfo finfo1, finfo2;
42         union smb_setfileinfo sfinfo;
43         NTSTATUS status, status2;
44         const char *call_name;
45         time_t basetime = (time(NULL) - 86400) & ~1;
46         bool check_fnum;
47         int n = time(NULL) % 100;
48         
49         asprintf(&path_fname, BASEDIR "\\fname_test_%d.txt", n);
50         asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n);
51         asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n);
52         asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n);
53
54         if (!torture_setup_dir(cli, BASEDIR)) {
55                 return false;
56         }
57
58 #define RECREATE_FILE(fname) do { \
59         if (fnum != -1) smbcli_close(cli->tree, fnum); \
60         fnum = create_complex_file(cli, torture, fname); \
61         if (fnum == -1) { \
62                 printf("(%s) ERROR: open of %s failed (%s)\n", \
63                        __location__, fname, smbcli_errstr(cli->tree)); \
64                 ret = false; \
65                 goto done; \
66         }} while (0)
67
68 #define RECREATE_BOTH do { \
69                 RECREATE_FILE(path_fname); \
70                 smbcli_close(cli->tree, fnum); \
71                 RECREATE_FILE(fnum_fname); \
72         } while (0)
73
74         RECREATE_BOTH;
75         
76 #define CHECK_CALL_FNUM(call, rightstatus) do { \
77         check_fnum = true; \
78         call_name = #call; \
79         sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
80         sfinfo.generic.in.file.fnum = fnum; \
81         status = smb_raw_setfileinfo(cli->tree, &sfinfo); \
82         if (!NT_STATUS_EQUAL(status, rightstatus)) { \
83                 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
84                         nt_errstr(status), nt_errstr(rightstatus)); \
85                 ret = false; \
86         } \
87         finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
88         finfo1.generic.in.file.fnum = fnum; \
89         status2 = smb_raw_fileinfo(cli->tree, torture, &finfo1); \
90         if (!NT_STATUS_IS_OK(status2)) { \
91                 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status)); \
92                 ret = false; \
93         }} while (0)
94
95 #define CHECK_CALL_PATH(call, rightstatus) do { \
96         check_fnum = false; \
97         call_name = #call; \
98         sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
99         sfinfo.generic.in.file.path = path_fname; \
100         status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
101         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
102                 sfinfo.generic.in.file.path = path_fname_new; \
103                 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
104         } \
105         if (!NT_STATUS_EQUAL(status, rightstatus)) { \
106                 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
107                         nt_errstr(status), nt_errstr(rightstatus)); \
108                 ret = false; \
109         } \
110         finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
111         finfo1.generic.in.file.path = path_fname; \
112         status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
113         if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
114                 finfo1.generic.in.file.path = path_fname_new; \
115                 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
116         } \
117         if (!NT_STATUS_IS_OK(status2)) { \
118                 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status2)); \
119                 ret = false; \
120         }} while (0)
121
122 #define CHECK1(call) \
123         do { if (NT_STATUS_IS_OK(status)) { \
124                 finfo2.generic.level = RAW_FILEINFO_ ## call; \
125                 if (check_fnum) { \
126                         finfo2.generic.in.file.fnum = fnum; \
127                         status2 = smb_raw_fileinfo(cli->tree, torture, &finfo2); \
128                 } else { \
129                         finfo2.generic.in.file.path = path_fname; \
130                         status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
131                         if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
132                                 finfo2.generic.in.file.path = path_fname_new; \
133                                 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
134                         } \
135                 } \
136                 if (!NT_STATUS_IS_OK(status2)) { \
137                         printf("%s - %s\n", #call, nt_errstr(status2)); \
138                         ret = false; \
139                 } \
140         }} while (0)
141
142 #define CHECK_VALUE(call, stype, field, value) do { \
143         CHECK1(call); \
144         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
145                 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
146                        call_name, #stype, #field, \
147                        (uint_t)value, (uint_t)finfo2.stype.out.field); \
148                 dump_all_info(torture, &finfo1); \
149                 ret = false; \
150         }} while (0)
151
152 #define CHECK_TIME(call, stype, field, value) do { \
153         CHECK1(call); \
154         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
155                 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
156                         call_name, #stype, #field, \
157                         (uint_t)value, \
158                         (uint_t)nt_time_to_unix(finfo2.stype.out.field)); \
159                 printf("\t%s", timestring(torture, value)); \
160                 printf("\t%s\n", nt_time_string(torture, finfo2.stype.out.field)); \
161                 dump_all_info(torture, &finfo1); \
162                 ret = false; \
163         }} while (0)
164
165 #define CHECK_STR(call, stype, field, value) do { \
166         CHECK1(call); \
167         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && strcmp(finfo2.stype.out.field, value) != 0) { \
168                 printf("(%s) %s - %s/%s should be '%s' - '%s'\n", __location__, \
169                         call_name, #stype, #field, \
170                         value, \
171                         finfo2.stype.out.field); \
172                 dump_all_info(torture, &finfo1); \
173                 ret = false; \
174         }} while (0)
175
176 #define CHECK_STATUS(status, correct) do { \
177         if (!NT_STATUS_EQUAL(status, correct)) { \
178                 printf("(%s) Incorrect status %s - should be %s\n", \
179                        __location__, nt_errstr(status), nt_errstr(correct)); \
180                 ret = false; \
181                 goto done; \
182         }} while (0)
183
184         
185         printf("test setattr\n");
186         sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_READONLY;
187         sfinfo.setattr.in.write_time = basetime;
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("setting to NORMAL doesn't do anything\n");
193         sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_NORMAL;
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_READONLY);
197         CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
198
199         printf("a zero write_time means don't change\n");
200         sfinfo.setattr.in.attrib = 0;
201         sfinfo.setattr.in.write_time = 0;
202         CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
203         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
204         CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
205
206         printf("test setattre\n");
207         sfinfo.setattre.in.create_time = basetime + 20;
208         sfinfo.setattre.in.access_time = basetime + 30;
209         sfinfo.setattre.in.write_time  = basetime + 40;
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         sfinfo.setattre.in.create_time = 0;
216         sfinfo.setattre.in.access_time = 0;
217         sfinfo.setattre.in.write_time  = 0;
218         CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
219         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
220         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
221         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 40);
222
223         printf("test standard level\n");
224         sfinfo.standard.in.create_time = basetime + 100;
225         sfinfo.standard.in.access_time = basetime + 200;
226         sfinfo.standard.in.write_time  = basetime + 300;
227         CHECK_CALL_FNUM(STANDARD, NT_STATUS_OK);
228         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
229         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
230         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
231
232         printf("test basic_info level\n");
233         basetime += 86400;
234         unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
235         unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
236         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
237         unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
238         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
239         CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
240         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
241         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
242         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
243         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
244         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
245
246         printf("a zero time means don't change\n");
247         unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
248         unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
249         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
250         unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
251         sfinfo.basic_info.in.attrib = 0;
252         CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
253         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
254         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
255         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
256         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
257         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
258
259         printf("test basic_information level\n");
260         basetime += 86400;
261         unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
262         unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
263         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
264         unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
265         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
266         CHECK_CALL_FNUM(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_NORMAL);
272
273         CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
274         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
275         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
276         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
277         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
278         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
279
280         printf("a zero time means don't change\n");
281         unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
282         unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
283         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
284         unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
285         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
286         CHECK_CALL_FNUM(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         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
291         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
292
293         CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
294         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
295         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
296         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
297
298         /* interesting - w2k3 leaves change_time as current time for 0 change time
299            in setpathinfo
300           CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
301         */
302         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
303
304         printf("test disposition_info level\n");
305         sfinfo.disposition_info.in.delete_on_close = 1;
306         CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
307         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
308         CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
309
310         sfinfo.disposition_info.in.delete_on_close = 0;
311         CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
312         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
313         CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
314
315         printf("test disposition_information level\n");
316         sfinfo.disposition_info.in.delete_on_close = 1;
317         CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
318         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
319         CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
320
321         /* this would delete the file! */
322         /*
323           CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
324           CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
325           CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
326         */
327
328         sfinfo.disposition_info.in.delete_on_close = 0;
329         CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
330         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
331         CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
332
333         CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
334         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
335         CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
336
337         printf("test allocation_info level\n");
338         sfinfo.allocation_info.in.alloc_size = 0;
339         CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
340         CHECK_VALUE(ALL_INFO, all_info, size, 0);
341         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
342
343         sfinfo.allocation_info.in.alloc_size = 4096;
344         CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
345         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
346         CHECK_VALUE(ALL_INFO, all_info, size, 0);
347
348         RECREATE_BOTH;
349         sfinfo.allocation_info.in.alloc_size = 0;
350         CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
351         CHECK_VALUE(ALL_INFO, all_info, size, 0);
352         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
353
354         CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
355         CHECK_VALUE(ALL_INFO, all_info, size, 0);
356         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
357
358         sfinfo.allocation_info.in.alloc_size = 4096;
359         CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
360         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
361         CHECK_VALUE(ALL_INFO, all_info, size, 0);
362
363         /* setting the allocation size up via setpathinfo seems
364            to be broken in w2k3 */
365         CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
366         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
367         CHECK_VALUE(ALL_INFO, all_info, size, 0);
368
369         printf("test end_of_file_info level\n");
370         sfinfo.end_of_file_info.in.size = 37;
371         CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
372         CHECK_VALUE(ALL_INFO, all_info, size, 37);
373
374         sfinfo.end_of_file_info.in.size = 7;
375         CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
376         CHECK_VALUE(ALL_INFO, all_info, size, 7);
377
378         sfinfo.end_of_file_info.in.size = 37;
379         CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
380         CHECK_VALUE(ALL_INFO, all_info, size, 37);
381
382         CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
383         CHECK_VALUE(ALL_INFO, all_info, size, 37);
384
385         sfinfo.end_of_file_info.in.size = 7;
386         CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
387         CHECK_VALUE(ALL_INFO, all_info, size, 7);
388
389         CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
390         CHECK_VALUE(ALL_INFO, all_info, size, 7);
391
392         printf("test position_information level\n");
393         sfinfo.position_information.in.position = 123456;
394         CHECK_CALL_FNUM(POSITION_INFORMATION, NT_STATUS_OK);
395         CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);
396
397         CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
398         CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);
399
400         printf("test mode_information level\n");
401         sfinfo.mode_information.in.mode = 2;
402         CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
403         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);
404
405         CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
406         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
407
408         sfinfo.mode_information.in.mode = 1;
409         CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
410         CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
411
412         sfinfo.mode_information.in.mode = 0;
413         CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
414         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
415
416         CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
417         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
418
419 #if 0
420         printf("test unix_basic level\n");
421         CHECK_CALL_FNUM(UNIX_BASIC, NT_STATUS_OK);
422         CHECK_CALL_PATH(UNIX_BASIC, NT_STATUS_OK);
423
424         printf("test unix_link level\n");
425         CHECK_CALL_FNUM(UNIX_LINK, NT_STATUS_OK);
426         CHECK_CALL_PATH(UNIX_LINK, NT_STATUS_OK);
427 #endif
428
429 done:
430         smb_raw_exit(cli->session);
431         smbcli_close(cli->tree, fnum);
432         if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fnum_fname))) {
433                 printf("Failed to delete %s - %s\n", fnum_fname, smbcli_errstr(cli->tree));
434         }
435         if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, path_fname))) {
436                 printf("Failed to delete %s - %s\n", path_fname, smbcli_errstr(cli->tree));
437         }
438
439         return ret;
440 }
441
442 /*
443  * basic testing of all RAW_SFILEINFO_RENAME call
444  */
445 bool torture_raw_sfileinfo_rename(struct torture_context *torture,
446                                                                   struct smbcli_state *cli)
447 {
448         bool ret = true;
449         int fnum_saved, d_fnum, fnum2, fnum = -1;
450         char *fnum_fname;
451         char *fnum_fname_new;
452         char *path_fname;
453         char *path_fname_new;
454         char *path_dname;
455         char *path_dname_new;
456         char *saved_name;
457         char *saved_name_new;
458         union smb_fileinfo finfo1, finfo2;
459         union smb_setfileinfo sfinfo;
460         NTSTATUS status, status2;
461         const char *call_name;
462         bool check_fnum;
463         int n = time(NULL) % 100;
464         
465         asprintf(&path_fname, BASEDIR "\\fname_test_%d.txt", n);
466         asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n);
467         asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n);
468         asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n);
469         asprintf(&path_dname, BASEDIR "\\dname_test_%d", n);
470         asprintf(&path_dname_new, BASEDIR "\\dname_test_new_%d", n);
471
472         if (!torture_setup_dir(cli, BASEDIR)) {
473                 return false;
474         }
475
476         RECREATE_BOTH;
477
478         ZERO_STRUCT(sfinfo);
479
480         smbcli_close(cli->tree, create_complex_file(cli, torture, fnum_fname_new));
481         smbcli_close(cli->tree, create_complex_file(cli, torture, path_fname_new));
482
483         sfinfo.rename_information.in.overwrite = 0;
484         sfinfo.rename_information.in.root_fid  = 0;
485         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
486         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
487
488         sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
489         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
490
491         sfinfo.rename_information.in.new_name  = fnum_fname_new;
492         sfinfo.rename_information.in.overwrite = 1;
493         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_NOT_SUPPORTED);
494
495         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
496         sfinfo.rename_information.in.overwrite = 1;
497         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
498         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
499
500         printf("Trying rename with dest file open\n");
501         fnum2 = create_complex_file(cli, torture, fnum_fname);
502         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
503         sfinfo.rename_information.in.overwrite = 1;
504         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
505         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
506
507         fnum_saved = fnum;
508         fnum = fnum2;
509         sfinfo.disposition_info.in.delete_on_close = 1;
510         CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
511         fnum = fnum_saved;
512
513         printf("Trying rename with dest file open and delete_on_close\n");
514         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
515         sfinfo.rename_information.in.overwrite = 1;
516         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
517
518         smbcli_close(cli->tree, fnum2);
519         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
520         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
521
522         printf("Trying rename with source file open twice\n");
523         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
524         sfinfo.rename_information.in.overwrite = 1;
525         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
526         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
527
528         fnum2 = create_complex_file(cli, torture, fnum_fname);
529         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
530         sfinfo.rename_information.in.overwrite = 0;
531         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
532         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
533         smbcli_close(cli->tree, fnum2);
534
535         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
536         sfinfo.rename_information.in.overwrite = 0;
537         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
538         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
539
540         sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
541         sfinfo.rename_information.in.overwrite = 1;
542         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
543         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
544
545         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
546         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
547         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
548
549         sfinfo.rename_information.in.new_name  = path_fname+strlen(BASEDIR)+1;
550         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
551         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
552
553         printf("Trying rename with a root fid\n");
554         status = create_directory_handle(cli->tree, BASEDIR, &d_fnum);
555         CHECK_STATUS(status, NT_STATUS_OK);
556         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
557         sfinfo.rename_information.in.root_fid = d_fnum;
558         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER);
559         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
560         smbcli_close(cli->tree, d_fnum);
561
562         printf("Trying rename directory\n");
563         if (!torture_setup_dir(cli, path_dname)) {
564                 ret = false;
565                 goto done;
566         }
567         saved_name = path_fname;
568         saved_name_new = path_fname_new;
569         path_fname = path_dname;
570         path_fname_new = path_dname_new;
571         sfinfo.rename_information.in.new_name  = path_dname_new+strlen(BASEDIR)+1;
572         sfinfo.rename_information.in.overwrite = 0;
573         sfinfo.rename_information.in.root_fid  = 0;
574         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
575         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
576         path_fname = saved_name;
577         path_fname_new = saved_name_new;
578
579         if (torture_setting_bool(torture, "samba3", false)) {
580                 printf("SKIP: Trying rename directory with a handle\n");
581                 printf("SKIP: Trying rename by path while a handle is open\n");
582                 printf("SKIP: Trying rename directory by path while a handle is open\n");
583                 goto done;
584         }
585
586         printf("Trying rename directory with a handle\n");
587         status = create_directory_handle(cli->tree, path_dname_new, &d_fnum);
588         fnum_saved = fnum;
589         fnum = d_fnum;
590         saved_name = fnum_fname;
591         saved_name_new = fnum_fname_new;
592         fnum_fname = path_dname;
593         fnum_fname_new = path_dname_new;
594         sfinfo.rename_information.in.new_name  = path_dname+strlen(BASEDIR)+1;
595         sfinfo.rename_information.in.overwrite = 0;
596         sfinfo.rename_information.in.root_fid  = 0;
597         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
598         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
599         smbcli_close(cli->tree, d_fnum);
600         fnum = fnum_saved;
601         fnum_fname = saved_name;
602         fnum_fname_new = saved_name_new;
603
604         printf("Trying rename by path while a handle is open\n");
605         fnum_saved = fnum;
606         fnum = create_complex_file(cli, torture, path_fname);
607         sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
608         sfinfo.rename_information.in.overwrite = 0;
609         sfinfo.rename_information.in.root_fid  = 0;
610         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
611         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
612         /* check that the handle returns the same name */
613         check_fnum = true;
614         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
615         /* rename it back on the handle */
616         sfinfo.rename_information.in.new_name  = path_fname+strlen(BASEDIR)+1;
617         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
618         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
619         check_fnum = false;
620         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
621         smbcli_close(cli->tree, fnum);
622         fnum = fnum_saved;
623
624         printf("Trying rename directory by path while a handle is open\n");
625         status = create_directory_handle(cli->tree, path_dname, &d_fnum);
626         fnum_saved = fnum;
627         fnum = d_fnum;
628         saved_name = path_fname;
629         saved_name_new = path_fname_new;
630         path_fname = path_dname;
631         path_fname_new = path_dname_new;
632         sfinfo.rename_information.in.new_name  = path_dname_new+strlen(BASEDIR)+1;
633         sfinfo.rename_information.in.overwrite = 0;
634         sfinfo.rename_information.in.root_fid  = 0;
635         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
636         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
637         path_fname = saved_name;
638         path_fname_new = saved_name_new;
639         saved_name = fnum_fname;
640         saved_name_new = fnum_fname_new;
641         fnum_fname = path_dname;
642         fnum_fname_new = path_dname_new;
643         /* check that the handle returns the same name */
644         check_fnum = true;
645         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
646         /* rename it back on the handle */
647         sfinfo.rename_information.in.new_name  = path_dname+strlen(BASEDIR)+1;
648         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
649         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
650         fnum_fname = saved_name;
651         fnum_fname_new = saved_name_new;
652         saved_name = path_fname;
653         saved_name_new = path_fname_new;
654         path_fname = path_dname;
655         path_fname_new = path_dname_new;
656         check_fnum = false;
657         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
658         smbcli_close(cli->tree, d_fnum);
659         fnum = fnum_saved;
660         path_fname = saved_name;
661         path_fname_new = saved_name_new;
662
663 done:
664         smb_raw_exit(cli->session);
665         smbcli_deltree(cli->tree, BASEDIR);
666         return ret;
667 }
668
669 /* 
670    look for the w2k3 setpathinfo STANDARD bug
671 */
672 bool torture_raw_sfileinfo_bug(struct torture_context *torture,
673                                                            struct smbcli_state *cli)
674 {
675         const char *fname = "\\bug3.txt";
676         union smb_setfileinfo sfinfo;
677         NTSTATUS status;
678         int fnum;
679
680         if (!torture_setting_bool(torture, "dangerous", false))
681                 torture_skip(torture, 
682                         "torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n");
683
684         fnum = create_complex_file(cli, torture, fname);
685         smbcli_close(cli->tree, fnum);
686
687         sfinfo.generic.level = RAW_SFILEINFO_STANDARD;
688         sfinfo.generic.in.file.path = fname;
689
690         sfinfo.standard.in.create_time = 0;
691         sfinfo.standard.in.access_time = 0;
692         sfinfo.standard.in.write_time  = 0;
693
694         status = smb_raw_setpathinfo(cli->tree, &sfinfo);
695         printf("%s - %s\n", fname, nt_errstr(status));
696
697         printf("now try and delete %s\n", fname);
698
699         return true;
700 }