ctdb-daemon: Schedule running of callback if there are no event scripts
[Samba.git] / source4 / torture / raw / setfileinfo.c
bloba08191d0bf252ad8be51786f7a20ca410431fc92
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 *path_fname;
40 char *path_fname_new;
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;
46 bool check_fnum;
47 int n = time(NULL) % 100;
49 path_fname = talloc_asprintf(torture, BASEDIR "\\fname_test_%d.txt", n);
50 path_fname_new = talloc_asprintf(torture, BASEDIR "\\fname_test_new_%d.txt", n);
51 fnum_fname = talloc_asprintf(torture, BASEDIR "\\fnum_test_%d.txt", n);
53 torture_assert(torture, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
55 #define RECREATE_FILE(fname) do { \
56 if (fnum != -1) smbcli_close(cli->tree, fnum); \
57 fnum = create_complex_file(cli, torture, fname); \
58 if (fnum == -1) { \
59 printf("(%s) ERROR: open of %s failed (%s)\n", \
60 __location__, fname, smbcli_errstr(cli->tree)); \
61 ret = false; \
62 goto done; \
63 }} while (0)
65 #define RECREATE_BOTH do { \
66 RECREATE_FILE(path_fname); \
67 smbcli_close(cli->tree, fnum); \
68 RECREATE_FILE(fnum_fname); \
69 } while (0)
71 RECREATE_BOTH;
73 #define CHECK_CALL_FNUM(call, rightstatus) do { \
74 check_fnum = true; \
75 call_name = #call; \
76 sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
77 sfinfo.generic.in.file.fnum = fnum; \
78 status = smb_raw_setfileinfo(cli->tree, &sfinfo); \
79 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
80 torture_warning(torture, \
81 "(%s) %s - %s", __location__, #call, \
82 nt_errstr(status)); \
83 } else if (!NT_STATUS_EQUAL(status, rightstatus)) { \
84 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
85 nt_errstr(status), nt_errstr(rightstatus)); \
86 ret = false; \
87 } \
88 finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
89 finfo1.generic.in.file.fnum = fnum; \
90 status2 = smb_raw_fileinfo(cli->tree, torture, &finfo1); \
91 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
92 torture_warning(torture, \
93 "(%s) %s - %s", __location__, #call, \
94 nt_errstr(status)); \
95 } else if (!NT_STATUS_IS_OK(status2)) { \
96 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status)); \
97 ret = false; \
98 }} while (0)
100 #define CHECK_CALL_PATH(call, rightstatus) do { \
101 check_fnum = false; \
102 call_name = #call; \
103 sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
104 sfinfo.generic.in.file.path = path_fname; \
105 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
106 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
107 sfinfo.generic.in.file.path = path_fname_new; \
108 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
110 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
111 torture_warning(torture, \
112 "(%s) %s - %s", __location__, #call, \
113 nt_errstr(status)); \
114 } else if (!NT_STATUS_EQUAL(status, rightstatus)) { \
115 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
116 nt_errstr(status), nt_errstr(rightstatus)); \
117 ret = false; \
119 finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
120 finfo1.generic.in.file.path = path_fname; \
121 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
122 if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
123 finfo1.generic.in.file.path = path_fname_new; \
124 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
126 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
127 torture_warning(torture, \
128 "(%s) %s - %s", __location__, #call, \
129 nt_errstr(status)); \
130 } else if (!NT_STATUS_IS_OK(status2)) { \
131 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status2)); \
132 ret = false; \
133 }} while (0)
135 #define CHECK1(call) \
136 do { if (NT_STATUS_IS_OK(status)) { \
137 finfo2.generic.level = RAW_FILEINFO_ ## call; \
138 if (check_fnum) { \
139 finfo2.generic.in.file.fnum = fnum; \
140 status2 = smb_raw_fileinfo(cli->tree, torture, &finfo2); \
141 } else { \
142 finfo2.generic.in.file.path = path_fname; \
143 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
144 if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
145 finfo2.generic.in.file.path = path_fname_new; \
146 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
149 if (!NT_STATUS_IS_OK(status2)) { \
150 printf("%s - %s\n", #call, nt_errstr(status2)); \
151 ret = false; \
153 }} while (0)
155 #define CHECK_VALUE(call, stype, field, value) do { \
156 CHECK1(call); \
157 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
158 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
159 call_name, #stype, #field, \
160 (unsigned int)value, (unsigned int)finfo2.stype.out.field); \
161 dump_all_info(torture, &finfo1); \
162 ret = false; \
163 }} while (0)
165 #define CHECK_TIME(call, stype, field, value) do { \
166 CHECK1(call); \
167 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
168 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
169 call_name, #stype, #field, \
170 (unsigned int)value, \
171 (unsigned int)nt_time_to_unix(finfo2.stype.out.field)); \
172 printf("\t%s", timestring(torture, value)); \
173 printf("\t%s\n", nt_time_string(torture, finfo2.stype.out.field)); \
174 dump_all_info(torture, &finfo1); \
175 ret = false; \
176 }} while (0)
178 #define CHECK_STR(call, stype, field, value) do { \
179 CHECK1(call); \
180 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && strcmp(finfo2.stype.out.field, value) != 0) { \
181 printf("(%s) %s - %s/%s should be '%s' - '%s'\n", __location__, \
182 call_name, #stype, #field, \
183 value, \
184 finfo2.stype.out.field); \
185 dump_all_info(torture, &finfo1); \
186 ret = false; \
187 }} while (0)
189 #define CHECK_STATUS(status, correct) do { \
190 if (!NT_STATUS_EQUAL(status, correct)) { \
191 printf("(%s) Incorrect status %s - should be %s\n", \
192 __location__, nt_errstr(status), nt_errstr(correct)); \
193 ret = false; \
194 goto done; \
195 }} while (0)
198 printf("Test setattr\n");
199 sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_READONLY;
200 sfinfo.setattr.in.write_time = basetime;
201 CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
202 CHECK_VALUE (ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
203 CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
205 printf("setting to NORMAL doesn't do anything\n");
206 sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_NORMAL;
207 sfinfo.setattr.in.write_time = 0;
208 CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
209 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
210 CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
212 printf("a zero write_time means don't change\n");
213 sfinfo.setattr.in.attrib = 0;
214 sfinfo.setattr.in.write_time = 0;
215 CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
216 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
217 CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
219 printf("Test setattre\n");
220 sfinfo.setattre.in.create_time = basetime + 20;
221 sfinfo.setattre.in.access_time = basetime + 30;
222 sfinfo.setattre.in.write_time = basetime + 40;
223 CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
224 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
225 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
226 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 40);
228 sfinfo.setattre.in.create_time = 0;
229 sfinfo.setattre.in.access_time = 0;
230 sfinfo.setattre.in.write_time = 0;
231 CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
232 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
233 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
234 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 40);
236 printf("Test standard level\n");
237 sfinfo.standard.in.create_time = basetime + 100;
238 sfinfo.standard.in.access_time = basetime + 200;
239 sfinfo.standard.in.write_time = basetime + 300;
240 CHECK_CALL_FNUM(STANDARD, NT_STATUS_OK);
241 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
242 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
243 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
245 printf("Test basic_info level\n");
246 basetime += 86400;
247 unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
248 unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
249 unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime + 300);
250 unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
251 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
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("a zero time means don't change\n");
260 unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
261 unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
262 unix_to_nt_time(&sfinfo.basic_info.in.write_time, 0);
263 unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
264 sfinfo.basic_info.in.attrib = 0;
265 CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
266 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
267 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
268 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
269 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
270 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
272 printf("Test basic_information level\n");
273 basetime += 86400;
274 unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
275 unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
276 unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime + 300);
277 unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
278 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
279 CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
280 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
281 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
282 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
283 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
284 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
286 CHECK_CALL_PATH(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 torture_comment(torture, "try to change a file to a directory\n");
294 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
295 CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_INVALID_PARAMETER);
297 printf("a zero time means don't change\n");
298 unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
299 unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
300 unix_to_nt_time(&sfinfo.basic_info.in.write_time, 0);
301 unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
302 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
303 CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
304 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
305 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
306 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
307 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
308 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
310 CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
311 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
312 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
313 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
315 /* interesting - w2k3 leaves change_time as current time for 0 change time
316 in setpathinfo
317 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
319 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
321 printf("Test disposition_info level\n");
322 sfinfo.disposition_info.in.delete_on_close = 1;
323 CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
324 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
325 CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
327 sfinfo.disposition_info.in.delete_on_close = 0;
328 CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
329 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
330 CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
332 printf("Test disposition_information level\n");
333 sfinfo.disposition_info.in.delete_on_close = 1;
334 CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
335 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
336 CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
338 /* this would delete the file! */
340 CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
341 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
342 CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
345 sfinfo.disposition_info.in.delete_on_close = 0;
346 CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
347 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
348 CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
350 CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
351 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
352 CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
354 printf("Test allocation_info level\n");
355 sfinfo.allocation_info.in.alloc_size = 0;
356 CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
357 CHECK_VALUE(ALL_INFO, all_info, size, 0);
358 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
360 sfinfo.allocation_info.in.alloc_size = 4096;
361 CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
362 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
363 CHECK_VALUE(ALL_INFO, all_info, size, 0);
365 RECREATE_BOTH;
366 sfinfo.allocation_info.in.alloc_size = 0;
367 CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
368 CHECK_VALUE(ALL_INFO, all_info, size, 0);
369 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
371 CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
372 CHECK_VALUE(ALL_INFO, all_info, size, 0);
373 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
375 sfinfo.allocation_info.in.alloc_size = 4096;
376 CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
377 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
378 CHECK_VALUE(ALL_INFO, all_info, size, 0);
380 /* setting the allocation size up via setpathinfo seems
381 to be broken in w2k3 */
382 CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
383 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
384 CHECK_VALUE(ALL_INFO, all_info, size, 0);
386 printf("Test end_of_file_info level\n");
387 sfinfo.end_of_file_info.in.size = 37;
388 CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
389 CHECK_VALUE(ALL_INFO, all_info, size, 37);
391 sfinfo.end_of_file_info.in.size = 7;
392 CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
393 CHECK_VALUE(ALL_INFO, all_info, size, 7);
395 sfinfo.end_of_file_info.in.size = 37;
396 CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
397 CHECK_VALUE(ALL_INFO, all_info, size, 37);
399 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
400 CHECK_VALUE(ALL_INFO, all_info, size, 37);
402 sfinfo.end_of_file_info.in.size = 7;
403 CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
404 CHECK_VALUE(ALL_INFO, all_info, size, 7);
406 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
407 CHECK_VALUE(ALL_INFO, all_info, size, 7);
409 printf("Test position_information level\n");
410 sfinfo.position_information.in.position = 123456;
411 CHECK_CALL_FNUM(POSITION_INFORMATION, NT_STATUS_OK);
412 CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);
414 CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
415 CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);
417 printf("Test mode_information level\n");
418 sfinfo.mode_information.in.mode = 2;
419 CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
420 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);
422 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
423 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
425 sfinfo.mode_information.in.mode = 1;
426 CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
427 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
429 sfinfo.mode_information.in.mode = 0;
430 CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
431 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
433 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
434 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
436 #if 0
437 printf("Test unix_basic level\n");
438 CHECK_CALL_FNUM(UNIX_BASIC, NT_STATUS_OK);
439 CHECK_CALL_PATH(UNIX_BASIC, NT_STATUS_OK);
441 printf("Test unix_link level\n");
442 CHECK_CALL_FNUM(UNIX_LINK, NT_STATUS_OK);
443 CHECK_CALL_PATH(UNIX_LINK, NT_STATUS_OK);
444 #endif
446 done:
447 smb_raw_exit(cli->session);
448 smbcli_close(cli->tree, fnum);
449 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fnum_fname))) {
450 printf("Failed to delete %s - %s\n", fnum_fname, smbcli_errstr(cli->tree));
452 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, path_fname))) {
453 printf("Failed to delete %s - %s\n", path_fname, smbcli_errstr(cli->tree));
456 return ret;
460 * basic testing of all RAW_SFILEINFO_RENAME call
462 static bool
463 torture_raw_sfileinfo_rename(struct torture_context *torture,
464 struct smbcli_state *cli)
466 bool ret = true;
467 int fnum_saved, d_fnum, fnum2, fnum = -1;
468 char *fnum_fname;
469 char *fnum_fname_new;
470 char *path_fname;
471 char *path_fname_new;
472 char *path_dname;
473 char *path_dname_new;
474 char *saved_name;
475 char *saved_name_new;
476 union smb_fileinfo finfo1, finfo2;
477 union smb_setfileinfo sfinfo;
478 NTSTATUS status, status2;
479 const char *call_name;
480 bool check_fnum;
481 int n = time(NULL) % 100;
483 path_fname = talloc_asprintf(torture, BASEDIR "\\fname_test_%d.txt", n);
484 path_fname_new = talloc_asprintf(torture, BASEDIR "\\fname_test_new_%d.txt", n);
485 fnum_fname = talloc_asprintf(torture, BASEDIR "\\fnum_test_%d.txt", n);
486 fnum_fname_new = talloc_asprintf(torture, BASEDIR "\\fnum_test_new_%d.txt", n);
487 path_dname = talloc_asprintf(torture, BASEDIR "\\dname_test_%d", n);
488 path_dname_new = talloc_asprintf(torture, BASEDIR "\\dname_test_new_%d", n);
490 torture_assert(torture, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
492 RECREATE_BOTH;
494 ZERO_STRUCT(sfinfo);
496 smbcli_close(cli->tree, create_complex_file(cli, torture, fnum_fname_new));
497 smbcli_close(cli->tree, create_complex_file(cli, torture, path_fname_new));
499 sfinfo.rename_information.in.overwrite = 0;
500 sfinfo.rename_information.in.root_fid = 0;
501 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
502 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
504 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
505 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
507 sfinfo.rename_information.in.new_name = fnum_fname_new;
508 sfinfo.rename_information.in.overwrite = 1;
509 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_NOT_SUPPORTED);
511 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
512 sfinfo.rename_information.in.overwrite = 1;
513 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
514 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
516 printf("Trying rename with dest file open\n");
517 fnum2 = create_complex_file(cli, torture, fnum_fname);
518 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
519 sfinfo.rename_information.in.overwrite = 1;
520 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
521 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
523 fnum_saved = fnum;
524 fnum = fnum2;
525 sfinfo.disposition_info.in.delete_on_close = 1;
526 CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
527 fnum = fnum_saved;
529 printf("Trying rename with dest file open and delete_on_close\n");
530 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
531 sfinfo.rename_information.in.overwrite = 1;
532 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
534 smbcli_close(cli->tree, fnum2);
535 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
536 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
538 printf("Trying rename with source file open twice\n");
539 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
540 sfinfo.rename_information.in.overwrite = 1;
541 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
542 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
544 fnum2 = create_complex_file(cli, torture, fnum_fname);
545 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
546 sfinfo.rename_information.in.overwrite = 0;
547 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
548 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
549 smbcli_close(cli->tree, fnum2);
551 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
552 sfinfo.rename_information.in.overwrite = 0;
553 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
554 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
556 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
557 sfinfo.rename_information.in.overwrite = 1;
558 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
559 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
561 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
562 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
563 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
565 sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1;
566 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
567 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
569 printf("Trying rename with a root fid\n");
570 status = create_directory_handle(cli->tree, BASEDIR, &d_fnum);
571 CHECK_STATUS(status, NT_STATUS_OK);
572 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
573 sfinfo.rename_information.in.root_fid = d_fnum;
574 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER);
575 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
576 smbcli_close(cli->tree, d_fnum);
578 printf("Trying rename directory\n");
579 if (!torture_setup_dir(cli, path_dname)) {
580 ret = false;
581 goto done;
583 saved_name = path_fname;
584 saved_name_new = path_fname_new;
585 path_fname = path_dname;
586 path_fname_new = path_dname_new;
587 sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
588 sfinfo.rename_information.in.overwrite = 0;
589 sfinfo.rename_information.in.root_fid = 0;
590 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
591 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
592 path_fname = saved_name;
593 path_fname_new = saved_name_new;
595 if (torture_setting_bool(torture, "samba3", false)) {
596 printf("SKIP: Trying rename directory with a handle\n");
597 printf("SKIP: Trying rename by path while a handle is open\n");
598 printf("SKIP: Trying rename directory by path while a handle is open\n");
599 goto done;
602 printf("Trying rename directory with a handle\n");
603 status = create_directory_handle(cli->tree, path_dname_new, &d_fnum);
604 fnum_saved = fnum;
605 fnum = d_fnum;
606 saved_name = fnum_fname;
607 saved_name_new = fnum_fname_new;
608 fnum_fname = path_dname;
609 fnum_fname_new = path_dname_new;
610 sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
611 sfinfo.rename_information.in.overwrite = 0;
612 sfinfo.rename_information.in.root_fid = 0;
613 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
614 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
615 smbcli_close(cli->tree, d_fnum);
616 fnum = fnum_saved;
617 fnum_fname = saved_name;
618 fnum_fname_new = saved_name_new;
620 printf("Trying rename by path while a handle is open\n");
621 fnum_saved = fnum;
622 fnum = create_complex_file(cli, torture, path_fname);
623 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
624 sfinfo.rename_information.in.overwrite = 0;
625 sfinfo.rename_information.in.root_fid = 0;
626 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
627 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
628 /* check that the handle returns the same name */
629 check_fnum = true;
630 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
631 /* rename it back on the handle */
632 sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1;
633 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
634 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
635 check_fnum = false;
636 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
637 smbcli_close(cli->tree, fnum);
638 fnum = fnum_saved;
640 printf("Trying rename directory by path while a handle is open\n");
641 status = create_directory_handle(cli->tree, path_dname, &d_fnum);
642 fnum_saved = fnum;
643 fnum = d_fnum;
644 saved_name = path_fname;
645 saved_name_new = path_fname_new;
646 path_fname = path_dname;
647 path_fname_new = path_dname_new;
648 sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
649 sfinfo.rename_information.in.overwrite = 0;
650 sfinfo.rename_information.in.root_fid = 0;
651 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
652 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
653 path_fname = saved_name;
654 path_fname_new = saved_name_new;
655 saved_name = fnum_fname;
656 saved_name_new = fnum_fname_new;
657 fnum_fname = path_dname;
658 fnum_fname_new = path_dname_new;
659 /* check that the handle returns the same name */
660 check_fnum = true;
661 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
662 /* rename it back on the handle */
663 sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
664 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
665 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
666 fnum_fname = saved_name;
667 fnum_fname_new = saved_name_new;
668 saved_name = path_fname;
669 saved_name_new = path_fname_new;
670 path_fname = path_dname;
671 path_fname_new = path_dname_new;
672 check_fnum = false;
673 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
674 smbcli_close(cli->tree, d_fnum);
675 fnum = fnum_saved;
676 path_fname = saved_name;
677 path_fname_new = saved_name_new;
679 done:
680 smb_raw_exit(cli->session);
681 smbcli_deltree(cli->tree, BASEDIR);
682 return ret;
686 look for the w2k3 setpathinfo STANDARD bug
688 static bool torture_raw_sfileinfo_bug(struct torture_context *torture,
689 struct smbcli_state *cli)
691 const char *fname = "\\bug3.txt";
692 union smb_setfileinfo sfinfo;
693 NTSTATUS status;
694 int fnum;
696 if (!torture_setting_bool(torture, "dangerous", false))
697 torture_skip(torture,
698 "torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n");
700 fnum = create_complex_file(cli, torture, fname);
701 smbcli_close(cli->tree, fnum);
703 sfinfo.generic.level = RAW_SFILEINFO_STANDARD;
704 sfinfo.generic.in.file.path = fname;
706 sfinfo.standard.in.create_time = 0;
707 sfinfo.standard.in.access_time = 0;
708 sfinfo.standard.in.write_time = 0;
710 status = smb_raw_setpathinfo(cli->tree, &sfinfo);
711 printf("%s - %s\n", fname, nt_errstr(status));
713 printf("now try and delete %s\n", fname);
715 return true;
719 * Test both the snia cifs RAW_SFILEINFO_END_OF_FILE_INFO and the undocumented
720 * pass-through RAW_SFILEINFO_END_OF_FILE_INFORMATION in the context of
721 * trans2setpathinfo.
723 static bool
724 torture_raw_sfileinfo_eof(struct torture_context *tctx,
725 struct smbcli_state *cli1, struct smbcli_state *cli2)
727 const char *fname = BASEDIR "\\test_sfileinfo_end_of_file.dat";
728 NTSTATUS status;
729 bool ret = true;
730 union smb_open io;
731 union smb_setfileinfo sfi;
732 union smb_fileinfo qfi;
733 uint16_t fnum = 0;
735 if (!torture_setup_dir(cli1, BASEDIR)) {
736 return false;
739 /* cleanup */
740 smbcli_unlink(cli1->tree, fname);
742 io.generic.level = RAW_OPEN_NTCREATEX;
743 io.ntcreatex.in.root_fid.fnum = 0;
744 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
745 io.ntcreatex.in.alloc_size = 0;
746 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
747 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
748 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
749 io.ntcreatex.in.create_options = 0;
750 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
751 io.ntcreatex.in.security_flags = 0;
752 io.ntcreatex.in.fname = fname;
753 io.ntcreatex.in.flags = 0;
755 /* Open the file sharing none. */
756 status = smb_raw_open(cli1->tree, tctx, &io);
757 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
758 done, "Status should be OK");
759 fnum = io.ntcreatex.out.file.fnum;
761 /* Try to sfileinfo to extend the file. */
762 ZERO_STRUCT(sfi);
763 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
764 sfi.generic.in.file.path = fname;
765 sfi.end_of_file_info.in.size = 100;
766 status = smb_raw_setpathinfo(cli2->tree, &sfi);
768 /* There should be share mode contention in this case. */
769 torture_assert_ntstatus_equal_goto(tctx, status,
770 NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
771 "SHARING_VIOLATION");
773 /* Make sure the size is still 0. */
774 ZERO_STRUCT(qfi);
775 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
776 qfi.generic.in.file.path = fname;
777 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
778 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
779 done, "Status should be OK");
781 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 0,
782 "alloc_size should be 0 since the setpathinfo failed.");
784 /* Try again with the pass through instead of documented version. */
785 ZERO_STRUCT(sfi);
786 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
787 sfi.generic.in.file.path = fname;
788 sfi.end_of_file_info.in.size = 100;
789 status = smb_raw_setpathinfo(cli2->tree, &sfi);
792 * Looks like a windows bug:
793 * http://lists.samba.org/archive/cifs-protocol/2009-November/001130.html
795 if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
796 /* It succeeds! This is just weird! */
797 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
798 ret, done, "Status should be OK");
800 /* Verify that the file was actually extended to 100. */
801 ZERO_STRUCT(qfi);
802 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
803 qfi.generic.in.file.path = fname;
804 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
805 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
806 ret, done, "Status should be OK");
808 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 100,
809 "alloc_size should be 100 since the setpathinfo "
810 "succeeded.");
811 } else {
812 torture_assert_ntstatus_equal_goto(tctx, status,
813 NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
814 "SHARING_VIOLATION");
817 /* close the first file. */
818 smbcli_close(cli1->tree, fnum);
819 fnum = 0;
821 /* Try to sfileinfo to extend the file again (non-pass-through). */
822 ZERO_STRUCT(sfi);
823 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
824 sfi.generic.in.file.path = fname;
825 sfi.end_of_file_info.in.size = 200;
826 status = smb_raw_setpathinfo(cli2->tree, &sfi);
828 /* This should cause the client to retun invalid level. */
829 if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
831 * Windows sends back an invalid packet that smbclient sees
832 * and returns INTERNAL_ERROR.
834 torture_assert_ntstatus_equal_goto(tctx, status,
835 NT_STATUS_INTERNAL_ERROR, ret, done, "Status should be "
836 "INTERNAL_ERROR");
837 } else {
838 torture_assert_ntstatus_equal_goto(tctx, status,
839 NT_STATUS_INVALID_LEVEL, ret, done, "Status should be "
840 "INVALID_LEVEL");
843 /* Try to extend the file now with the passthrough level. */
844 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
845 status = smb_raw_setpathinfo(cli2->tree, &sfi);
846 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
847 done, "Status should be OK");
849 /* Verify that the file was actually extended to 200. */
850 ZERO_STRUCT(qfi);
851 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
852 qfi.generic.in.file.path = fname;
853 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
855 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
856 done, "Status should be OK");
857 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 200,
858 "alloc_size should be 200 since the setpathinfo succeeded.");
860 /* Open the file so end of file can be set by handle. */
861 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE;
862 status = smb_raw_open(cli1->tree, tctx, &io);
863 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
864 done, "Status should be OK");
865 fnum = io.ntcreatex.out.file.fnum;
867 /* Try sfileinfo to extend the file by handle (non-pass-through). */
868 ZERO_STRUCT(sfi);
869 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
870 sfi.generic.in.file.fnum = fnum;
871 sfi.end_of_file_info.in.size = 300;
872 status = smb_raw_setfileinfo(cli1->tree, &sfi);
873 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
874 done, "Status should be OK");
876 /* Verify that the file was actually extended to 300. */
877 ZERO_STRUCT(qfi);
878 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
879 qfi.generic.in.file.path = fname;
880 status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
881 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
882 done, "Status should be OK");
883 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 300,
884 "alloc_size should be 300 since the setpathinfo succeeded.");
886 /* Try sfileinfo to extend the file by handle (pass-through). */
887 ZERO_STRUCT(sfi);
888 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
889 sfi.generic.in.file.fnum = fnum;
890 sfi.end_of_file_info.in.size = 400;
891 status = smb_raw_setfileinfo(cli1->tree, &sfi);
892 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
893 done, "Status should be OK");
895 /* Verify that the file was actually extended to 300. */
896 ZERO_STRUCT(qfi);
897 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
898 qfi.generic.in.file.path = fname;
899 status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
900 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
901 done, "Status should be OK");
902 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 400,
903 "alloc_size should be 400 since the setpathinfo succeeded.");
904 done:
905 if (fnum > 0) {
906 smbcli_close(cli1->tree, fnum);
907 fnum = 0;
910 smb_raw_exit(cli1->session);
911 smb_raw_exit(cli2->session);
912 smbcli_deltree(cli1->tree, BASEDIR);
913 return ret;
916 static bool
917 torture_raw_sfileinfo_eof_access(struct torture_context *tctx,
918 struct smbcli_state *cli1, struct smbcli_state *cli2)
920 const char *fname = BASEDIR "\\test_exclusive3.dat";
921 NTSTATUS status, expected_status;
922 bool ret = true;
923 union smb_open io;
924 union smb_setfileinfo sfi;
925 uint16_t fnum=0;
926 uint32_t access_mask = 0;
928 if (!torture_setup_dir(cli1, BASEDIR)) {
929 return false;
932 /* cleanup */
933 smbcli_unlink(cli1->tree, fname);
936 * base ntcreatex parms
938 io.generic.level = RAW_OPEN_NTCREATEX;
939 io.ntcreatex.in.root_fid.fnum = 0;
940 io.ntcreatex.in.alloc_size = 0;
941 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
942 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
943 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
944 io.ntcreatex.in.create_options = 0;
945 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
946 io.ntcreatex.in.security_flags = 0;
947 io.ntcreatex.in.fname = fname;
948 io.ntcreatex.in.flags = 0;
951 for (access_mask = 1; access_mask <= 0x00001FF; access_mask++) {
952 io.ntcreatex.in.access_mask = access_mask;
954 status = smb_raw_open(cli1->tree, tctx, &io);
955 if (!NT_STATUS_IS_OK(status)) {
956 continue;
959 fnum = io.ntcreatex.out.file.fnum;
961 ZERO_STRUCT(sfi);
962 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
963 sfi.generic.in.file.fnum = fnum;
964 sfi.end_of_file_info.in.size = 100;
966 status = smb_raw_setfileinfo(cli1->tree, &sfi);
968 expected_status = (access_mask & SEC_FILE_WRITE_DATA) ?
969 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
971 if (!NT_STATUS_EQUAL(expected_status, status)) {
972 torture_comment(tctx, "0x%x wrong\n", access_mask);
975 torture_assert_ntstatus_equal_goto(tctx, status,
976 expected_status, ret, done, "Status Wrong");
978 smbcli_close(cli1->tree, fnum);
981 done:
982 smb_raw_exit(cli1->session);
983 smb_raw_exit(cli2->session);
984 smbcli_deltree(cli1->tree, BASEDIR);
985 return ret;
988 static bool
989 torture_raw_sfileinfo_archive(struct torture_context *tctx,
990 struct smbcli_state *cli)
992 const char *fname = BASEDIR "\\test_archive.dat";
993 NTSTATUS status;
994 bool ret = true;
995 union smb_open io;
996 union smb_setfileinfo sfinfo;
997 union smb_fileinfo finfo;
998 uint16_t fnum=0;
1000 torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1002 /* cleanup */
1003 smbcli_unlink(cli->tree, fname);
1006 * create a normal file, verify archive bit
1008 io.generic.level = RAW_OPEN_NTCREATEX;
1009 io.ntcreatex.in.root_fid.fnum = 0;
1010 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1011 io.ntcreatex.in.alloc_size = 0;
1012 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1013 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1014 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1015 io.ntcreatex.in.create_options = 0;
1016 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1017 io.ntcreatex.in.security_flags = 0;
1018 io.ntcreatex.in.fname = fname;
1019 io.ntcreatex.in.flags = 0;
1020 status = smb_raw_open(cli->tree, tctx, &io);
1021 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1022 ret, done, "open failed");
1023 fnum = io.ntcreatex.out.file.fnum;
1025 torture_assert_int_equal(tctx,
1026 io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1027 FILE_ATTRIBUTE_ARCHIVE,
1028 "archive bit not set");
1031 * try to turn off archive bit
1033 ZERO_STRUCT(sfinfo);
1034 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1035 sfinfo.generic.in.file.fnum = fnum;
1036 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
1037 status = smb_raw_setfileinfo(cli->tree, &sfinfo);
1038 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1039 ret, done, "setfileinfo failed");
1041 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
1042 finfo.generic.in.file.fnum = fnum;
1043 status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1044 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1045 ret, done, "fileinfo failed");
1047 torture_assert_int_equal(tctx,
1048 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1049 FILE_ATTRIBUTE_NORMAL,
1050 "archive bit set");
1052 status = smbcli_close(cli->tree, fnum);
1053 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1054 ret, done, "close failed");
1056 status = smbcli_unlink(cli->tree, fname);
1057 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1058 ret, done, "unlink failed");
1061 * create a directory, verify no archive bit
1063 io.generic.level = RAW_OPEN_NTCREATEX;
1064 io.ntcreatex.in.root_fid.fnum = 0;
1065 io.ntcreatex.in.access_mask = SEC_RIGHTS_DIR_ALL;
1066 io.ntcreatex.in.alloc_size = 0;
1067 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1068 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1069 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1070 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1071 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1072 io.ntcreatex.in.security_flags = 0;
1073 io.ntcreatex.in.fname = fname;
1074 io.ntcreatex.in.flags = 0;
1075 status = smb_raw_open(cli->tree, tctx, &io);
1076 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1077 ret, done, "directory open failed");
1078 fnum = io.ntcreatex.out.file.fnum;
1080 torture_assert_int_equal(tctx,
1081 io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1082 FILE_ATTRIBUTE_DIRECTORY,
1083 "archive bit set");
1086 * verify you can turn on archive bit
1088 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1089 sfinfo.generic.in.file.fnum = fnum;
1090 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE;
1091 status = smb_raw_setfileinfo(cli->tree, &sfinfo);
1092 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1093 ret, done, "setfileinfo failed");
1095 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
1096 finfo.generic.in.file.fnum = fnum;
1097 status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1098 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1099 ret, done, "fileinfo failed");
1101 torture_assert_int_equal(tctx,
1102 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1103 FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE,
1104 "archive bit not set");
1107 * and try to turn it back off
1109 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1110 sfinfo.generic.in.file.fnum = fnum;
1111 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
1112 status = smb_raw_setfileinfo(cli->tree, &sfinfo);
1113 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1114 ret, done, "setfileinfo failed");
1116 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
1117 finfo.generic.in.file.fnum = fnum;
1118 status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1119 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1120 ret, done, "fileinfo failed");
1122 torture_assert_int_equal(tctx,
1123 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1124 FILE_ATTRIBUTE_DIRECTORY,
1125 "archive bit set");
1127 status = smbcli_close(cli->tree, fnum);
1128 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1129 ret, done, "close failed");
1131 done:
1132 smbcli_close(cli->tree, fnum);
1133 smbcli_deltree(cli->tree, BASEDIR);
1134 return ret;
1137 struct torture_suite *torture_raw_sfileinfo(TALLOC_CTX *mem_ctx)
1139 struct torture_suite *suite = torture_suite_create(mem_ctx, "sfileinfo");
1141 torture_suite_add_1smb_test(suite, "base", torture_raw_sfileinfo_base);
1142 torture_suite_add_1smb_test(suite, "rename", torture_raw_sfileinfo_rename);
1143 torture_suite_add_1smb_test(suite, "bug", torture_raw_sfileinfo_bug);
1144 torture_suite_add_2smb_test(suite, "end-of-file",
1145 torture_raw_sfileinfo_eof);
1146 torture_suite_add_2smb_test(suite, "end-of-file-access",
1147 torture_raw_sfileinfo_eof_access);
1148 torture_suite_add_1smb_test(suite, "archive",
1149 torture_raw_sfileinfo_archive);
1151 return suite;