dsdb-acl: remove unused variable
[Samba/gebeck_regimport.git] / source4 / torture / raw / setfileinfo.c
blob95ce060177e69d324475dcb2d1bfb686b6f03a8e
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 "system/time.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "libcli/libcli.h"
24 #include "torture/util.h"
25 #include "torture/raw/proto.h"
27 #define BASEDIR "\\testsfileinfo"
29 /* basic testing of all RAW_SFILEINFO_* calls
30 for each call we test that it succeeds, and where possible test
31 for consistency between the calls.
33 static bool
34 torture_raw_sfileinfo_base(struct torture_context *torture, struct smbcli_state *cli)
36 bool ret = true;
37 int fnum = -1;
38 char *fnum_fname;
39 char *fnum_fname_new;
40 char *path_fname;
41 char *path_fname_new;
42 union smb_fileinfo finfo1, finfo2;
43 union smb_setfileinfo sfinfo;
44 NTSTATUS status, status2;
45 const char *call_name;
46 time_t basetime = (time(NULL) - 86400) & ~1;
47 bool check_fnum;
48 int n = time(NULL) % 100;
50 asprintf(&path_fname, BASEDIR "\\fname_test_%d.txt", n);
51 asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n);
52 asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n);
53 asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n);
55 torture_assert(torture, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
57 #define RECREATE_FILE(fname) do { \
58 if (fnum != -1) smbcli_close(cli->tree, fnum); \
59 fnum = create_complex_file(cli, torture, fname); \
60 if (fnum == -1) { \
61 printf("(%s) ERROR: open of %s failed (%s)\n", \
62 __location__, fname, smbcli_errstr(cli->tree)); \
63 ret = false; \
64 goto done; \
65 }} while (0)
67 #define RECREATE_BOTH do { \
68 RECREATE_FILE(path_fname); \
69 smbcli_close(cli->tree, fnum); \
70 RECREATE_FILE(fnum_fname); \
71 } while (0)
73 RECREATE_BOTH;
75 #define CHECK_CALL_FNUM(call, rightstatus) do { \
76 check_fnum = true; \
77 call_name = #call; \
78 sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
79 sfinfo.generic.in.file.fnum = fnum; \
80 status = smb_raw_setfileinfo(cli->tree, &sfinfo); \
81 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
82 torture_warning(torture, \
83 "(%s) %s - %s", __location__, #call, \
84 nt_errstr(status)); \
85 } else 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_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
94 torture_warning(torture, \
95 "(%s) %s - %s", __location__, #call, \
96 nt_errstr(status)); \
97 } else if (!NT_STATUS_IS_OK(status2)) { \
98 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status)); \
99 ret = false; \
100 }} while (0)
102 #define CHECK_CALL_PATH(call, rightstatus) do { \
103 check_fnum = false; \
104 call_name = #call; \
105 sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
106 sfinfo.generic.in.file.path = path_fname; \
107 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
108 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
109 sfinfo.generic.in.file.path = path_fname_new; \
110 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
112 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
113 torture_warning(torture, \
114 "(%s) %s - %s", __location__, #call, \
115 nt_errstr(status)); \
116 } else if (!NT_STATUS_EQUAL(status, rightstatus)) { \
117 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
118 nt_errstr(status), nt_errstr(rightstatus)); \
119 ret = false; \
121 finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
122 finfo1.generic.in.file.path = path_fname; \
123 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
124 if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
125 finfo1.generic.in.file.path = path_fname_new; \
126 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
128 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
129 torture_warning(torture, \
130 "(%s) %s - %s", __location__, #call, \
131 nt_errstr(status)); \
132 } else if (!NT_STATUS_IS_OK(status2)) { \
133 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status2)); \
134 ret = false; \
135 }} while (0)
137 #define CHECK1(call) \
138 do { if (NT_STATUS_IS_OK(status)) { \
139 finfo2.generic.level = RAW_FILEINFO_ ## call; \
140 if (check_fnum) { \
141 finfo2.generic.in.file.fnum = fnum; \
142 status2 = smb_raw_fileinfo(cli->tree, torture, &finfo2); \
143 } else { \
144 finfo2.generic.in.file.path = path_fname; \
145 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
146 if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
147 finfo2.generic.in.file.path = path_fname_new; \
148 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
151 if (!NT_STATUS_IS_OK(status2)) { \
152 printf("%s - %s\n", #call, nt_errstr(status2)); \
153 ret = false; \
155 }} while (0)
157 #define CHECK_VALUE(call, stype, field, value) do { \
158 CHECK1(call); \
159 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
160 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
161 call_name, #stype, #field, \
162 (unsigned int)value, (unsigned int)finfo2.stype.out.field); \
163 dump_all_info(torture, &finfo1); \
164 ret = false; \
165 }} while (0)
167 #define CHECK_TIME(call, stype, field, value) do { \
168 CHECK1(call); \
169 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
170 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
171 call_name, #stype, #field, \
172 (unsigned int)value, \
173 (unsigned int)nt_time_to_unix(finfo2.stype.out.field)); \
174 printf("\t%s", timestring(torture, value)); \
175 printf("\t%s\n", nt_time_string(torture, finfo2.stype.out.field)); \
176 dump_all_info(torture, &finfo1); \
177 ret = false; \
178 }} while (0)
180 #define CHECK_STR(call, stype, field, value) do { \
181 CHECK1(call); \
182 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && strcmp(finfo2.stype.out.field, value) != 0) { \
183 printf("(%s) %s - %s/%s should be '%s' - '%s'\n", __location__, \
184 call_name, #stype, #field, \
185 value, \
186 finfo2.stype.out.field); \
187 dump_all_info(torture, &finfo1); \
188 ret = false; \
189 }} while (0)
191 #define CHECK_STATUS(status, correct) do { \
192 if (!NT_STATUS_EQUAL(status, correct)) { \
193 printf("(%s) Incorrect status %s - should be %s\n", \
194 __location__, nt_errstr(status), nt_errstr(correct)); \
195 ret = false; \
196 goto done; \
197 }} while (0)
200 printf("Test setattr\n");
201 sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_READONLY;
202 sfinfo.setattr.in.write_time = basetime;
203 CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
204 CHECK_VALUE (ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
205 CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
207 printf("setting to NORMAL doesn't do anything\n");
208 sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_NORMAL;
209 sfinfo.setattr.in.write_time = 0;
210 CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
211 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
212 CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
214 printf("a zero write_time means don't change\n");
215 sfinfo.setattr.in.attrib = 0;
216 sfinfo.setattr.in.write_time = 0;
217 CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
218 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
219 CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
221 printf("Test setattre\n");
222 sfinfo.setattre.in.create_time = basetime + 20;
223 sfinfo.setattre.in.access_time = basetime + 30;
224 sfinfo.setattre.in.write_time = basetime + 40;
225 CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
226 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
227 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
228 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 40);
230 sfinfo.setattre.in.create_time = 0;
231 sfinfo.setattre.in.access_time = 0;
232 sfinfo.setattre.in.write_time = 0;
233 CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
234 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
235 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
236 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 40);
238 printf("Test standard level\n");
239 sfinfo.standard.in.create_time = basetime + 100;
240 sfinfo.standard.in.access_time = basetime + 200;
241 sfinfo.standard.in.write_time = basetime + 300;
242 CHECK_CALL_FNUM(STANDARD, 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);
247 printf("Test basic_info level\n");
248 basetime += 86400;
249 unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
250 unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
251 unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime + 300);
252 unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
253 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
254 CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
255 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
256 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
257 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
258 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
259 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
261 printf("a zero time means don't change\n");
262 unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
263 unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
264 unix_to_nt_time(&sfinfo.basic_info.in.write_time, 0);
265 unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
266 sfinfo.basic_info.in.attrib = 0;
267 CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
268 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
269 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
270 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
271 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
272 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
274 printf("Test basic_information level\n");
275 basetime += 86400;
276 unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
277 unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
278 unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime + 300);
279 unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
280 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
281 CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
282 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
283 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
284 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
285 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
286 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
288 CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
289 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
290 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
291 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
292 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
293 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
295 torture_comment(torture, "try to change a file to a directory\n");
296 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
297 CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_INVALID_PARAMETER);
299 printf("a zero time means don't change\n");
300 unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
301 unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
302 unix_to_nt_time(&sfinfo.basic_info.in.write_time, 0);
303 unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
304 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
305 CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
306 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
307 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
308 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
309 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
310 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
312 CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
313 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
314 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
315 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
317 /* interesting - w2k3 leaves change_time as current time for 0 change time
318 in setpathinfo
319 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
321 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
323 printf("Test disposition_info level\n");
324 sfinfo.disposition_info.in.delete_on_close = 1;
325 CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
326 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
327 CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
329 sfinfo.disposition_info.in.delete_on_close = 0;
330 CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
331 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
332 CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
334 printf("Test disposition_information level\n");
335 sfinfo.disposition_info.in.delete_on_close = 1;
336 CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
337 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
338 CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
340 /* this would delete the file! */
342 CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
343 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
344 CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
347 sfinfo.disposition_info.in.delete_on_close = 0;
348 CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
349 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
350 CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
352 CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
353 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
354 CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
356 printf("Test allocation_info level\n");
357 sfinfo.allocation_info.in.alloc_size = 0;
358 CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
359 CHECK_VALUE(ALL_INFO, all_info, size, 0);
360 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
362 sfinfo.allocation_info.in.alloc_size = 4096;
363 CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
364 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
365 CHECK_VALUE(ALL_INFO, all_info, size, 0);
367 RECREATE_BOTH;
368 sfinfo.allocation_info.in.alloc_size = 0;
369 CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
370 CHECK_VALUE(ALL_INFO, all_info, size, 0);
371 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
373 CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
374 CHECK_VALUE(ALL_INFO, all_info, size, 0);
375 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
377 sfinfo.allocation_info.in.alloc_size = 4096;
378 CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
379 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
380 CHECK_VALUE(ALL_INFO, all_info, size, 0);
382 /* setting the allocation size up via setpathinfo seems
383 to be broken in w2k3 */
384 CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
385 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
386 CHECK_VALUE(ALL_INFO, all_info, size, 0);
388 printf("Test end_of_file_info level\n");
389 sfinfo.end_of_file_info.in.size = 37;
390 CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
391 CHECK_VALUE(ALL_INFO, all_info, size, 37);
393 sfinfo.end_of_file_info.in.size = 7;
394 CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
395 CHECK_VALUE(ALL_INFO, all_info, size, 7);
397 sfinfo.end_of_file_info.in.size = 37;
398 CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
399 CHECK_VALUE(ALL_INFO, all_info, size, 37);
401 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
402 CHECK_VALUE(ALL_INFO, all_info, size, 37);
404 sfinfo.end_of_file_info.in.size = 7;
405 CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
406 CHECK_VALUE(ALL_INFO, all_info, size, 7);
408 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
409 CHECK_VALUE(ALL_INFO, all_info, size, 7);
411 printf("Test position_information level\n");
412 sfinfo.position_information.in.position = 123456;
413 CHECK_CALL_FNUM(POSITION_INFORMATION, NT_STATUS_OK);
414 CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);
416 CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
417 CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);
419 printf("Test mode_information level\n");
420 sfinfo.mode_information.in.mode = 2;
421 CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
422 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);
424 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
425 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
427 sfinfo.mode_information.in.mode = 1;
428 CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
429 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
431 sfinfo.mode_information.in.mode = 0;
432 CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
433 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
435 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
436 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
438 #if 0
439 printf("Test unix_basic level\n");
440 CHECK_CALL_FNUM(UNIX_BASIC, NT_STATUS_OK);
441 CHECK_CALL_PATH(UNIX_BASIC, NT_STATUS_OK);
443 printf("Test unix_link level\n");
444 CHECK_CALL_FNUM(UNIX_LINK, NT_STATUS_OK);
445 CHECK_CALL_PATH(UNIX_LINK, NT_STATUS_OK);
446 #endif
448 done:
449 smb_raw_exit(cli->session);
450 smbcli_close(cli->tree, fnum);
451 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fnum_fname))) {
452 printf("Failed to delete %s - %s\n", fnum_fname, smbcli_errstr(cli->tree));
454 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, path_fname))) {
455 printf("Failed to delete %s - %s\n", path_fname, smbcli_errstr(cli->tree));
458 return ret;
462 * basic testing of all RAW_SFILEINFO_RENAME call
464 static bool
465 torture_raw_sfileinfo_rename(struct torture_context *torture,
466 struct smbcli_state *cli)
468 bool ret = true;
469 int fnum_saved, d_fnum, fnum2, fnum = -1;
470 char *fnum_fname;
471 char *fnum_fname_new;
472 char *path_fname;
473 char *path_fname_new;
474 char *path_dname;
475 char *path_dname_new;
476 char *saved_name;
477 char *saved_name_new;
478 union smb_fileinfo finfo1, finfo2;
479 union smb_setfileinfo sfinfo;
480 NTSTATUS status, status2;
481 const char *call_name;
482 bool check_fnum;
483 int n = time(NULL) % 100;
485 asprintf(&path_fname, BASEDIR "\\fname_test_%d.txt", n);
486 asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n);
487 asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n);
488 asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n);
489 asprintf(&path_dname, BASEDIR "\\dname_test_%d", n);
490 asprintf(&path_dname_new, BASEDIR "\\dname_test_new_%d", n);
492 torture_assert(torture, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
494 RECREATE_BOTH;
496 ZERO_STRUCT(sfinfo);
498 smbcli_close(cli->tree, create_complex_file(cli, torture, fnum_fname_new));
499 smbcli_close(cli->tree, create_complex_file(cli, torture, path_fname_new));
501 sfinfo.rename_information.in.overwrite = 0;
502 sfinfo.rename_information.in.root_fid = 0;
503 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
504 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
506 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
507 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
509 sfinfo.rename_information.in.new_name = fnum_fname_new;
510 sfinfo.rename_information.in.overwrite = 1;
511 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_NOT_SUPPORTED);
513 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
514 sfinfo.rename_information.in.overwrite = 1;
515 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
516 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
518 printf("Trying rename with dest file open\n");
519 fnum2 = create_complex_file(cli, torture, fnum_fname);
520 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
521 sfinfo.rename_information.in.overwrite = 1;
522 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
523 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
525 fnum_saved = fnum;
526 fnum = fnum2;
527 sfinfo.disposition_info.in.delete_on_close = 1;
528 CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
529 fnum = fnum_saved;
531 printf("Trying rename with dest file open and delete_on_close\n");
532 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
533 sfinfo.rename_information.in.overwrite = 1;
534 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
536 smbcli_close(cli->tree, fnum2);
537 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
538 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
540 printf("Trying rename with source file open twice\n");
541 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
542 sfinfo.rename_information.in.overwrite = 1;
543 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
544 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
546 fnum2 = create_complex_file(cli, torture, fnum_fname);
547 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
548 sfinfo.rename_information.in.overwrite = 0;
549 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
550 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
551 smbcli_close(cli->tree, fnum2);
553 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
554 sfinfo.rename_information.in.overwrite = 0;
555 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
556 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
558 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
559 sfinfo.rename_information.in.overwrite = 1;
560 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
561 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
563 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
564 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
565 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
567 sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1;
568 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
569 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
571 printf("Trying rename with a root fid\n");
572 status = create_directory_handle(cli->tree, BASEDIR, &d_fnum);
573 CHECK_STATUS(status, NT_STATUS_OK);
574 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
575 sfinfo.rename_information.in.root_fid = d_fnum;
576 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER);
577 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
578 smbcli_close(cli->tree, d_fnum);
580 printf("Trying rename directory\n");
581 if (!torture_setup_dir(cli, path_dname)) {
582 ret = false;
583 goto done;
585 saved_name = path_fname;
586 saved_name_new = path_fname_new;
587 path_fname = path_dname;
588 path_fname_new = path_dname_new;
589 sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
590 sfinfo.rename_information.in.overwrite = 0;
591 sfinfo.rename_information.in.root_fid = 0;
592 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
593 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
594 path_fname = saved_name;
595 path_fname_new = saved_name_new;
597 if (torture_setting_bool(torture, "samba3", false)) {
598 printf("SKIP: Trying rename directory with a handle\n");
599 printf("SKIP: Trying rename by path while a handle is open\n");
600 printf("SKIP: Trying rename directory by path while a handle is open\n");
601 goto done;
604 printf("Trying rename directory with a handle\n");
605 status = create_directory_handle(cli->tree, path_dname_new, &d_fnum);
606 fnum_saved = fnum;
607 fnum = d_fnum;
608 saved_name = fnum_fname;
609 saved_name_new = fnum_fname_new;
610 fnum_fname = path_dname;
611 fnum_fname_new = path_dname_new;
612 sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
613 sfinfo.rename_information.in.overwrite = 0;
614 sfinfo.rename_information.in.root_fid = 0;
615 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
616 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
617 smbcli_close(cli->tree, d_fnum);
618 fnum = fnum_saved;
619 fnum_fname = saved_name;
620 fnum_fname_new = saved_name_new;
622 printf("Trying rename by path while a handle is open\n");
623 fnum_saved = fnum;
624 fnum = create_complex_file(cli, torture, path_fname);
625 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
626 sfinfo.rename_information.in.overwrite = 0;
627 sfinfo.rename_information.in.root_fid = 0;
628 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
629 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
630 /* check that the handle returns the same name */
631 check_fnum = true;
632 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
633 /* rename it back on the handle */
634 sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1;
635 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
636 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
637 check_fnum = false;
638 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
639 smbcli_close(cli->tree, fnum);
640 fnum = fnum_saved;
642 printf("Trying rename directory by path while a handle is open\n");
643 status = create_directory_handle(cli->tree, path_dname, &d_fnum);
644 fnum_saved = fnum;
645 fnum = d_fnum;
646 saved_name = path_fname;
647 saved_name_new = path_fname_new;
648 path_fname = path_dname;
649 path_fname_new = path_dname_new;
650 sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
651 sfinfo.rename_information.in.overwrite = 0;
652 sfinfo.rename_information.in.root_fid = 0;
653 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
654 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
655 path_fname = saved_name;
656 path_fname_new = saved_name_new;
657 saved_name = fnum_fname;
658 saved_name_new = fnum_fname_new;
659 fnum_fname = path_dname;
660 fnum_fname_new = path_dname_new;
661 /* check that the handle returns the same name */
662 check_fnum = true;
663 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
664 /* rename it back on the handle */
665 sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
666 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
667 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
668 fnum_fname = saved_name;
669 fnum_fname_new = saved_name_new;
670 saved_name = path_fname;
671 saved_name_new = path_fname_new;
672 path_fname = path_dname;
673 path_fname_new = path_dname_new;
674 check_fnum = false;
675 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
676 smbcli_close(cli->tree, d_fnum);
677 fnum = fnum_saved;
678 path_fname = saved_name;
679 path_fname_new = saved_name_new;
681 done:
682 smb_raw_exit(cli->session);
683 smbcli_deltree(cli->tree, BASEDIR);
684 return ret;
688 look for the w2k3 setpathinfo STANDARD bug
690 static bool torture_raw_sfileinfo_bug(struct torture_context *torture,
691 struct smbcli_state *cli)
693 const char *fname = "\\bug3.txt";
694 union smb_setfileinfo sfinfo;
695 NTSTATUS status;
696 int fnum;
698 if (!torture_setting_bool(torture, "dangerous", false))
699 torture_skip(torture,
700 "torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n");
702 fnum = create_complex_file(cli, torture, fname);
703 smbcli_close(cli->tree, fnum);
705 sfinfo.generic.level = RAW_SFILEINFO_STANDARD;
706 sfinfo.generic.in.file.path = fname;
708 sfinfo.standard.in.create_time = 0;
709 sfinfo.standard.in.access_time = 0;
710 sfinfo.standard.in.write_time = 0;
712 status = smb_raw_setpathinfo(cli->tree, &sfinfo);
713 printf("%s - %s\n", fname, nt_errstr(status));
715 printf("now try and delete %s\n", fname);
717 return true;
721 * Test both the snia cifs RAW_SFILEINFO_END_OF_FILE_INFO and the undocumented
722 * pass-through RAW_SFILEINFO_END_OF_FILE_INFORMATION in the context of
723 * trans2setpathinfo.
725 static bool
726 torture_raw_sfileinfo_eof(struct torture_context *tctx,
727 struct smbcli_state *cli1, struct smbcli_state *cli2)
729 const char *fname = BASEDIR "\\test_sfileinfo_end_of_file.dat";
730 NTSTATUS status;
731 bool ret = true;
732 union smb_open io;
733 union smb_setfileinfo sfi;
734 union smb_fileinfo qfi;
735 uint16_t fnum = 0;
737 if (!torture_setup_dir(cli1, BASEDIR)) {
738 return false;
741 /* cleanup */
742 smbcli_unlink(cli1->tree, fname);
744 io.generic.level = RAW_OPEN_NTCREATEX;
745 io.ntcreatex.in.root_fid.fnum = 0;
746 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
747 io.ntcreatex.in.alloc_size = 0;
748 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
749 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
750 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
751 io.ntcreatex.in.create_options = 0;
752 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
753 io.ntcreatex.in.security_flags = 0;
754 io.ntcreatex.in.fname = fname;
755 io.ntcreatex.in.flags = 0;
757 /* Open the file sharing none. */
758 status = smb_raw_open(cli1->tree, tctx, &io);
759 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
760 done, "Status should be OK");
761 fnum = io.ntcreatex.out.file.fnum;
763 /* Try to sfileinfo to extend the file. */
764 ZERO_STRUCT(sfi);
765 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
766 sfi.generic.in.file.path = fname;
767 sfi.end_of_file_info.in.size = 100;
768 status = smb_raw_setpathinfo(cli2->tree, &sfi);
770 /* There should be share mode contention in this case. */
771 torture_assert_ntstatus_equal_goto(tctx, status,
772 NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
773 "SHARING_VIOLATION");
775 /* Make sure the size is still 0. */
776 ZERO_STRUCT(qfi);
777 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
778 qfi.generic.in.file.path = fname;
779 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
780 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
781 done, "Status should be OK");
783 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 0,
784 "alloc_size should be 0 since the setpathinfo failed.");
786 /* Try again with the pass through instead of documented version. */
787 ZERO_STRUCT(sfi);
788 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
789 sfi.generic.in.file.path = fname;
790 sfi.end_of_file_info.in.size = 100;
791 status = smb_raw_setpathinfo(cli2->tree, &sfi);
794 * Looks like a windows bug:
795 * http://lists.samba.org/archive/cifs-protocol/2009-November/001130.html
797 if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
798 /* It succeeds! This is just weird! */
799 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
800 ret, done, "Status should be OK");
802 /* Verify that the file was actually extended to 100. */
803 ZERO_STRUCT(qfi);
804 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
805 qfi.generic.in.file.path = fname;
806 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
807 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
808 ret, done, "Status should be OK");
810 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 100,
811 "alloc_size should be 100 since the setpathinfo "
812 "succeeded.");
813 } else {
814 torture_assert_ntstatus_equal_goto(tctx, status,
815 NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
816 "SHARING_VIOLATION");
819 /* close the first file. */
820 smbcli_close(cli1->tree, fnum);
821 fnum = 0;
823 /* Try to sfileinfo to extend the file again (non-pass-through). */
824 ZERO_STRUCT(sfi);
825 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
826 sfi.generic.in.file.path = fname;
827 sfi.end_of_file_info.in.size = 200;
828 status = smb_raw_setpathinfo(cli2->tree, &sfi);
830 /* This should cause the client to retun invalid level. */
831 if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
833 * Windows sends back an invalid packet that smbclient sees
834 * and returns INTERNAL_ERROR.
836 torture_assert_ntstatus_equal_goto(tctx, status,
837 NT_STATUS_INTERNAL_ERROR, ret, done, "Status should be "
838 "INTERNAL_ERROR");
839 } else {
840 torture_assert_ntstatus_equal_goto(tctx, status,
841 NT_STATUS_INVALID_LEVEL, ret, done, "Status should be "
842 "INVALID_LEVEL");
845 /* Try to extend the file now with the passthrough level. */
846 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
847 status = smb_raw_setpathinfo(cli2->tree, &sfi);
848 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
849 done, "Status should be OK");
851 /* Verify that the file was actually extended to 200. */
852 ZERO_STRUCT(qfi);
853 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
854 qfi.generic.in.file.path = fname;
855 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
857 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
858 done, "Status should be OK");
859 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 200,
860 "alloc_size should be 200 since the setpathinfo succeeded.");
862 /* Open the file so end of file can be set by handle. */
863 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE;
864 status = smb_raw_open(cli1->tree, tctx, &io);
865 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
866 done, "Status should be OK");
867 fnum = io.ntcreatex.out.file.fnum;
869 /* Try sfileinfo to extend the file by handle (non-pass-through). */
870 ZERO_STRUCT(sfi);
871 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
872 sfi.generic.in.file.fnum = fnum;
873 sfi.end_of_file_info.in.size = 300;
874 status = smb_raw_setfileinfo(cli1->tree, &sfi);
875 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
876 done, "Status should be OK");
878 /* Verify that the file was actually extended to 300. */
879 ZERO_STRUCT(qfi);
880 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
881 qfi.generic.in.file.path = fname;
882 status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
883 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
884 done, "Status should be OK");
885 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 300,
886 "alloc_size should be 300 since the setpathinfo succeeded.");
888 /* Try sfileinfo to extend the file by handle (pass-through). */
889 ZERO_STRUCT(sfi);
890 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
891 sfi.generic.in.file.fnum = fnum;
892 sfi.end_of_file_info.in.size = 400;
893 status = smb_raw_setfileinfo(cli1->tree, &sfi);
894 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
895 done, "Status should be OK");
897 /* Verify that the file was actually extended to 300. */
898 ZERO_STRUCT(qfi);
899 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
900 qfi.generic.in.file.path = fname;
901 status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
902 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
903 done, "Status should be OK");
904 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 400,
905 "alloc_size should be 400 since the setpathinfo succeeded.");
906 done:
907 if (fnum > 0) {
908 smbcli_close(cli1->tree, fnum);
909 fnum = 0;
912 smb_raw_exit(cli1->session);
913 smb_raw_exit(cli2->session);
914 smbcli_deltree(cli1->tree, BASEDIR);
915 return ret;
918 static bool
919 torture_raw_sfileinfo_eof_access(struct torture_context *tctx,
920 struct smbcli_state *cli1, struct smbcli_state *cli2)
922 const char *fname = BASEDIR "\\test_exclusive3.dat";
923 NTSTATUS status, expected_status;
924 bool ret = true;
925 union smb_open io;
926 union smb_setfileinfo sfi;
927 uint16_t fnum=0;
928 uint32_t access_mask = 0;
930 if (!torture_setup_dir(cli1, BASEDIR)) {
931 return false;
934 /* cleanup */
935 smbcli_unlink(cli1->tree, fname);
938 * base ntcreatex parms
940 io.generic.level = RAW_OPEN_NTCREATEX;
941 io.ntcreatex.in.root_fid.fnum = 0;
942 io.ntcreatex.in.alloc_size = 0;
943 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
944 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
945 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
946 io.ntcreatex.in.create_options = 0;
947 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
948 io.ntcreatex.in.security_flags = 0;
949 io.ntcreatex.in.fname = fname;
950 io.ntcreatex.in.flags = 0;
953 for (access_mask = 1; access_mask <= 0x00001FF; access_mask++) {
954 io.ntcreatex.in.access_mask = access_mask;
956 status = smb_raw_open(cli1->tree, tctx, &io);
957 if (!NT_STATUS_IS_OK(status)) {
958 continue;
961 fnum = io.ntcreatex.out.file.fnum;
963 ZERO_STRUCT(sfi);
964 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
965 sfi.generic.in.file.fnum = fnum;
966 sfi.end_of_file_info.in.size = 100;
968 status = smb_raw_setfileinfo(cli1->tree, &sfi);
970 expected_status = (access_mask & SEC_FILE_WRITE_DATA) ?
971 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
973 if (!NT_STATUS_EQUAL(expected_status, status)) {
974 torture_comment(tctx, "0x%x wrong\n", access_mask);
977 torture_assert_ntstatus_equal_goto(tctx, status,
978 expected_status, ret, done, "Status Wrong");
980 smbcli_close(cli1->tree, fnum);
983 done:
984 smb_raw_exit(cli1->session);
985 smb_raw_exit(cli2->session);
986 smbcli_deltree(cli1->tree, BASEDIR);
987 return ret;
990 static bool
991 torture_raw_sfileinfo_archive(struct torture_context *tctx,
992 struct smbcli_state *cli)
994 const char *fname = BASEDIR "\\test_archive.dat";
995 NTSTATUS status;
996 bool ret = true;
997 union smb_open io;
998 union smb_setfileinfo sfinfo;
999 union smb_fileinfo finfo;
1000 uint16_t fnum=0;
1002 torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1004 /* cleanup */
1005 smbcli_unlink(cli->tree, fname);
1008 * create a normal file, verify archive bit
1010 io.generic.level = RAW_OPEN_NTCREATEX;
1011 io.ntcreatex.in.root_fid.fnum = 0;
1012 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1013 io.ntcreatex.in.alloc_size = 0;
1014 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1015 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1016 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1017 io.ntcreatex.in.create_options = 0;
1018 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1019 io.ntcreatex.in.security_flags = 0;
1020 io.ntcreatex.in.fname = fname;
1021 io.ntcreatex.in.flags = 0;
1022 status = smb_raw_open(cli->tree, tctx, &io);
1023 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1024 ret, done, "open failed");
1025 fnum = io.ntcreatex.out.file.fnum;
1027 torture_assert_int_equal(tctx,
1028 io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1029 FILE_ATTRIBUTE_ARCHIVE,
1030 "archive bit not set");
1033 * try to turn off archive bit
1035 ZERO_STRUCT(sfinfo);
1036 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1037 sfinfo.generic.in.file.fnum = fnum;
1038 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
1039 status = smb_raw_setfileinfo(cli->tree, &sfinfo);
1040 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1041 ret, done, "setfileinfo failed");
1043 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
1044 finfo.generic.in.file.fnum = fnum;
1045 status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1046 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1047 ret, done, "fileinfo failed");
1049 torture_assert_int_equal(tctx,
1050 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1051 FILE_ATTRIBUTE_NORMAL,
1052 "archive bit set");
1054 status = smbcli_close(cli->tree, fnum);
1055 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1056 ret, done, "close failed");
1058 status = smbcli_unlink(cli->tree, fname);
1059 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1060 ret, done, "unlink failed");
1063 * create a directory, verify no archive bit
1065 io.generic.level = RAW_OPEN_NTCREATEX;
1066 io.ntcreatex.in.root_fid.fnum = 0;
1067 io.ntcreatex.in.access_mask = SEC_RIGHTS_DIR_ALL;
1068 io.ntcreatex.in.alloc_size = 0;
1069 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1070 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1071 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1072 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1073 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1074 io.ntcreatex.in.security_flags = 0;
1075 io.ntcreatex.in.fname = fname;
1076 io.ntcreatex.in.flags = 0;
1077 status = smb_raw_open(cli->tree, tctx, &io);
1078 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1079 ret, done, "directory open failed");
1080 fnum = io.ntcreatex.out.file.fnum;
1082 torture_assert_int_equal(tctx,
1083 io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1084 FILE_ATTRIBUTE_DIRECTORY,
1085 "archive bit set");
1088 * verify you can turn on archive bit
1090 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1091 sfinfo.generic.in.file.fnum = fnum;
1092 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE;
1093 status = smb_raw_setfileinfo(cli->tree, &sfinfo);
1094 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1095 ret, done, "setfileinfo failed");
1097 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
1098 finfo.generic.in.file.fnum = fnum;
1099 status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1100 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1101 ret, done, "fileinfo failed");
1103 torture_assert_int_equal(tctx,
1104 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1105 FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE,
1106 "archive bit not set");
1109 * and try to turn it back off
1111 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1112 sfinfo.generic.in.file.fnum = fnum;
1113 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
1114 status = smb_raw_setfileinfo(cli->tree, &sfinfo);
1115 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1116 ret, done, "setfileinfo failed");
1118 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
1119 finfo.generic.in.file.fnum = fnum;
1120 status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1121 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1122 ret, done, "fileinfo failed");
1124 torture_assert_int_equal(tctx,
1125 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1126 FILE_ATTRIBUTE_DIRECTORY,
1127 "archive bit set");
1129 status = smbcli_close(cli->tree, fnum);
1130 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1131 ret, done, "close failed");
1133 done:
1134 smbcli_close(cli->tree, fnum);
1135 smbcli_deltree(cli->tree, BASEDIR);
1136 return ret;
1139 struct torture_suite *torture_raw_sfileinfo(TALLOC_CTX *mem_ctx)
1141 struct torture_suite *suite = torture_suite_create(mem_ctx, "sfileinfo");
1143 torture_suite_add_1smb_test(suite, "base", torture_raw_sfileinfo_base);
1144 torture_suite_add_1smb_test(suite, "rename", torture_raw_sfileinfo_rename);
1145 torture_suite_add_1smb_test(suite, "bug", torture_raw_sfileinfo_bug);
1146 torture_suite_add_2smb_test(suite, "end-of-file",
1147 torture_raw_sfileinfo_eof);
1148 torture_suite_add_2smb_test(suite, "end-of-file-access",
1149 torture_raw_sfileinfo_eof_access);
1150 torture_suite_add_1smb_test(suite, "archive",
1151 torture_raw_sfileinfo_archive);
1153 return suite;