s3-waf: remove version from libpdb.so for now.
[Samba/vl.git] / source4 / torture / raw / setfileinfo.c
blob45414cbf9453f53acb2eee082749e6bc060b1067
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 if (!torture_setup_dir(cli, BASEDIR)) {
56 return false;
59 #define RECREATE_FILE(fname) do { \
60 if (fnum != -1) smbcli_close(cli->tree, fnum); \
61 fnum = create_complex_file(cli, torture, fname); \
62 if (fnum == -1) { \
63 printf("(%s) ERROR: open of %s failed (%s)\n", \
64 __location__, fname, smbcli_errstr(cli->tree)); \
65 ret = false; \
66 goto done; \
67 }} while (0)
69 #define RECREATE_BOTH do { \
70 RECREATE_FILE(path_fname); \
71 smbcli_close(cli->tree, fnum); \
72 RECREATE_FILE(fnum_fname); \
73 } while (0)
75 RECREATE_BOTH;
77 #define CHECK_CALL_FNUM(call, rightstatus) do { \
78 check_fnum = true; \
79 call_name = #call; \
80 sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
81 sfinfo.generic.in.file.fnum = fnum; \
82 status = smb_raw_setfileinfo(cli->tree, &sfinfo); \
83 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
84 torture_warning(torture, \
85 "(%s) %s - %s", __location__, #call, \
86 nt_errstr(status)); \
87 } else if (!NT_STATUS_EQUAL(status, rightstatus)) { \
88 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
89 nt_errstr(status), nt_errstr(rightstatus)); \
90 ret = false; \
91 } \
92 finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
93 finfo1.generic.in.file.fnum = fnum; \
94 status2 = smb_raw_fileinfo(cli->tree, torture, &finfo1); \
95 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
96 torture_warning(torture, \
97 "(%s) %s - %s", __location__, #call, \
98 nt_errstr(status)); \
99 } else if (!NT_STATUS_IS_OK(status2)) { \
100 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status)); \
101 ret = false; \
102 }} while (0)
104 #define CHECK_CALL_PATH(call, rightstatus) do { \
105 check_fnum = false; \
106 call_name = #call; \
107 sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
108 sfinfo.generic.in.file.path = path_fname; \
109 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
110 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
111 sfinfo.generic.in.file.path = path_fname_new; \
112 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
114 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
115 torture_warning(torture, \
116 "(%s) %s - %s", __location__, #call, \
117 nt_errstr(status)); \
118 } else if (!NT_STATUS_EQUAL(status, rightstatus)) { \
119 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
120 nt_errstr(status), nt_errstr(rightstatus)); \
121 ret = false; \
123 finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
124 finfo1.generic.in.file.path = path_fname; \
125 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
126 if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
127 finfo1.generic.in.file.path = path_fname_new; \
128 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
130 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
131 torture_warning(torture, \
132 "(%s) %s - %s", __location__, #call, \
133 nt_errstr(status)); \
134 } else if (!NT_STATUS_IS_OK(status2)) { \
135 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status2)); \
136 ret = false; \
137 }} while (0)
139 #define CHECK1(call) \
140 do { if (NT_STATUS_IS_OK(status)) { \
141 finfo2.generic.level = RAW_FILEINFO_ ## call; \
142 if (check_fnum) { \
143 finfo2.generic.in.file.fnum = fnum; \
144 status2 = smb_raw_fileinfo(cli->tree, torture, &finfo2); \
145 } else { \
146 finfo2.generic.in.file.path = path_fname; \
147 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
148 if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
149 finfo2.generic.in.file.path = path_fname_new; \
150 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
153 if (!NT_STATUS_IS_OK(status2)) { \
154 printf("%s - %s\n", #call, nt_errstr(status2)); \
155 ret = false; \
157 }} while (0)
159 #define CHECK_VALUE(call, stype, field, value) do { \
160 CHECK1(call); \
161 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
162 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
163 call_name, #stype, #field, \
164 (unsigned int)value, (unsigned int)finfo2.stype.out.field); \
165 dump_all_info(torture, &finfo1); \
166 ret = false; \
167 }} while (0)
169 #define CHECK_TIME(call, stype, field, value) do { \
170 CHECK1(call); \
171 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
172 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
173 call_name, #stype, #field, \
174 (unsigned int)value, \
175 (unsigned int)nt_time_to_unix(finfo2.stype.out.field)); \
176 printf("\t%s", timestring(torture, value)); \
177 printf("\t%s\n", nt_time_string(torture, finfo2.stype.out.field)); \
178 dump_all_info(torture, &finfo1); \
179 ret = false; \
180 }} while (0)
182 #define CHECK_STR(call, stype, field, value) do { \
183 CHECK1(call); \
184 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && strcmp(finfo2.stype.out.field, value) != 0) { \
185 printf("(%s) %s - %s/%s should be '%s' - '%s'\n", __location__, \
186 call_name, #stype, #field, \
187 value, \
188 finfo2.stype.out.field); \
189 dump_all_info(torture, &finfo1); \
190 ret = false; \
191 }} while (0)
193 #define CHECK_STATUS(status, correct) do { \
194 if (!NT_STATUS_EQUAL(status, correct)) { \
195 printf("(%s) Incorrect status %s - should be %s\n", \
196 __location__, nt_errstr(status), nt_errstr(correct)); \
197 ret = false; \
198 goto done; \
199 }} while (0)
202 printf("Test setattr\n");
203 sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_READONLY;
204 sfinfo.setattr.in.write_time = basetime;
205 CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
206 CHECK_VALUE (ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
207 CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
209 printf("setting to NORMAL doesn't do anything\n");
210 sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_NORMAL;
211 sfinfo.setattr.in.write_time = 0;
212 CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
213 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
214 CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
216 printf("a zero write_time means don't change\n");
217 sfinfo.setattr.in.attrib = 0;
218 sfinfo.setattr.in.write_time = 0;
219 CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
220 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
221 CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
223 printf("Test setattre\n");
224 sfinfo.setattre.in.create_time = basetime + 20;
225 sfinfo.setattre.in.access_time = basetime + 30;
226 sfinfo.setattre.in.write_time = basetime + 40;
227 CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
228 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
229 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
230 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 40);
232 sfinfo.setattre.in.create_time = 0;
233 sfinfo.setattre.in.access_time = 0;
234 sfinfo.setattre.in.write_time = 0;
235 CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
236 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
237 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
238 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 40);
240 printf("Test standard level\n");
241 sfinfo.standard.in.create_time = basetime + 100;
242 sfinfo.standard.in.access_time = basetime + 200;
243 sfinfo.standard.in.write_time = basetime + 300;
244 CHECK_CALL_FNUM(STANDARD, NT_STATUS_OK);
245 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
246 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
247 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
249 printf("Test basic_info level\n");
250 basetime += 86400;
251 unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
252 unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
253 unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime + 300);
254 unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
255 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
256 CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
257 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
258 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
259 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
260 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
261 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
263 printf("a zero time means don't change\n");
264 unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
265 unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
266 unix_to_nt_time(&sfinfo.basic_info.in.write_time, 0);
267 unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
268 sfinfo.basic_info.in.attrib = 0;
269 CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
270 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
271 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
272 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
273 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
274 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
276 printf("Test basic_information level\n");
277 basetime += 86400;
278 unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
279 unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
280 unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime + 300);
281 unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
282 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
283 CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
284 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
285 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
286 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
287 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
288 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
290 CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
291 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
292 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
293 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
294 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
295 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
297 torture_comment(torture, "try to change a file to a directory\n");
298 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
299 CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_INVALID_PARAMETER);
301 printf("a zero time means don't change\n");
302 unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
303 unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
304 unix_to_nt_time(&sfinfo.basic_info.in.write_time, 0);
305 unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
306 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
307 CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
308 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
309 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
310 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
311 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
312 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
314 CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
315 CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
316 CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
317 CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
319 /* interesting - w2k3 leaves change_time as current time for 0 change time
320 in setpathinfo
321 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
323 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
325 printf("Test disposition_info level\n");
326 sfinfo.disposition_info.in.delete_on_close = 1;
327 CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
328 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
329 CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
331 sfinfo.disposition_info.in.delete_on_close = 0;
332 CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
333 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
334 CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
336 printf("Test disposition_information level\n");
337 sfinfo.disposition_info.in.delete_on_close = 1;
338 CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
339 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
340 CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
342 /* this would delete the file! */
344 CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
345 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
346 CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
349 sfinfo.disposition_info.in.delete_on_close = 0;
350 CHECK_CALL_FNUM(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 CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
355 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
356 CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
358 printf("Test allocation_info level\n");
359 sfinfo.allocation_info.in.alloc_size = 0;
360 CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
361 CHECK_VALUE(ALL_INFO, all_info, size, 0);
362 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
364 sfinfo.allocation_info.in.alloc_size = 4096;
365 CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
366 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
367 CHECK_VALUE(ALL_INFO, all_info, size, 0);
369 RECREATE_BOTH;
370 sfinfo.allocation_info.in.alloc_size = 0;
371 CHECK_CALL_FNUM(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 CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
376 CHECK_VALUE(ALL_INFO, all_info, size, 0);
377 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
379 sfinfo.allocation_info.in.alloc_size = 4096;
380 CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
381 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
382 CHECK_VALUE(ALL_INFO, all_info, size, 0);
384 /* setting the allocation size up via setpathinfo seems
385 to be broken in w2k3 */
386 CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
387 CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
388 CHECK_VALUE(ALL_INFO, all_info, size, 0);
390 printf("Test end_of_file_info level\n");
391 sfinfo.end_of_file_info.in.size = 37;
392 CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
393 CHECK_VALUE(ALL_INFO, all_info, size, 37);
395 sfinfo.end_of_file_info.in.size = 7;
396 CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
397 CHECK_VALUE(ALL_INFO, all_info, size, 7);
399 sfinfo.end_of_file_info.in.size = 37;
400 CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
401 CHECK_VALUE(ALL_INFO, all_info, size, 37);
403 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
404 CHECK_VALUE(ALL_INFO, all_info, size, 37);
406 sfinfo.end_of_file_info.in.size = 7;
407 CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
408 CHECK_VALUE(ALL_INFO, all_info, size, 7);
410 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
411 CHECK_VALUE(ALL_INFO, all_info, size, 7);
413 printf("Test position_information level\n");
414 sfinfo.position_information.in.position = 123456;
415 CHECK_CALL_FNUM(POSITION_INFORMATION, NT_STATUS_OK);
416 CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);
418 CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
419 CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);
421 printf("Test mode_information level\n");
422 sfinfo.mode_information.in.mode = 2;
423 CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
424 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);
426 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
427 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
429 sfinfo.mode_information.in.mode = 1;
430 CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
431 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
433 sfinfo.mode_information.in.mode = 0;
434 CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
435 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
437 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
438 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
440 #if 0
441 printf("Test unix_basic level\n");
442 CHECK_CALL_FNUM(UNIX_BASIC, NT_STATUS_OK);
443 CHECK_CALL_PATH(UNIX_BASIC, NT_STATUS_OK);
445 printf("Test unix_link level\n");
446 CHECK_CALL_FNUM(UNIX_LINK, NT_STATUS_OK);
447 CHECK_CALL_PATH(UNIX_LINK, NT_STATUS_OK);
448 #endif
450 done:
451 smb_raw_exit(cli->session);
452 smbcli_close(cli->tree, fnum);
453 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fnum_fname))) {
454 printf("Failed to delete %s - %s\n", fnum_fname, smbcli_errstr(cli->tree));
456 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, path_fname))) {
457 printf("Failed to delete %s - %s\n", path_fname, smbcli_errstr(cli->tree));
460 return ret;
464 * basic testing of all RAW_SFILEINFO_RENAME call
466 static bool
467 torture_raw_sfileinfo_rename(struct torture_context *torture,
468 struct smbcli_state *cli)
470 bool ret = true;
471 int fnum_saved, d_fnum, fnum2, fnum = -1;
472 char *fnum_fname;
473 char *fnum_fname_new;
474 char *path_fname;
475 char *path_fname_new;
476 char *path_dname;
477 char *path_dname_new;
478 char *saved_name;
479 char *saved_name_new;
480 union smb_fileinfo finfo1, finfo2;
481 union smb_setfileinfo sfinfo;
482 NTSTATUS status, status2;
483 const char *call_name;
484 bool check_fnum;
485 int n = time(NULL) % 100;
487 asprintf(&path_fname, BASEDIR "\\fname_test_%d.txt", n);
488 asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n);
489 asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n);
490 asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n);
491 asprintf(&path_dname, BASEDIR "\\dname_test_%d", n);
492 asprintf(&path_dname_new, BASEDIR "\\dname_test_new_%d", n);
494 if (!torture_setup_dir(cli, BASEDIR)) {
495 return false;
498 RECREATE_BOTH;
500 ZERO_STRUCT(sfinfo);
502 smbcli_close(cli->tree, create_complex_file(cli, torture, fnum_fname_new));
503 smbcli_close(cli->tree, create_complex_file(cli, torture, path_fname_new));
505 sfinfo.rename_information.in.overwrite = 0;
506 sfinfo.rename_information.in.root_fid = 0;
507 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
508 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
510 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
511 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
513 sfinfo.rename_information.in.new_name = fnum_fname_new;
514 sfinfo.rename_information.in.overwrite = 1;
515 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_NOT_SUPPORTED);
517 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
518 sfinfo.rename_information.in.overwrite = 1;
519 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
520 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
522 printf("Trying rename with dest file open\n");
523 fnum2 = create_complex_file(cli, torture, fnum_fname);
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_ACCESS_DENIED);
527 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
529 fnum_saved = fnum;
530 fnum = fnum2;
531 sfinfo.disposition_info.in.delete_on_close = 1;
532 CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
533 fnum = fnum_saved;
535 printf("Trying rename with dest file open and delete_on_close\n");
536 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
537 sfinfo.rename_information.in.overwrite = 1;
538 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
540 smbcli_close(cli->tree, fnum2);
541 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
542 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
544 printf("Trying rename with source file open twice\n");
545 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
546 sfinfo.rename_information.in.overwrite = 1;
547 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
548 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
550 fnum2 = create_complex_file(cli, torture, fnum_fname);
551 sfinfo.rename_information.in.new_name = fnum_fname_new+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_new);
555 smbcli_close(cli->tree, fnum2);
557 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
558 sfinfo.rename_information.in.overwrite = 0;
559 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
560 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
562 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
563 sfinfo.rename_information.in.overwrite = 1;
564 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
565 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
567 sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1;
568 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
569 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
571 sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1;
572 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
573 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
575 printf("Trying rename with a root fid\n");
576 status = create_directory_handle(cli->tree, BASEDIR, &d_fnum);
577 CHECK_STATUS(status, NT_STATUS_OK);
578 sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1;
579 sfinfo.rename_information.in.root_fid = d_fnum;
580 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER);
581 CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
582 smbcli_close(cli->tree, d_fnum);
584 printf("Trying rename directory\n");
585 if (!torture_setup_dir(cli, path_dname)) {
586 ret = false;
587 goto done;
589 saved_name = path_fname;
590 saved_name_new = path_fname_new;
591 path_fname = path_dname;
592 path_fname_new = path_dname_new;
593 sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
594 sfinfo.rename_information.in.overwrite = 0;
595 sfinfo.rename_information.in.root_fid = 0;
596 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
597 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
598 path_fname = saved_name;
599 path_fname_new = saved_name_new;
601 if (torture_setting_bool(torture, "samba3", false)) {
602 printf("SKIP: Trying rename directory with a handle\n");
603 printf("SKIP: Trying rename by path while a handle is open\n");
604 printf("SKIP: Trying rename directory by path while a handle is open\n");
605 goto done;
608 printf("Trying rename directory with a handle\n");
609 status = create_directory_handle(cli->tree, path_dname_new, &d_fnum);
610 fnum_saved = fnum;
611 fnum = d_fnum;
612 saved_name = fnum_fname;
613 saved_name_new = fnum_fname_new;
614 fnum_fname = path_dname;
615 fnum_fname_new = path_dname_new;
616 sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
617 sfinfo.rename_information.in.overwrite = 0;
618 sfinfo.rename_information.in.root_fid = 0;
619 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
620 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
621 smbcli_close(cli->tree, d_fnum);
622 fnum = fnum_saved;
623 fnum_fname = saved_name;
624 fnum_fname_new = saved_name_new;
626 printf("Trying rename by path while a handle is open\n");
627 fnum_saved = fnum;
628 fnum = create_complex_file(cli, torture, path_fname);
629 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
630 sfinfo.rename_information.in.overwrite = 0;
631 sfinfo.rename_information.in.root_fid = 0;
632 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
633 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
634 /* check that the handle returns the same name */
635 check_fnum = true;
636 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
637 /* rename it back on the handle */
638 sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1;
639 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
640 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
641 check_fnum = false;
642 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
643 smbcli_close(cli->tree, fnum);
644 fnum = fnum_saved;
646 printf("Trying rename directory by path while a handle is open\n");
647 status = create_directory_handle(cli->tree, path_dname, &d_fnum);
648 fnum_saved = fnum;
649 fnum = d_fnum;
650 saved_name = path_fname;
651 saved_name_new = path_fname_new;
652 path_fname = path_dname;
653 path_fname_new = path_dname_new;
654 sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
655 sfinfo.rename_information.in.overwrite = 0;
656 sfinfo.rename_information.in.root_fid = 0;
657 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
658 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
659 path_fname = saved_name;
660 path_fname_new = saved_name_new;
661 saved_name = fnum_fname;
662 saved_name_new = fnum_fname_new;
663 fnum_fname = path_dname;
664 fnum_fname_new = path_dname_new;
665 /* check that the handle returns the same name */
666 check_fnum = true;
667 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
668 /* rename it back on the handle */
669 sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
670 CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
671 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
672 fnum_fname = saved_name;
673 fnum_fname_new = saved_name_new;
674 saved_name = path_fname;
675 saved_name_new = path_fname_new;
676 path_fname = path_dname;
677 path_fname_new = path_dname_new;
678 check_fnum = false;
679 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
680 smbcli_close(cli->tree, d_fnum);
681 fnum = fnum_saved;
682 path_fname = saved_name;
683 path_fname_new = saved_name_new;
685 done:
686 smb_raw_exit(cli->session);
687 smbcli_deltree(cli->tree, BASEDIR);
688 return ret;
692 look for the w2k3 setpathinfo STANDARD bug
694 static bool torture_raw_sfileinfo_bug(struct torture_context *torture,
695 struct smbcli_state *cli)
697 const char *fname = "\\bug3.txt";
698 union smb_setfileinfo sfinfo;
699 NTSTATUS status;
700 int fnum;
702 if (!torture_setting_bool(torture, "dangerous", false))
703 torture_skip(torture,
704 "torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n");
706 fnum = create_complex_file(cli, torture, fname);
707 smbcli_close(cli->tree, fnum);
709 sfinfo.generic.level = RAW_SFILEINFO_STANDARD;
710 sfinfo.generic.in.file.path = fname;
712 sfinfo.standard.in.create_time = 0;
713 sfinfo.standard.in.access_time = 0;
714 sfinfo.standard.in.write_time = 0;
716 status = smb_raw_setpathinfo(cli->tree, &sfinfo);
717 printf("%s - %s\n", fname, nt_errstr(status));
719 printf("now try and delete %s\n", fname);
721 return true;
725 * Test both the snia cifs RAW_SFILEINFO_END_OF_FILE_INFO and the undocumented
726 * pass-through RAW_SFILEINFO_END_OF_FILE_INFORMATION in the context of
727 * trans2setpathinfo.
729 static bool
730 torture_raw_sfileinfo_eof(struct torture_context *tctx,
731 struct smbcli_state *cli1, struct smbcli_state *cli2)
733 const char *fname = BASEDIR "\\test_sfileinfo_end_of_file.dat";
734 NTSTATUS status;
735 bool ret = true;
736 union smb_open io;
737 union smb_setfileinfo sfi;
738 union smb_fileinfo qfi;
739 uint16_t fnum = 0;
741 if (!torture_setup_dir(cli1, BASEDIR)) {
742 return false;
745 /* cleanup */
746 smbcli_unlink(cli1->tree, fname);
748 io.generic.level = RAW_OPEN_NTCREATEX;
749 io.ntcreatex.in.root_fid.fnum = 0;
750 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
751 io.ntcreatex.in.alloc_size = 0;
752 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
753 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
754 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
755 io.ntcreatex.in.create_options = 0;
756 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
757 io.ntcreatex.in.security_flags = 0;
758 io.ntcreatex.in.fname = fname;
759 io.ntcreatex.in.flags = 0;
761 /* Open the file sharing none. */
762 status = smb_raw_open(cli1->tree, tctx, &io);
763 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
764 done, "Status should be OK");
765 fnum = io.ntcreatex.out.file.fnum;
767 /* Try to sfileinfo to extend the file. */
768 ZERO_STRUCT(sfi);
769 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
770 sfi.generic.in.file.path = fname;
771 sfi.end_of_file_info.in.size = 100;
772 status = smb_raw_setpathinfo(cli2->tree, &sfi);
774 /* There should be share mode contention in this case. */
775 torture_assert_ntstatus_equal_goto(tctx, status,
776 NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
777 "SHARING_VIOLATION");
779 /* Make sure the size is still 0. */
780 ZERO_STRUCT(qfi);
781 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
782 qfi.generic.in.file.path = fname;
783 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
784 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
785 done, "Status should be OK");
787 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 0,
788 "alloc_size should be 0 since the setpathinfo failed.");
790 /* Try again with the pass through instead of documented version. */
791 ZERO_STRUCT(sfi);
792 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
793 sfi.generic.in.file.path = fname;
794 sfi.end_of_file_info.in.size = 100;
795 status = smb_raw_setpathinfo(cli2->tree, &sfi);
798 * Looks like a windows bug:
799 * http://lists.samba.org/archive/cifs-protocol/2009-November/001130.html
801 if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
802 /* It succeeds! This is just weird! */
803 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
804 ret, done, "Status should be OK");
806 /* Verify that the file was actually extended to 100. */
807 ZERO_STRUCT(qfi);
808 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
809 qfi.generic.in.file.path = fname;
810 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
811 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
812 ret, done, "Status should be OK");
814 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 100,
815 "alloc_size should be 100 since the setpathinfo "
816 "succeeded.");
817 } else {
818 torture_assert_ntstatus_equal_goto(tctx, status,
819 NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
820 "SHARING_VIOLATION");
823 /* close the first file. */
824 smbcli_close(cli1->tree, fnum);
825 fnum = 0;
827 /* Try to sfileinfo to extend the file again (non-pass-through). */
828 ZERO_STRUCT(sfi);
829 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
830 sfi.generic.in.file.path = fname;
831 sfi.end_of_file_info.in.size = 200;
832 status = smb_raw_setpathinfo(cli2->tree, &sfi);
834 /* This should cause the client to retun invalid level. */
835 if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
837 * Windows sends back an invalid packet that smbclient sees
838 * and returns INTERNAL_ERROR.
840 torture_assert_ntstatus_equal_goto(tctx, status,
841 NT_STATUS_INTERNAL_ERROR, ret, done, "Status should be "
842 "INTERNAL_ERROR");
843 } else {
844 torture_assert_ntstatus_equal_goto(tctx, status,
845 NT_STATUS_INVALID_LEVEL, ret, done, "Status should be "
846 "INVALID_LEVEL");
849 /* Try to extend the file now with the passthrough level. */
850 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
851 status = smb_raw_setpathinfo(cli2->tree, &sfi);
852 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
853 done, "Status should be OK");
855 /* Verify that the file was actually extended to 200. */
856 ZERO_STRUCT(qfi);
857 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
858 qfi.generic.in.file.path = fname;
859 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
861 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
862 done, "Status should be OK");
863 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 200,
864 "alloc_size should be 200 since the setpathinfo succeeded.");
866 /* Open the file so end of file can be set by handle. */
867 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE;
868 status = smb_raw_open(cli1->tree, tctx, &io);
869 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
870 done, "Status should be OK");
871 fnum = io.ntcreatex.out.file.fnum;
873 /* Try sfileinfo to extend the file by handle (non-pass-through). */
874 ZERO_STRUCT(sfi);
875 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
876 sfi.generic.in.file.fnum = fnum;
877 sfi.end_of_file_info.in.size = 300;
878 status = smb_raw_setfileinfo(cli1->tree, &sfi);
879 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
880 done, "Status should be OK");
882 /* Verify that the file was actually extended to 300. */
883 ZERO_STRUCT(qfi);
884 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
885 qfi.generic.in.file.path = fname;
886 status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
887 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
888 done, "Status should be OK");
889 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 300,
890 "alloc_size should be 300 since the setpathinfo succeeded.");
892 /* Try sfileinfo to extend the file by handle (pass-through). */
893 ZERO_STRUCT(sfi);
894 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
895 sfi.generic.in.file.fnum = fnum;
896 sfi.end_of_file_info.in.size = 400;
897 status = smb_raw_setfileinfo(cli1->tree, &sfi);
898 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
899 done, "Status should be OK");
901 /* Verify that the file was actually extended to 300. */
902 ZERO_STRUCT(qfi);
903 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
904 qfi.generic.in.file.path = fname;
905 status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
906 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
907 done, "Status should be OK");
908 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 400,
909 "alloc_size should be 400 since the setpathinfo succeeded.");
910 done:
911 if (fnum > 0) {
912 smbcli_close(cli1->tree, fnum);
913 fnum = 0;
916 smb_raw_exit(cli1->session);
917 smb_raw_exit(cli2->session);
918 smbcli_deltree(cli1->tree, BASEDIR);
919 return ret;
922 static bool
923 torture_raw_sfileinfo_eof_access(struct torture_context *tctx,
924 struct smbcli_state *cli1, struct smbcli_state *cli2)
926 const char *fname = BASEDIR "\\test_exclusive3.dat";
927 NTSTATUS status, expected_status;
928 bool ret = true;
929 union smb_open io;
930 union smb_setfileinfo sfi;
931 uint16_t fnum=0;
932 uint32_t access_mask = 0;
934 if (!torture_setup_dir(cli1, BASEDIR)) {
935 return false;
938 /* cleanup */
939 smbcli_unlink(cli1->tree, fname);
942 * base ntcreatex parms
944 io.generic.level = RAW_OPEN_NTCREATEX;
945 io.ntcreatex.in.root_fid.fnum = 0;
946 io.ntcreatex.in.alloc_size = 0;
947 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
948 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
949 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
950 io.ntcreatex.in.create_options = 0;
951 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
952 io.ntcreatex.in.security_flags = 0;
953 io.ntcreatex.in.fname = fname;
954 io.ntcreatex.in.flags = 0;
957 for (access_mask = 1; access_mask <= 0x00001FF; access_mask++) {
958 io.ntcreatex.in.access_mask = access_mask;
960 status = smb_raw_open(cli1->tree, tctx, &io);
961 if (!NT_STATUS_IS_OK(status)) {
962 continue;
965 fnum = io.ntcreatex.out.file.fnum;
967 ZERO_STRUCT(sfi);
968 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
969 sfi.generic.in.file.fnum = fnum;
970 sfi.end_of_file_info.in.size = 100;
972 status = smb_raw_setfileinfo(cli1->tree, &sfi);
974 expected_status = (access_mask & SEC_FILE_WRITE_DATA) ?
975 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
977 if (!NT_STATUS_EQUAL(expected_status, status)) {
978 torture_comment(tctx, "0x%x wrong\n", access_mask);
981 torture_assert_ntstatus_equal_goto(tctx, status,
982 expected_status, ret, done, "Status Wrong");
984 smbcli_close(cli1->tree, fnum);
987 done:
988 smb_raw_exit(cli1->session);
989 smb_raw_exit(cli2->session);
990 smbcli_deltree(cli1->tree, BASEDIR);
991 return ret;
994 static bool
995 torture_raw_sfileinfo_archive(struct torture_context *tctx,
996 struct smbcli_state *cli)
998 const char *fname = BASEDIR "\\test_archive.dat";
999 NTSTATUS status;
1000 bool ret = true;
1001 union smb_open io;
1002 union smb_setfileinfo sfinfo;
1003 union smb_fileinfo finfo;
1004 uint16_t fnum=0;
1006 if (!torture_setup_dir(cli, BASEDIR)) {
1007 return false;
1010 /* cleanup */
1011 smbcli_unlink(cli->tree, fname);
1014 * create a normal file, verify archive bit
1016 io.generic.level = RAW_OPEN_NTCREATEX;
1017 io.ntcreatex.in.root_fid.fnum = 0;
1018 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1019 io.ntcreatex.in.alloc_size = 0;
1020 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1021 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1022 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1023 io.ntcreatex.in.create_options = 0;
1024 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1025 io.ntcreatex.in.security_flags = 0;
1026 io.ntcreatex.in.fname = fname;
1027 io.ntcreatex.in.flags = 0;
1028 status = smb_raw_open(cli->tree, tctx, &io);
1029 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1030 ret, done, "open failed");
1031 fnum = io.ntcreatex.out.file.fnum;
1033 torture_assert_int_equal(tctx,
1034 io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1035 FILE_ATTRIBUTE_ARCHIVE,
1036 "archive bit not set");
1039 * try to turn off archive bit
1041 ZERO_STRUCT(sfinfo);
1042 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1043 sfinfo.generic.in.file.fnum = fnum;
1044 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
1045 status = smb_raw_setfileinfo(cli->tree, &sfinfo);
1046 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1047 ret, done, "setfileinfo failed");
1049 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
1050 finfo.generic.in.file.fnum = fnum;
1051 status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1052 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1053 ret, done, "fileinfo failed");
1055 torture_assert_int_equal(tctx,
1056 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1057 FILE_ATTRIBUTE_NORMAL,
1058 "archive bit set");
1060 status = smbcli_close(cli->tree, fnum);
1061 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1062 ret, done, "close failed");
1064 status = smbcli_unlink(cli->tree, fname);
1065 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1066 ret, done, "unlink failed");
1069 * create a directory, verify no archive bit
1071 io.generic.level = RAW_OPEN_NTCREATEX;
1072 io.ntcreatex.in.root_fid.fnum = 0;
1073 io.ntcreatex.in.access_mask = SEC_RIGHTS_DIR_ALL;
1074 io.ntcreatex.in.alloc_size = 0;
1075 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1076 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1077 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1078 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1079 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1080 io.ntcreatex.in.security_flags = 0;
1081 io.ntcreatex.in.fname = fname;
1082 io.ntcreatex.in.flags = 0;
1083 status = smb_raw_open(cli->tree, tctx, &io);
1084 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1085 ret, done, "directory open failed");
1086 fnum = io.ntcreatex.out.file.fnum;
1088 torture_assert_int_equal(tctx,
1089 io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1090 FILE_ATTRIBUTE_DIRECTORY,
1091 "archive bit set");
1094 * verify you can turn on archive bit
1096 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1097 sfinfo.generic.in.file.fnum = fnum;
1098 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE;
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|FILE_ATTRIBUTE_ARCHIVE,
1112 "archive bit not set");
1115 * and try to turn it back off
1117 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
1118 sfinfo.generic.in.file.fnum = fnum;
1119 sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
1120 status = smb_raw_setfileinfo(cli->tree, &sfinfo);
1121 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1122 ret, done, "setfileinfo failed");
1124 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
1125 finfo.generic.in.file.fnum = fnum;
1126 status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1127 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1128 ret, done, "fileinfo failed");
1130 torture_assert_int_equal(tctx,
1131 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1132 FILE_ATTRIBUTE_DIRECTORY,
1133 "archive bit set");
1135 status = smbcli_close(cli->tree, fnum);
1136 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1137 ret, done, "close failed");
1139 done:
1140 smbcli_close(cli->tree, fnum);
1141 smbcli_deltree(cli->tree, BASEDIR);
1142 return ret;
1145 struct torture_suite *torture_raw_sfileinfo(TALLOC_CTX *mem_ctx)
1147 struct torture_suite *suite = torture_suite_create(mem_ctx, "sfileinfo");
1149 torture_suite_add_1smb_test(suite, "base", torture_raw_sfileinfo_base);
1150 torture_suite_add_1smb_test(suite, "rename", torture_raw_sfileinfo_rename);
1151 torture_suite_add_1smb_test(suite, "bug", torture_raw_sfileinfo_bug);
1152 torture_suite_add_2smb_test(suite, "end-of-file",
1153 torture_raw_sfileinfo_eof);
1154 torture_suite_add_2smb_test(suite, "end-of-file-access",
1155 torture_raw_sfileinfo_eof_access);
1156 torture_suite_add_1smb_test(suite, "archive",
1157 torture_raw_sfileinfo_archive);
1159 return suite;