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/>.
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
)
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;
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
)) {
61 #define RECREATE_FILE(fname) do { \
62 if (fnum != -1) smbcli_close(cli->tree, fnum); \
63 fnum = create_complex_file(cli, torture, fname); \
65 printf("(%s) ERROR: open of %s failed (%s)\n", \
66 __location__, fname, smbcli_errstr(cli->tree)); \
71 #define RECREATE_BOTH do { \
72 RECREATE_FILE(path_fname); \
73 smbcli_close(cli->tree, fnum); \
74 RECREATE_FILE(fnum_fname); \
79 #define CHECK_CALL_FNUM(call, rightstatus) do { \
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)); \
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)); \
98 #define CHECK_CALL_PATH(call, rightstatus) do { \
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)); \
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)); \
125 #define CHECK1(call) \
126 do { if (NT_STATUS_IS_OK(status)) { \
127 finfo2.generic.level = RAW_FILEINFO_ ## call; \
129 finfo2.generic.in.file.fnum = fnum; \
130 status2 = smb_raw_fileinfo(cli->tree, torture, &finfo2); \
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)); \
145 #define CHECK_VALUE(call, stype, field, value) do { \
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); \
155 #define CHECK_TIME(call, stype, field, value) do { \
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, \
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); \
168 #define CHECK_STR(call, stype, field, value) do { \
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, \
174 finfo2.stype.out.field); \
175 dump_all_info(torture, &finfo1); \
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)); \
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");
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");
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
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);
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);
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
);
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
));
446 * basic testing of all RAW_SFILEINFO_RENAME call
448 bool torture_raw_sfileinfo_rename(struct torture_context
*torture
,
449 struct smbcli_state
*cli
)
452 int fnum_saved
, d_fnum
, fnum2
, fnum
= -1;
454 char *fnum_fname_new
;
456 char *path_fname_new
;
458 char *path_dname_new
;
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
;
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
)) {
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
);
512 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
513 CHECK_CALL_FNUM(DISPOSITION_INFO
, NT_STATUS_OK
);
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
)) {
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");
589 printf("Trying rename directory with a handle\n");
590 status
= create_directory_handle(cli
->tree
, path_dname_new
, &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
);
604 fnum_fname
= saved_name
;
605 fnum_fname_new
= saved_name_new
;
607 printf("Trying rename by path while a handle is open\n");
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 */
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
);
623 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_fname
);
624 smbcli_close(cli
->tree
, fnum
);
627 printf("Trying rename directory by path while a handle is open\n");
628 status
= create_directory_handle(cli
->tree
, path_dname
, &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 */
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
;
660 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_dname
);
661 smbcli_close(cli
->tree
, d_fnum
);
663 path_fname
= saved_name
;
664 path_fname_new
= saved_name_new
;
667 smb_raw_exit(cli
->session
);
668 smbcli_deltree(cli
->tree
, BASEDIR
);
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
;
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
);