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