s3: Fix bug #9085.
[Samba.git] / source4 / torture / raw / setfileinfo.c
blob10eaa6710d42a4f792c85c81ac2d030fb6b8b4b2
1 /*
2 Unix SMB/CIFS implementation.
3 RAW_SFILEINFO_* individual test suite
4 Copyright (C) Andrew Tridgell 2003
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.
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.
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/>.
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"
29 #define BASEDIR "\\testsfileinfo"
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.
35 bool torture_raw_sfileinfo(struct torture_context *torture,
36 struct smbcli_state *cli)
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;
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);
57 if (!torture_setup_dir(cli, BASEDIR)) {
58 return false;
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)
71 #define RECREATE_BOTH do { \
72 RECREATE_FILE(path_fname); \
73 smbcli_close(cli->tree, fnum); \
74 RECREATE_FILE(fnum_fname); \
75 } while (0)
77 RECREATE_BOTH;
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)
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); \
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; \
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); \
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)
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); \
139 if (!NT_STATUS_IS_OK(status2)) { \
140 printf("%s - %s\n", #call, nt_errstr(status2)); \
141 ret = false; \
143 }} while (0)
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)
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)
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)
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)
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
305 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
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);
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);
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);
324 /* this would delete the file! */
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
385 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
386 CHECK_VALUE(ALL_INFO, all_info, size, 37);
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);
392 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
393 CHECK_VALUE(ALL_INFO, all_info, size, 7);
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);
400 CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
401 CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);
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);
408 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
409 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
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);
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);
419 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
420 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
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);
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
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));
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));
442 return ret;
446 * basic testing of all RAW_SFILEINFO_RENAME call
448 bool torture_raw_sfileinfo_rename(struct torture_context *torture,
449 struct smbcli_state *cli)
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;
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);
475 if (!torture_setup_dir(cli, BASEDIR)) {
476 return false;
479 RECREATE_BOTH;
481 ZERO_STRUCT(sfinfo);
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));
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);
491 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
492 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
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);
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);
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);
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;
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);
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);
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);
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);
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);
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);
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);
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);
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);
565 printf("Trying rename directory\n");
566 if (!torture_setup_dir(cli, path_dname)) {
567 ret = false;
568 goto done;
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;
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;
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;
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;
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;
666 done:
667 smb_raw_exit(cli->session);
668 smbcli_deltree(cli->tree, BASEDIR);
669 return ret;
673 look for the w2k3 setpathinfo STANDARD bug
675 bool torture_raw_sfileinfo_bug(struct torture_context *torture,
676 struct smbcli_state *cli)
678 const char *fname = "\\bug3.txt";
679 union smb_setfileinfo sfinfo;
680 NTSTATUS status;
681 int fnum;
683 if (!torture_setting_bool(torture, "dangerous", false))
684 torture_skip(torture,
685 "torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n");
687 fnum = create_complex_file(cli, torture, fname);
688 smbcli_close(cli->tree, fnum);
690 sfinfo.generic.level = RAW_SFILEINFO_STANDARD;
691 sfinfo.generic.in.file.path = fname;
693 sfinfo.standard.in.create_time = 0;
694 sfinfo.standard.in.access_time = 0;
695 sfinfo.standard.in.write_time = 0;
697 status = smb_raw_setpathinfo(cli->tree, &sfinfo);
698 printf("%s - %s\n", fname, nt_errstr(status));
700 printf("now try and delete %s\n", fname);
702 return true;