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 "system/time.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "libcli/libcli.h"
24 #include "torture/util.h"
26 #define BASEDIR "\\testsfileinfo"
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.
33 torture_raw_sfileinfo_base(struct torture_context *torture, struct smbcli_state *cli)
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;
47 int n = time(NULL) % 100;
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);
54 if (!torture_setup_dir(cli, BASEDIR)) {
58 #define RECREATE_FILE(fname) do { \
59 if (fnum != -1) smbcli_close(cli->tree, fnum); \
60 fnum = create_complex_file(cli, torture, fname); \
62 printf("(%s) ERROR: open of %s failed (%s)\n", \
63 __location__, fname, smbcli_errstr(cli->tree)); \
68 #define RECREATE_BOTH do { \
69 RECREATE_FILE(path_fname); \
70 smbcli_close(cli->tree, fnum); \
71 RECREATE_FILE(fnum_fname); \
76 #define CHECK_CALL_FNUM(call, rightstatus) do { \
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)); \
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)); \
95 #define CHECK_CALL_PATH(call, rightstatus) do { \
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); \
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)); \
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); \
117 if (!NT_STATUS_IS_OK(status2)) { \
118 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status2)); \
122 #define CHECK1(call) \
123 do { if (NT_STATUS_IS_OK(status)) { \
124 finfo2.generic.level = RAW_FILEINFO_ ## call; \
126 finfo2.generic.in.file.fnum = fnum; \
127 status2 = smb_raw_fileinfo(cli->tree, torture, &finfo2); \
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); \
136 if (!NT_STATUS_IS_OK(status2)) { \
137 printf("%s - %s\n", #call, nt_errstr(status2)); \
142 #define CHECK_VALUE(call, stype, field, value) do { \
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 (unsigned int)value, (unsigned int)finfo2.stype.out.field); \
148 dump_all_info(torture, &finfo1); \
152 #define CHECK_TIME(call, stype, field, value) do { \
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 (unsigned int)value, \
158 (unsigned int)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); \
165 #define CHECK_STR(call, stype, field, value) do { \
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, \
171 finfo2.stype.out.field); \
172 dump_all_info(torture, &finfo1); \
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)); \
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);
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);
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);
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);
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);
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);
232 printf("Test basic_info level\n");
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);
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);
259 printf("Test basic_information level\n");
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);
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);
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);
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);
298 /* interesting - w2k3 leaves change_time as current time for 0 change time
300 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
302 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
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);
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);
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);
321 /* this would delete the file! */
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
382 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
383 CHECK_VALUE(ALL_INFO, all_info, size, 37);
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);
389 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
390 CHECK_VALUE(ALL_INFO, all_info, size, 7);
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);
397 CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
398 CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);
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);
405 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
406 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
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);
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);
416 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
417 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 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);
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);
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));
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));
443 * basic testing of all RAW_SFILEINFO_RENAME call
446 torture_raw_sfileinfo_rename(struct torture_context *torture,
447 struct smbcli_state *cli)
450 int fnum_saved, d_fnum, fnum2, fnum = -1;
452 char *fnum_fname_new;
454 char *path_fname_new;
456 char *path_dname_new;
458 char *saved_name_new;
459 union smb_fileinfo finfo1, finfo2;
460 union smb_setfileinfo sfinfo;
461 NTSTATUS status, status2;
462 const char *call_name;
464 int n = time(NULL) % 100;
466 asprintf(&path_fname, BASEDIR "\\fname_test_%d.txt", n);
467 asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n);
468 asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n);
469 asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n);
470 asprintf(&path_dname, BASEDIR "\\dname_test_%d", n);
471 asprintf(&path_dname_new, BASEDIR "\\dname_test_new_%d", n);
473 if (!torture_setup_dir(cli, BASEDIR)) {
481 smbcli_close(cli->tree, create_complex_file(cli, torture, fnum_fname_new));
482 smbcli_close(cli->tree, create_complex_file(cli, torture, path_fname_new));
484 sfinfo.rename_information.in.overwrite = 0;
485 sfinfo.rename_information.in.root_fid = 0;
486 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
487 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
489 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
490 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
492 sfinfo.rename_information.in.new_name = fnum_fname_new;
493 sfinfo.rename_information.in.overwrite = 1;
494 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_NOT_SUPPORTED);
496 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
497 sfinfo.rename_information.in.overwrite = 1;
498 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
499 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
501 printf("Trying rename with dest file open\n");
502 fnum2 = create_complex_file(cli, torture, fnum_fname);
503 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
504 sfinfo.rename_information.in.overwrite = 1;
505 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
506 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
510 sfinfo.disposition_info.in.delete_on_close = 1;
511 CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
514 printf("Trying rename with dest file open and delete_on_close\n");
515 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
516 sfinfo.rename_information.in.overwrite = 1;
517 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
519 smbcli_close(cli->tree, fnum2);
520 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
521 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
523 printf("Trying rename with source file open twice\n");
524 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
525 sfinfo.rename_information.in.overwrite = 1;
526 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
527 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
529 fnum2 = create_complex_file(cli, torture, fnum_fname);
530 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
531 sfinfo.rename_information.in.overwrite = 0;
532 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
533 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
534 smbcli_close(cli->tree, fnum2);
536 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
537 sfinfo.rename_information.in.overwrite = 0;
538 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
539 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
541 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
542 sfinfo.rename_information.in.overwrite = 1;
543 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
544 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
546 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
547 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
548 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
550 sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1;
551 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
552 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
554 printf("Trying rename with a root fid\n");
555 status = create_directory_handle(cli->tree, BASEDIR, &d_fnum);
556 CHECK_STATUS(status, NT_STATUS_OK);
557 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
558 sfinfo.rename_information.in.root_fid = d_fnum;
559 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER);
560 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
561 smbcli_close(cli->tree, d_fnum);
563 printf("Trying rename directory\n");
564 if (!torture_setup_dir(cli, path_dname)) {
568 saved_name = path_fname;
569 saved_name_new = path_fname_new;
570 path_fname = path_dname;
571 path_fname_new = path_dname_new;
572 sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
573 sfinfo.rename_information.in.overwrite = 0;
574 sfinfo.rename_information.in.root_fid = 0;
575 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
576 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
577 path_fname = saved_name;
578 path_fname_new = saved_name_new;
580 if (torture_setting_bool(torture, "samba3", false)) {
581 printf("SKIP: Trying rename directory with a handle\n");
582 printf("SKIP: Trying rename by path while a handle is open\n");
583 printf("SKIP: Trying rename directory by path while a handle is open\n");
587 printf("Trying rename directory with a handle\n");
588 status = create_directory_handle(cli->tree, path_dname_new, &d_fnum);
591 saved_name = fnum_fname;
592 saved_name_new = fnum_fname_new;
593 fnum_fname = path_dname;
594 fnum_fname_new = path_dname_new;
595 sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
596 sfinfo.rename_information.in.overwrite = 0;
597 sfinfo.rename_information.in.root_fid = 0;
598 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
599 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
600 smbcli_close(cli->tree, d_fnum);
602 fnum_fname = saved_name;
603 fnum_fname_new = saved_name_new;
605 printf("Trying rename by path while a handle is open\n");
607 fnum = create_complex_file(cli, torture, path_fname);
608 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
609 sfinfo.rename_information.in.overwrite = 0;
610 sfinfo.rename_information.in.root_fid = 0;
611 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
612 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
613 /* check that the handle returns the same name */
615 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
616 /* rename it back on the handle */
617 sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1;
618 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
619 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
621 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
622 smbcli_close(cli->tree, fnum);
625 printf("Trying rename directory by path while a handle is open\n");
626 status = create_directory_handle(cli->tree, path_dname, &d_fnum);
629 saved_name = path_fname;
630 saved_name_new = path_fname_new;
631 path_fname = path_dname;
632 path_fname_new = path_dname_new;
633 sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
634 sfinfo.rename_information.in.overwrite = 0;
635 sfinfo.rename_information.in.root_fid = 0;
636 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
637 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
638 path_fname = saved_name;
639 path_fname_new = saved_name_new;
640 saved_name = fnum_fname;
641 saved_name_new = fnum_fname_new;
642 fnum_fname = path_dname;
643 fnum_fname_new = path_dname_new;
644 /* check that the handle returns the same name */
646 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
647 /* rename it back on the handle */
648 sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
649 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
650 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
651 fnum_fname = saved_name;
652 fnum_fname_new = saved_name_new;
653 saved_name = path_fname;
654 saved_name_new = path_fname_new;
655 path_fname = path_dname;
656 path_fname_new = path_dname_new;
658 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
659 smbcli_close(cli->tree, d_fnum);
661 path_fname = saved_name;
662 path_fname_new = saved_name_new;
665 smb_raw_exit(cli->session);
666 smbcli_deltree(cli->tree, BASEDIR);
671 look for the w2k3 setpathinfo STANDARD bug
673 static bool torture_raw_sfileinfo_bug(struct torture_context *torture,
674 struct smbcli_state *cli)
676 const char *fname = "\\bug3.txt";
677 union smb_setfileinfo sfinfo;
681 if (!torture_setting_bool(torture, "dangerous", false))
682 torture_skip(torture,
683 "torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n");
685 fnum = create_complex_file(cli, torture, fname);
686 smbcli_close(cli->tree, fnum);
688 sfinfo.generic.level = RAW_SFILEINFO_STANDARD;
689 sfinfo.generic.in.file.path = fname;
691 sfinfo.standard.in.create_time = 0;
692 sfinfo.standard.in.access_time = 0;
693 sfinfo.standard.in.write_time = 0;
695 status = smb_raw_setpathinfo(cli->tree, &sfinfo);
696 printf("%s - %s\n", fname, nt_errstr(status));
698 printf("now try and delete %s\n", fname);
704 * Test both the snia cifs RAW_SFILEINFO_END_OF_FILE_INFO and the undocumented
705 * pass-through RAW_SFILEINFO_END_OF_FILE_INFORMATION in the context of
709 torture_raw_sfileinfo_eof(struct torture_context *tctx,
710 struct smbcli_state *cli1, struct smbcli_state *cli2)
712 const char *fname = BASEDIR "\\test_sfileinfo_end_of_file.dat";
716 union smb_setfileinfo sfi;
717 union smb_fileinfo qfi;
720 if (!torture_setup_dir(cli1, BASEDIR)) {
725 smbcli_unlink(cli1->tree, fname);
727 io.generic.level = RAW_OPEN_NTCREATEX;
728 io.ntcreatex.in.root_fid.fnum = 0;
729 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
730 io.ntcreatex.in.alloc_size = 0;
731 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
732 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
733 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
734 io.ntcreatex.in.create_options = 0;
735 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
736 io.ntcreatex.in.security_flags = 0;
737 io.ntcreatex.in.fname = fname;
738 io.ntcreatex.in.flags = 0;
740 /* Open the file sharing none. */
741 status = smb_raw_open(cli1->tree, tctx, &io);
742 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
743 done, "Status should be OK");
744 fnum = io.ntcreatex.out.file.fnum;
746 /* Try to sfileinfo to extend the file. */
748 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
749 sfi.generic.in.file.path = fname;
750 sfi.end_of_file_info.in.size = 100;
751 status = smb_raw_setpathinfo(cli2->tree, &sfi);
753 /* There should be share mode contention in this case. */
754 torture_assert_ntstatus_equal_goto(tctx, status,
755 NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
756 "SHARING_VIOLATION");
758 /* Make sure the size is still 0. */
760 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
761 qfi.generic.in.file.path = fname;
762 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
763 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
764 done, "Status should be OK");
766 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 0,
767 "alloc_size should be 0 since the setpathinfo failed.");
769 /* Try again with the pass through instead of documented version. */
771 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
772 sfi.generic.in.file.path = fname;
773 sfi.end_of_file_info.in.size = 100;
774 status = smb_raw_setpathinfo(cli2->tree, &sfi);
777 * Looks like a windows bug:
778 * http://lists.samba.org/archive/cifs-protocol/2009-November/001130.html
780 if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
781 /* It succeeds! This is just weird! */
782 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
783 ret, done, "Status should be OK");
785 /* Verify that the file was actually extended to 100. */
787 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
788 qfi.generic.in.file.path = fname;
789 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
790 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
791 ret, done, "Status should be OK");
793 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 100,
794 "alloc_size should be 100 since the setpathinfo "
797 torture_assert_ntstatus_equal_goto(tctx, status,
798 NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
799 "SHARING_VIOLATION");
802 /* close the first file. */
803 smbcli_close(cli1->tree, fnum);
806 /* Try to sfileinfo to extend the file again (non-pass-through). */
808 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
809 sfi.generic.in.file.path = fname;
810 sfi.end_of_file_info.in.size = 200;
811 status = smb_raw_setpathinfo(cli2->tree, &sfi);
813 /* This should cause the client to retun invalid level. */
814 if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
816 * Windows sends back an invalid packet that smbclient sees
817 * and returns INTERNAL_ERROR.
819 torture_assert_ntstatus_equal_goto(tctx, status,
820 NT_STATUS_INTERNAL_ERROR, ret, done, "Status should be "
823 torture_assert_ntstatus_equal_goto(tctx, status,
824 NT_STATUS_INVALID_LEVEL, ret, done, "Status should be "
828 /* Try to extend the file now with the passthrough level. */
829 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
830 status = smb_raw_setpathinfo(cli2->tree, &sfi);
831 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
832 done, "Status should be OK");
834 /* Verify that the file was actually extended to 200. */
836 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
837 qfi.generic.in.file.path = fname;
838 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
840 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
841 done, "Status should be OK");
842 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 200,
843 "alloc_size should be 200 since the setpathinfo succeeded.");
845 /* Open the file so end of file can be set by handle. */
846 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE;
847 status = smb_raw_open(cli1->tree, tctx, &io);
848 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
849 done, "Status should be OK");
850 fnum = io.ntcreatex.out.file.fnum;
852 /* Try sfileinfo to extend the file by handle (non-pass-through). */
854 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
855 sfi.generic.in.file.fnum = fnum;
856 sfi.end_of_file_info.in.size = 300;
857 status = smb_raw_setfileinfo(cli1->tree, &sfi);
858 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
859 done, "Status should be OK");
861 /* Verify that the file was actually extended to 300. */
863 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
864 qfi.generic.in.file.path = fname;
865 status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
866 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
867 done, "Status should be OK");
868 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 300,
869 "alloc_size should be 300 since the setpathinfo succeeded.");
871 /* Try sfileinfo to extend the file by handle (pass-through). */
873 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
874 sfi.generic.in.file.fnum = fnum;
875 sfi.end_of_file_info.in.size = 400;
876 status = smb_raw_setfileinfo(cli1->tree, &sfi);
877 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
878 done, "Status should be OK");
880 /* Verify that the file was actually extended to 300. */
882 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
883 qfi.generic.in.file.path = fname;
884 status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
885 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
886 done, "Status should be OK");
887 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 400,
888 "alloc_size should be 400 since the setpathinfo succeeded.");
891 smbcli_close(cli1->tree, fnum);
895 smb_raw_exit(cli1->session);
896 smb_raw_exit(cli2->session);
897 smbcli_deltree(cli1->tree, BASEDIR);
902 torture_raw_sfileinfo_eof_access(struct torture_context *tctx,
903 struct smbcli_state *cli1, struct smbcli_state *cli2)
905 const char *fname = BASEDIR "\\test_exclusive3.dat";
906 NTSTATUS status, expected_status;
909 union smb_setfileinfo sfi;
911 uint32_t access_mask = 0;
913 if (!torture_setup_dir(cli1, BASEDIR)) {
918 smbcli_unlink(cli1->tree, fname);
921 * base ntcreatex parms
923 io.generic.level = RAW_OPEN_NTCREATEX;
924 io.ntcreatex.in.root_fid.fnum = 0;
925 io.ntcreatex.in.alloc_size = 0;
926 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
927 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
928 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
929 io.ntcreatex.in.create_options = 0;
930 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
931 io.ntcreatex.in.security_flags = 0;
932 io.ntcreatex.in.fname = fname;
933 io.ntcreatex.in.flags = 0;
936 for (access_mask = 1; access_mask <= 0x00001FF; access_mask++) {
937 io.ntcreatex.in.access_mask = access_mask;
939 status = smb_raw_open(cli1->tree, tctx, &io);
940 if (!NT_STATUS_IS_OK(status)) {
944 fnum = io.ntcreatex.out.file.fnum;
947 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
948 sfi.generic.in.file.fnum = fnum;
949 sfi.end_of_file_info.in.size = 100;
951 status = smb_raw_setfileinfo(cli1->tree, &sfi);
953 expected_status = (access_mask & SEC_FILE_WRITE_DATA) ?
954 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
956 if (!NT_STATUS_EQUAL(expected_status, status)) {
957 torture_comment(tctx, "0x%x wrong\n", access_mask);
960 torture_assert_ntstatus_equal_goto(tctx, status,
961 expected_status, ret, done, "Status Wrong");
963 smbcli_close(cli1->tree, fnum);
967 smb_raw_exit(cli1->session);
968 smb_raw_exit(cli2->session);
969 smbcli_deltree(cli1->tree, BASEDIR);
974 torture_raw_sfileinfo_archive(struct torture_context *tctx,
975 struct smbcli_state *cli)
977 const char *fname = BASEDIR "\\test_archive.dat";
981 union smb_setfileinfo sfinfo;
982 union smb_fileinfo finfo;
985 if (!torture_setup_dir(cli, BASEDIR)) {
990 smbcli_unlink(cli->tree, fname);
993 * create a normal file, verify archive bit
995 io.generic.level = RAW_OPEN_NTCREATEX;
996 io.ntcreatex.in.root_fid.fnum = 0;
997 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
998 io.ntcreatex.in.alloc_size = 0;
999 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1000 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1001 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1002 io.ntcreatex.in.create_options = 0;
1003 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1004 io.ntcreatex.in.security_flags = 0;
1005 io.ntcreatex.in.fname = fname;
1006 io.ntcreatex.in.flags = 0;
1007 status = smb_raw_open(cli->tree, tctx, &io);
1008 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1009 ret, done, "open failed");
1010 fnum = io.ntcreatex.out.file.fnum;
1012 torture_assert_int_equal(tctx,
1013 io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1014 FILE_ATTRIBUTE_ARCHIVE,
1015 "archive bit not set");
1018 * try to turn off archive bit
1020 ZERO_STRUCT(sfinfo);
1021 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1022 sfinfo.generic.in.file.fnum = fnum;
1023 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
1024 status = smb_raw_setfileinfo(cli->tree, &sfinfo);
1025 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1026 ret, done, "setfileinfo failed");
1028 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
1029 finfo.generic.in.file.fnum = fnum;
1030 status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1031 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1032 ret, done, "fileinfo failed");
1034 torture_assert_int_equal(tctx,
1035 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1036 FILE_ATTRIBUTE_NORMAL,
1039 status = smbcli_close(cli->tree, fnum);
1040 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1041 ret, done, "close failed");
1043 status = smbcli_unlink(cli->tree, fname);
1044 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1045 ret, done, "unlink failed");
1048 * create a directory, verify no archive bit
1050 io.generic.level = RAW_OPEN_NTCREATEX;
1051 io.ntcreatex.in.root_fid.fnum = 0;
1052 io.ntcreatex.in.access_mask = SEC_RIGHTS_DIR_ALL;
1053 io.ntcreatex.in.alloc_size = 0;
1054 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1055 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1056 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1057 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1058 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1059 io.ntcreatex.in.security_flags = 0;
1060 io.ntcreatex.in.fname = fname;
1061 io.ntcreatex.in.flags = 0;
1062 status = smb_raw_open(cli->tree, tctx, &io);
1063 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1064 ret, done, "directory open failed");
1065 fnum = io.ntcreatex.out.file.fnum;
1067 torture_assert_int_equal(tctx,
1068 io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1069 FILE_ATTRIBUTE_DIRECTORY,
1073 * verify you can turn on archive bit
1075 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1076 sfinfo.generic.in.file.fnum = fnum;
1077 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE;
1078 status = smb_raw_setfileinfo(cli->tree, &sfinfo);
1079 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1080 ret, done, "setfileinfo failed");
1082 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
1083 finfo.generic.in.file.fnum = fnum;
1084 status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1085 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1086 ret, done, "fileinfo failed");
1088 torture_assert_int_equal(tctx,
1089 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1090 FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE,
1091 "archive bit not set");
1094 * and try to turn it back off
1096 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1097 sfinfo.generic.in.file.fnum = fnum;
1098 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
1099 status = smb_raw_setfileinfo(cli->tree, &sfinfo);
1100 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1101 ret, done, "setfileinfo failed");
1103 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
1104 finfo.generic.in.file.fnum = fnum;
1105 status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1106 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1107 ret, done, "fileinfo failed");
1109 torture_assert_int_equal(tctx,
1110 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1111 FILE_ATTRIBUTE_DIRECTORY,
1114 status = smbcli_close(cli->tree, fnum);
1115 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1116 ret, done, "close failed");
1119 smbcli_close(cli->tree, fnum);
1120 smbcli_deltree(cli->tree, BASEDIR);
1124 struct torture_suite *torture_raw_sfileinfo(TALLOC_CTX *mem_ctx)
1126 struct torture_suite *suite = torture_suite_create(mem_ctx,
1129 torture_suite_add_1smb_test(suite, "BASE", torture_raw_sfileinfo_base);
1130 torture_suite_add_1smb_test(suite, "RENAME",
1131 torture_raw_sfileinfo_rename);
1132 torture_suite_add_1smb_test(suite, "BUG", torture_raw_sfileinfo_bug);
1133 torture_suite_add_2smb_test(suite, "END-OF-FILE",
1134 torture_raw_sfileinfo_eof);
1135 torture_suite_add_2smb_test(suite, "END-OF-FILE-ACCESS",
1136 torture_raw_sfileinfo_eof_access);
1137 torture_suite_add_1smb_test(suite, "ARCHIVE", torture_raw_sfileinfo_archive);