2 Unix SMB/CIFS implementation.
3 RAW_SFILEINFO_* individual test suite
4 Copyright (C) Andrew Tridgell 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "system/time.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "libcli/libcli.h"
24 #include "torture/util.h"
26 #define BASEDIR "\\testsfileinfo"
28 /* basic testing of all RAW_SFILEINFO_* calls
29 for each call we test that it succeeds, and where possible test
30 for consistency between the calls.
33 torture_raw_sfileinfo_base(struct torture_context
*torture
, struct smbcli_state
*cli
)
41 union smb_fileinfo finfo1
, finfo2
;
42 union smb_setfileinfo sfinfo
;
43 NTSTATUS status
, status2
;
44 const char *call_name
;
45 time_t basetime
= (time(NULL
) - 86400) & ~1;
47 int n
= time(NULL
) % 100;
49 asprintf(&path_fname
, BASEDIR
"\\fname_test_%d.txt", n
);
50 asprintf(&path_fname_new
, BASEDIR
"\\fname_test_new_%d.txt", n
);
51 asprintf(&fnum_fname
, BASEDIR
"\\fnum_test_%d.txt", n
);
52 asprintf(&fnum_fname_new
, BASEDIR
"\\fnum_test_new_%d.txt", n
);
54 if (!torture_setup_dir(cli
, BASEDIR
)) {
58 #define RECREATE_FILE(fname) do { \
59 if (fnum != -1) smbcli_close(cli->tree, fnum); \
60 fnum = create_complex_file(cli, torture, fname); \
62 printf("(%s) ERROR: open of %s failed (%s)\n", \
63 __location__, fname, smbcli_errstr(cli->tree)); \
68 #define RECREATE_BOTH do { \
69 RECREATE_FILE(path_fname); \
70 smbcli_close(cli->tree, fnum); \
71 RECREATE_FILE(fnum_fname); \
76 #define CHECK_CALL_FNUM(call, rightstatus) do { \
79 sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
80 sfinfo.generic.in.file.fnum = fnum; \
81 status = smb_raw_setfileinfo(cli->tree, &sfinfo); \
82 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
83 torture_warning(torture, \
84 "(%s) %s - %s", __location__, #call, \
86 } else if (!NT_STATUS_EQUAL(status, rightstatus)) { \
87 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
88 nt_errstr(status), nt_errstr(rightstatus)); \
91 finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
92 finfo1.generic.in.file.fnum = fnum; \
93 status2 = smb_raw_fileinfo(cli->tree, torture, &finfo1); \
94 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
95 torture_warning(torture, \
96 "(%s) %s - %s", __location__, #call, \
98 } else if (!NT_STATUS_IS_OK(status2)) { \
99 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status)); \
103 #define CHECK_CALL_PATH(call, rightstatus) do { \
104 check_fnum = false; \
106 sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
107 sfinfo.generic.in.file.path = path_fname; \
108 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
109 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
110 sfinfo.generic.in.file.path = path_fname_new; \
111 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
113 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
114 torture_warning(torture, \
115 "(%s) %s - %s", __location__, #call, \
116 nt_errstr(status)); \
117 } else if (!NT_STATUS_EQUAL(status, rightstatus)) { \
118 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
119 nt_errstr(status), nt_errstr(rightstatus)); \
122 finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
123 finfo1.generic.in.file.path = path_fname; \
124 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
125 if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
126 finfo1.generic.in.file.path = path_fname_new; \
127 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
129 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
130 torture_warning(torture, \
131 "(%s) %s - %s", __location__, #call, \
132 nt_errstr(status)); \
133 } else if (!NT_STATUS_IS_OK(status2)) { \
134 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status2)); \
138 #define CHECK1(call) \
139 do { if (NT_STATUS_IS_OK(status)) { \
140 finfo2.generic.level = RAW_FILEINFO_ ## call; \
142 finfo2.generic.in.file.fnum = fnum; \
143 status2 = smb_raw_fileinfo(cli->tree, torture, &finfo2); \
145 finfo2.generic.in.file.path = path_fname; \
146 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
147 if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
148 finfo2.generic.in.file.path = path_fname_new; \
149 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
152 if (!NT_STATUS_IS_OK(status2)) { \
153 printf("%s - %s\n", #call, nt_errstr(status2)); \
158 #define CHECK_VALUE(call, stype, field, value) do { \
160 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
161 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
162 call_name, #stype, #field, \
163 (unsigned int)value, (unsigned int)finfo2.stype.out.field); \
164 dump_all_info(torture, &finfo1); \
168 #define CHECK_TIME(call, stype, field, value) do { \
170 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
171 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
172 call_name, #stype, #field, \
173 (unsigned int)value, \
174 (unsigned int)nt_time_to_unix(finfo2.stype.out.field)); \
175 printf("\t%s", timestring(torture, value)); \
176 printf("\t%s\n", nt_time_string(torture, finfo2.stype.out.field)); \
177 dump_all_info(torture, &finfo1); \
181 #define CHECK_STR(call, stype, field, value) do { \
183 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && strcmp(finfo2.stype.out.field, value) != 0) { \
184 printf("(%s) %s - %s/%s should be '%s' - '%s'\n", __location__, \
185 call_name, #stype, #field, \
187 finfo2.stype.out.field); \
188 dump_all_info(torture, &finfo1); \
192 #define CHECK_STATUS(status, correct) do { \
193 if (!NT_STATUS_EQUAL(status, correct)) { \
194 printf("(%s) Incorrect status %s - should be %s\n", \
195 __location__, nt_errstr(status), nt_errstr(correct)); \
201 printf("Test setattr\n");
202 sfinfo
.setattr
.in
.attrib
= FILE_ATTRIBUTE_READONLY
;
203 sfinfo
.setattr
.in
.write_time
= basetime
;
204 CHECK_CALL_PATH(SETATTR
, NT_STATUS_OK
);
205 CHECK_VALUE (ALL_INFO
, all_info
, attrib
, FILE_ATTRIBUTE_READONLY
);
206 CHECK_TIME (ALL_INFO
, all_info
, write_time
, basetime
);
208 printf("setting to NORMAL doesn't do anything\n");
209 sfinfo
.setattr
.in
.attrib
= FILE_ATTRIBUTE_NORMAL
;
210 sfinfo
.setattr
.in
.write_time
= 0;
211 CHECK_CALL_PATH(SETATTR
, NT_STATUS_OK
);
212 CHECK_VALUE(ALL_INFO
, all_info
, attrib
, FILE_ATTRIBUTE_READONLY
);
213 CHECK_TIME (ALL_INFO
, all_info
, write_time
, basetime
);
215 printf("a zero write_time means don't change\n");
216 sfinfo
.setattr
.in
.attrib
= 0;
217 sfinfo
.setattr
.in
.write_time
= 0;
218 CHECK_CALL_PATH(SETATTR
, NT_STATUS_OK
);
219 CHECK_VALUE(ALL_INFO
, all_info
, attrib
, FILE_ATTRIBUTE_NORMAL
);
220 CHECK_TIME (ALL_INFO
, all_info
, write_time
, basetime
);
222 printf("Test setattre\n");
223 sfinfo
.setattre
.in
.create_time
= basetime
+ 20;
224 sfinfo
.setattre
.in
.access_time
= basetime
+ 30;
225 sfinfo
.setattre
.in
.write_time
= basetime
+ 40;
226 CHECK_CALL_FNUM(SETATTRE
, NT_STATUS_OK
);
227 CHECK_TIME(ALL_INFO
, all_info
, create_time
, basetime
+ 20);
228 CHECK_TIME(ALL_INFO
, all_info
, access_time
, basetime
+ 30);
229 CHECK_TIME(ALL_INFO
, all_info
, write_time
, basetime
+ 40);
231 sfinfo
.setattre
.in
.create_time
= 0;
232 sfinfo
.setattre
.in
.access_time
= 0;
233 sfinfo
.setattre
.in
.write_time
= 0;
234 CHECK_CALL_FNUM(SETATTRE
, NT_STATUS_OK
);
235 CHECK_TIME(ALL_INFO
, all_info
, create_time
, basetime
+ 20);
236 CHECK_TIME(ALL_INFO
, all_info
, access_time
, basetime
+ 30);
237 CHECK_TIME(ALL_INFO
, all_info
, write_time
, basetime
+ 40);
239 printf("Test standard level\n");
240 sfinfo
.standard
.in
.create_time
= basetime
+ 100;
241 sfinfo
.standard
.in
.access_time
= basetime
+ 200;
242 sfinfo
.standard
.in
.write_time
= basetime
+ 300;
243 CHECK_CALL_FNUM(STANDARD
, NT_STATUS_OK
);
244 CHECK_TIME(ALL_INFO
, all_info
, create_time
, basetime
+ 100);
245 CHECK_TIME(ALL_INFO
, all_info
, access_time
, basetime
+ 200);
246 CHECK_TIME(ALL_INFO
, all_info
, write_time
, basetime
+ 300);
248 printf("Test basic_info level\n");
250 unix_to_nt_time(&sfinfo
.basic_info
.in
.create_time
, basetime
+ 100);
251 unix_to_nt_time(&sfinfo
.basic_info
.in
.access_time
, basetime
+ 200);
252 unix_to_nt_time(&sfinfo
.basic_info
.in
.write_time
, basetime
+ 300);
253 unix_to_nt_time(&sfinfo
.basic_info
.in
.change_time
, basetime
+ 400);
254 sfinfo
.basic_info
.in
.attrib
= FILE_ATTRIBUTE_READONLY
;
255 CHECK_CALL_FNUM(BASIC_INFO
, NT_STATUS_OK
);
256 CHECK_TIME(ALL_INFO
, all_info
, create_time
, basetime
+ 100);
257 CHECK_TIME(ALL_INFO
, all_info
, access_time
, basetime
+ 200);
258 CHECK_TIME(ALL_INFO
, all_info
, write_time
, basetime
+ 300);
259 CHECK_TIME(ALL_INFO
, all_info
, change_time
, basetime
+ 400);
260 CHECK_VALUE(ALL_INFO
, all_info
, attrib
, FILE_ATTRIBUTE_READONLY
);
262 printf("a zero time means don't change\n");
263 unix_to_nt_time(&sfinfo
.basic_info
.in
.create_time
, 0);
264 unix_to_nt_time(&sfinfo
.basic_info
.in
.access_time
, 0);
265 unix_to_nt_time(&sfinfo
.basic_info
.in
.write_time
, 0);
266 unix_to_nt_time(&sfinfo
.basic_info
.in
.change_time
, 0);
267 sfinfo
.basic_info
.in
.attrib
= 0;
268 CHECK_CALL_FNUM(BASIC_INFO
, NT_STATUS_OK
);
269 CHECK_TIME(ALL_INFO
, all_info
, create_time
, basetime
+ 100);
270 CHECK_TIME(ALL_INFO
, all_info
, access_time
, basetime
+ 200);
271 CHECK_TIME(ALL_INFO
, all_info
, write_time
, basetime
+ 300);
272 CHECK_TIME(ALL_INFO
, all_info
, change_time
, basetime
+ 400);
273 CHECK_VALUE(ALL_INFO
, all_info
, attrib
, FILE_ATTRIBUTE_READONLY
);
275 printf("Test basic_information level\n");
277 unix_to_nt_time(&sfinfo
.basic_info
.in
.create_time
, basetime
+ 100);
278 unix_to_nt_time(&sfinfo
.basic_info
.in
.access_time
, basetime
+ 200);
279 unix_to_nt_time(&sfinfo
.basic_info
.in
.write_time
, basetime
+ 300);
280 unix_to_nt_time(&sfinfo
.basic_info
.in
.change_time
, basetime
+ 400);
281 sfinfo
.basic_info
.in
.attrib
= FILE_ATTRIBUTE_NORMAL
;
282 CHECK_CALL_FNUM(BASIC_INFORMATION
, NT_STATUS_OK
);
283 CHECK_TIME(ALL_INFO
, all_info
, create_time
, basetime
+ 100);
284 CHECK_TIME(ALL_INFO
, all_info
, access_time
, basetime
+ 200);
285 CHECK_TIME(ALL_INFO
, all_info
, write_time
, basetime
+ 300);
286 CHECK_TIME(ALL_INFO
, all_info
, change_time
, basetime
+ 400);
287 CHECK_VALUE(ALL_INFO
, all_info
, attrib
, FILE_ATTRIBUTE_NORMAL
);
289 CHECK_CALL_PATH(BASIC_INFORMATION
, NT_STATUS_OK
);
290 CHECK_TIME(ALL_INFO
, all_info
, create_time
, basetime
+ 100);
291 CHECK_TIME(ALL_INFO
, all_info
, access_time
, basetime
+ 200);
292 CHECK_TIME(ALL_INFO
, all_info
, write_time
, basetime
+ 300);
293 CHECK_TIME(ALL_INFO
, all_info
, change_time
, basetime
+ 400);
294 CHECK_VALUE(ALL_INFO
, all_info
, attrib
, FILE_ATTRIBUTE_NORMAL
);
296 torture_comment(torture
, "try to change a file to a directory\n");
297 sfinfo
.basic_info
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
298 CHECK_CALL_FNUM(BASIC_INFO
, NT_STATUS_INVALID_PARAMETER
);
300 printf("a zero time means don't change\n");
301 unix_to_nt_time(&sfinfo
.basic_info
.in
.create_time
, 0);
302 unix_to_nt_time(&sfinfo
.basic_info
.in
.access_time
, 0);
303 unix_to_nt_time(&sfinfo
.basic_info
.in
.write_time
, 0);
304 unix_to_nt_time(&sfinfo
.basic_info
.in
.change_time
, 0);
305 sfinfo
.basic_info
.in
.attrib
= FILE_ATTRIBUTE_NORMAL
;
306 CHECK_CALL_FNUM(BASIC_INFORMATION
, NT_STATUS_OK
);
307 CHECK_TIME(ALL_INFO
, all_info
, create_time
, basetime
+ 100);
308 CHECK_TIME(ALL_INFO
, all_info
, access_time
, basetime
+ 200);
309 CHECK_TIME(ALL_INFO
, all_info
, write_time
, basetime
+ 300);
310 CHECK_TIME(ALL_INFO
, all_info
, change_time
, basetime
+ 400);
311 CHECK_VALUE(ALL_INFO
, all_info
, attrib
, FILE_ATTRIBUTE_NORMAL
);
313 CHECK_CALL_PATH(BASIC_INFORMATION
, NT_STATUS_OK
);
314 CHECK_TIME(ALL_INFO
, all_info
, create_time
, basetime
+ 100);
315 CHECK_TIME(ALL_INFO
, all_info
, access_time
, basetime
+ 200);
316 CHECK_TIME(ALL_INFO
, all_info
, write_time
, basetime
+ 300);
318 /* interesting - w2k3 leaves change_time as current time for 0 change time
320 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
322 CHECK_VALUE(ALL_INFO
, all_info
, attrib
, FILE_ATTRIBUTE_NORMAL
);
324 printf("Test disposition_info level\n");
325 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
326 CHECK_CALL_FNUM(DISPOSITION_INFO
, NT_STATUS_OK
);
327 CHECK_VALUE(ALL_INFO
, all_info
, delete_pending
, 1);
328 CHECK_VALUE(ALL_INFO
, all_info
, nlink
, 0);
330 sfinfo
.disposition_info
.in
.delete_on_close
= 0;
331 CHECK_CALL_FNUM(DISPOSITION_INFO
, NT_STATUS_OK
);
332 CHECK_VALUE(ALL_INFO
, all_info
, delete_pending
, 0);
333 CHECK_VALUE(ALL_INFO
, all_info
, nlink
, 1);
335 printf("Test disposition_information level\n");
336 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
337 CHECK_CALL_FNUM(DISPOSITION_INFORMATION
, NT_STATUS_OK
);
338 CHECK_VALUE(ALL_INFO
, all_info
, delete_pending
, 1);
339 CHECK_VALUE(ALL_INFO
, all_info
, nlink
, 0);
341 /* this would delete the file! */
343 CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
344 CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
345 CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
348 sfinfo
.disposition_info
.in
.delete_on_close
= 0;
349 CHECK_CALL_FNUM(DISPOSITION_INFORMATION
, NT_STATUS_OK
);
350 CHECK_VALUE(ALL_INFO
, all_info
, delete_pending
, 0);
351 CHECK_VALUE(ALL_INFO
, all_info
, nlink
, 1);
353 CHECK_CALL_PATH(DISPOSITION_INFORMATION
, NT_STATUS_OK
);
354 CHECK_VALUE(ALL_INFO
, all_info
, delete_pending
, 0);
355 CHECK_VALUE(ALL_INFO
, all_info
, nlink
, 1);
357 printf("Test allocation_info level\n");
358 sfinfo
.allocation_info
.in
.alloc_size
= 0;
359 CHECK_CALL_FNUM(ALLOCATION_INFO
, NT_STATUS_OK
);
360 CHECK_VALUE(ALL_INFO
, all_info
, size
, 0);
361 CHECK_VALUE(ALL_INFO
, all_info
, alloc_size
, 0);
363 sfinfo
.allocation_info
.in
.alloc_size
= 4096;
364 CHECK_CALL_FNUM(ALLOCATION_INFO
, NT_STATUS_OK
);
365 CHECK_VALUE(ALL_INFO
, all_info
, alloc_size
, 4096);
366 CHECK_VALUE(ALL_INFO
, all_info
, size
, 0);
369 sfinfo
.allocation_info
.in
.alloc_size
= 0;
370 CHECK_CALL_FNUM(ALLOCATION_INFORMATION
, NT_STATUS_OK
);
371 CHECK_VALUE(ALL_INFO
, all_info
, size
, 0);
372 CHECK_VALUE(ALL_INFO
, all_info
, alloc_size
, 0);
374 CHECK_CALL_PATH(ALLOCATION_INFORMATION
, NT_STATUS_OK
);
375 CHECK_VALUE(ALL_INFO
, all_info
, size
, 0);
376 CHECK_VALUE(ALL_INFO
, all_info
, alloc_size
, 0);
378 sfinfo
.allocation_info
.in
.alloc_size
= 4096;
379 CHECK_CALL_FNUM(ALLOCATION_INFORMATION
, NT_STATUS_OK
);
380 CHECK_VALUE(ALL_INFO
, all_info
, alloc_size
, 4096);
381 CHECK_VALUE(ALL_INFO
, all_info
, size
, 0);
383 /* setting the allocation size up via setpathinfo seems
384 to be broken in w2k3 */
385 CHECK_CALL_PATH(ALLOCATION_INFORMATION
, NT_STATUS_OK
);
386 CHECK_VALUE(ALL_INFO
, all_info
, alloc_size
, 0);
387 CHECK_VALUE(ALL_INFO
, all_info
, size
, 0);
389 printf("Test end_of_file_info level\n");
390 sfinfo
.end_of_file_info
.in
.size
= 37;
391 CHECK_CALL_FNUM(END_OF_FILE_INFO
, NT_STATUS_OK
);
392 CHECK_VALUE(ALL_INFO
, all_info
, size
, 37);
394 sfinfo
.end_of_file_info
.in
.size
= 7;
395 CHECK_CALL_FNUM(END_OF_FILE_INFO
, NT_STATUS_OK
);
396 CHECK_VALUE(ALL_INFO
, all_info
, size
, 7);
398 sfinfo
.end_of_file_info
.in
.size
= 37;
399 CHECK_CALL_FNUM(END_OF_FILE_INFORMATION
, NT_STATUS_OK
);
400 CHECK_VALUE(ALL_INFO
, all_info
, size
, 37);
402 CHECK_CALL_PATH(END_OF_FILE_INFORMATION
, NT_STATUS_OK
);
403 CHECK_VALUE(ALL_INFO
, all_info
, size
, 37);
405 sfinfo
.end_of_file_info
.in
.size
= 7;
406 CHECK_CALL_FNUM(END_OF_FILE_INFORMATION
, NT_STATUS_OK
);
407 CHECK_VALUE(ALL_INFO
, all_info
, size
, 7);
409 CHECK_CALL_PATH(END_OF_FILE_INFORMATION
, NT_STATUS_OK
);
410 CHECK_VALUE(ALL_INFO
, all_info
, size
, 7);
412 printf("Test position_information level\n");
413 sfinfo
.position_information
.in
.position
= 123456;
414 CHECK_CALL_FNUM(POSITION_INFORMATION
, NT_STATUS_OK
);
415 CHECK_VALUE(POSITION_INFORMATION
, position_information
, position
, 123456);
417 CHECK_CALL_PATH(POSITION_INFORMATION
, NT_STATUS_OK
);
418 CHECK_VALUE(POSITION_INFORMATION
, position_information
, position
, 0);
420 printf("Test mode_information level\n");
421 sfinfo
.mode_information
.in
.mode
= 2;
422 CHECK_CALL_FNUM(MODE_INFORMATION
, NT_STATUS_OK
);
423 CHECK_VALUE(MODE_INFORMATION
, mode_information
, mode
, 2);
425 CHECK_CALL_PATH(MODE_INFORMATION
, NT_STATUS_OK
);
426 CHECK_VALUE(MODE_INFORMATION
, mode_information
, mode
, 0);
428 sfinfo
.mode_information
.in
.mode
= 1;
429 CHECK_CALL_FNUM(MODE_INFORMATION
, NT_STATUS_INVALID_PARAMETER
);
430 CHECK_CALL_PATH(MODE_INFORMATION
, NT_STATUS_INVALID_PARAMETER
);
432 sfinfo
.mode_information
.in
.mode
= 0;
433 CHECK_CALL_FNUM(MODE_INFORMATION
, NT_STATUS_OK
);
434 CHECK_VALUE(MODE_INFORMATION
, mode_information
, mode
, 0);
436 CHECK_CALL_PATH(MODE_INFORMATION
, NT_STATUS_OK
);
437 CHECK_VALUE(MODE_INFORMATION
, mode_information
, mode
, 0);
440 printf("Test unix_basic level\n");
441 CHECK_CALL_FNUM(UNIX_BASIC
, NT_STATUS_OK
);
442 CHECK_CALL_PATH(UNIX_BASIC
, NT_STATUS_OK
);
444 printf("Test unix_link level\n");
445 CHECK_CALL_FNUM(UNIX_LINK
, NT_STATUS_OK
);
446 CHECK_CALL_PATH(UNIX_LINK
, NT_STATUS_OK
);
450 smb_raw_exit(cli
->session
);
451 smbcli_close(cli
->tree
, fnum
);
452 if (NT_STATUS_IS_ERR(smbcli_unlink(cli
->tree
, fnum_fname
))) {
453 printf("Failed to delete %s - %s\n", fnum_fname
, smbcli_errstr(cli
->tree
));
455 if (NT_STATUS_IS_ERR(smbcli_unlink(cli
->tree
, path_fname
))) {
456 printf("Failed to delete %s - %s\n", path_fname
, smbcli_errstr(cli
->tree
));
463 * basic testing of all RAW_SFILEINFO_RENAME call
466 torture_raw_sfileinfo_rename(struct torture_context
*torture
,
467 struct smbcli_state
*cli
)
470 int fnum_saved
, d_fnum
, fnum2
, fnum
= -1;
472 char *fnum_fname_new
;
474 char *path_fname_new
;
476 char *path_dname_new
;
478 char *saved_name_new
;
479 union smb_fileinfo finfo1
, finfo2
;
480 union smb_setfileinfo sfinfo
;
481 NTSTATUS status
, status2
;
482 const char *call_name
;
484 int n
= time(NULL
) % 100;
486 asprintf(&path_fname
, BASEDIR
"\\fname_test_%d.txt", n
);
487 asprintf(&path_fname_new
, BASEDIR
"\\fname_test_new_%d.txt", n
);
488 asprintf(&fnum_fname
, BASEDIR
"\\fnum_test_%d.txt", n
);
489 asprintf(&fnum_fname_new
, BASEDIR
"\\fnum_test_new_%d.txt", n
);
490 asprintf(&path_dname
, BASEDIR
"\\dname_test_%d", n
);
491 asprintf(&path_dname_new
, BASEDIR
"\\dname_test_new_%d", n
);
493 if (!torture_setup_dir(cli
, BASEDIR
)) {
501 smbcli_close(cli
->tree
, create_complex_file(cli
, torture
, fnum_fname_new
));
502 smbcli_close(cli
->tree
, create_complex_file(cli
, torture
, path_fname_new
));
504 sfinfo
.rename_information
.in
.overwrite
= 0;
505 sfinfo
.rename_information
.in
.root_fid
= 0;
506 sfinfo
.rename_information
.in
.new_name
= fnum_fname_new
+strlen(BASEDIR
)+1;
507 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_OBJECT_NAME_COLLISION
);
509 sfinfo
.rename_information
.in
.new_name
= path_fname_new
+strlen(BASEDIR
)+1;
510 CHECK_CALL_PATH(RENAME_INFORMATION
, NT_STATUS_OBJECT_NAME_COLLISION
);
512 sfinfo
.rename_information
.in
.new_name
= fnum_fname_new
;
513 sfinfo
.rename_information
.in
.overwrite
= 1;
514 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_NOT_SUPPORTED
);
516 sfinfo
.rename_information
.in
.new_name
= fnum_fname_new
+strlen(BASEDIR
)+1;
517 sfinfo
.rename_information
.in
.overwrite
= 1;
518 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_OK
);
519 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, fnum_fname_new
);
521 printf("Trying rename with dest file open\n");
522 fnum2
= create_complex_file(cli
, torture
, fnum_fname
);
523 sfinfo
.rename_information
.in
.new_name
= fnum_fname
+strlen(BASEDIR
)+1;
524 sfinfo
.rename_information
.in
.overwrite
= 1;
525 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_ACCESS_DENIED
);
526 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, fnum_fname_new
);
530 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
531 CHECK_CALL_FNUM(DISPOSITION_INFO
, NT_STATUS_OK
);
534 printf("Trying rename with dest file open and delete_on_close\n");
535 sfinfo
.rename_information
.in
.new_name
= fnum_fname
+strlen(BASEDIR
)+1;
536 sfinfo
.rename_information
.in
.overwrite
= 1;
537 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_ACCESS_DENIED
);
539 smbcli_close(cli
->tree
, fnum2
);
540 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_OK
);
541 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, fnum_fname
);
543 printf("Trying rename with source file open twice\n");
544 sfinfo
.rename_information
.in
.new_name
= fnum_fname
+strlen(BASEDIR
)+1;
545 sfinfo
.rename_information
.in
.overwrite
= 1;
546 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_OK
);
547 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, fnum_fname
);
549 fnum2
= create_complex_file(cli
, torture
, fnum_fname
);
550 sfinfo
.rename_information
.in
.new_name
= fnum_fname_new
+strlen(BASEDIR
)+1;
551 sfinfo
.rename_information
.in
.overwrite
= 0;
552 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_OK
);
553 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, fnum_fname_new
);
554 smbcli_close(cli
->tree
, fnum2
);
556 sfinfo
.rename_information
.in
.new_name
= fnum_fname
+strlen(BASEDIR
)+1;
557 sfinfo
.rename_information
.in
.overwrite
= 0;
558 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_OK
);
559 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, fnum_fname
);
561 sfinfo
.rename_information
.in
.new_name
= path_fname_new
+strlen(BASEDIR
)+1;
562 sfinfo
.rename_information
.in
.overwrite
= 1;
563 CHECK_CALL_PATH(RENAME_INFORMATION
, NT_STATUS_OK
);
564 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_fname_new
);
566 sfinfo
.rename_information
.in
.new_name
= fnum_fname
+strlen(BASEDIR
)+1;
567 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_OK
);
568 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, fnum_fname
);
570 sfinfo
.rename_information
.in
.new_name
= path_fname
+strlen(BASEDIR
)+1;
571 CHECK_CALL_PATH(RENAME_INFORMATION
, NT_STATUS_OK
);
572 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_fname
);
574 printf("Trying rename with a root fid\n");
575 status
= create_directory_handle(cli
->tree
, BASEDIR
, &d_fnum
);
576 CHECK_STATUS(status
, NT_STATUS_OK
);
577 sfinfo
.rename_information
.in
.new_name
= fnum_fname_new
+strlen(BASEDIR
)+1;
578 sfinfo
.rename_information
.in
.root_fid
= d_fnum
;
579 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_INVALID_PARAMETER
);
580 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, fnum_fname
);
581 smbcli_close(cli
->tree
, d_fnum
);
583 printf("Trying rename directory\n");
584 if (!torture_setup_dir(cli
, path_dname
)) {
588 saved_name
= path_fname
;
589 saved_name_new
= path_fname_new
;
590 path_fname
= path_dname
;
591 path_fname_new
= path_dname_new
;
592 sfinfo
.rename_information
.in
.new_name
= path_dname_new
+strlen(BASEDIR
)+1;
593 sfinfo
.rename_information
.in
.overwrite
= 0;
594 sfinfo
.rename_information
.in
.root_fid
= 0;
595 CHECK_CALL_PATH(RENAME_INFORMATION
, NT_STATUS_OK
);
596 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_dname_new
);
597 path_fname
= saved_name
;
598 path_fname_new
= saved_name_new
;
600 if (torture_setting_bool(torture
, "samba3", false)) {
601 printf("SKIP: Trying rename directory with a handle\n");
602 printf("SKIP: Trying rename by path while a handle is open\n");
603 printf("SKIP: Trying rename directory by path while a handle is open\n");
607 printf("Trying rename directory with a handle\n");
608 status
= create_directory_handle(cli
->tree
, path_dname_new
, &d_fnum
);
611 saved_name
= fnum_fname
;
612 saved_name_new
= fnum_fname_new
;
613 fnum_fname
= path_dname
;
614 fnum_fname_new
= path_dname_new
;
615 sfinfo
.rename_information
.in
.new_name
= path_dname
+strlen(BASEDIR
)+1;
616 sfinfo
.rename_information
.in
.overwrite
= 0;
617 sfinfo
.rename_information
.in
.root_fid
= 0;
618 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_OK
);
619 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_dname
);
620 smbcli_close(cli
->tree
, d_fnum
);
622 fnum_fname
= saved_name
;
623 fnum_fname_new
= saved_name_new
;
625 printf("Trying rename by path while a handle is open\n");
627 fnum
= create_complex_file(cli
, torture
, path_fname
);
628 sfinfo
.rename_information
.in
.new_name
= path_fname_new
+strlen(BASEDIR
)+1;
629 sfinfo
.rename_information
.in
.overwrite
= 0;
630 sfinfo
.rename_information
.in
.root_fid
= 0;
631 CHECK_CALL_PATH(RENAME_INFORMATION
, NT_STATUS_OK
);
632 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_fname_new
);
633 /* check that the handle returns the same name */
635 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_fname_new
);
636 /* rename it back on the handle */
637 sfinfo
.rename_information
.in
.new_name
= path_fname
+strlen(BASEDIR
)+1;
638 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_OK
);
639 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_fname
);
641 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_fname
);
642 smbcli_close(cli
->tree
, fnum
);
645 printf("Trying rename directory by path while a handle is open\n");
646 status
= create_directory_handle(cli
->tree
, path_dname
, &d_fnum
);
649 saved_name
= path_fname
;
650 saved_name_new
= path_fname_new
;
651 path_fname
= path_dname
;
652 path_fname_new
= path_dname_new
;
653 sfinfo
.rename_information
.in
.new_name
= path_dname_new
+strlen(BASEDIR
)+1;
654 sfinfo
.rename_information
.in
.overwrite
= 0;
655 sfinfo
.rename_information
.in
.root_fid
= 0;
656 CHECK_CALL_PATH(RENAME_INFORMATION
, NT_STATUS_OK
);
657 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_dname_new
);
658 path_fname
= saved_name
;
659 path_fname_new
= saved_name_new
;
660 saved_name
= fnum_fname
;
661 saved_name_new
= fnum_fname_new
;
662 fnum_fname
= path_dname
;
663 fnum_fname_new
= path_dname_new
;
664 /* check that the handle returns the same name */
666 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_dname_new
);
667 /* rename it back on the handle */
668 sfinfo
.rename_information
.in
.new_name
= path_dname
+strlen(BASEDIR
)+1;
669 CHECK_CALL_FNUM(RENAME_INFORMATION
, NT_STATUS_OK
);
670 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_dname
);
671 fnum_fname
= saved_name
;
672 fnum_fname_new
= saved_name_new
;
673 saved_name
= path_fname
;
674 saved_name_new
= path_fname_new
;
675 path_fname
= path_dname
;
676 path_fname_new
= path_dname_new
;
678 CHECK_STR(NAME_INFO
, name_info
, fname
.s
, path_dname
);
679 smbcli_close(cli
->tree
, d_fnum
);
681 path_fname
= saved_name
;
682 path_fname_new
= saved_name_new
;
685 smb_raw_exit(cli
->session
);
686 smbcli_deltree(cli
->tree
, BASEDIR
);
691 look for the w2k3 setpathinfo STANDARD bug
693 static bool torture_raw_sfileinfo_bug(struct torture_context
*torture
,
694 struct smbcli_state
*cli
)
696 const char *fname
= "\\bug3.txt";
697 union smb_setfileinfo sfinfo
;
701 if (!torture_setting_bool(torture
, "dangerous", false))
702 torture_skip(torture
,
703 "torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n");
705 fnum
= create_complex_file(cli
, torture
, fname
);
706 smbcli_close(cli
->tree
, fnum
);
708 sfinfo
.generic
.level
= RAW_SFILEINFO_STANDARD
;
709 sfinfo
.generic
.in
.file
.path
= fname
;
711 sfinfo
.standard
.in
.create_time
= 0;
712 sfinfo
.standard
.in
.access_time
= 0;
713 sfinfo
.standard
.in
.write_time
= 0;
715 status
= smb_raw_setpathinfo(cli
->tree
, &sfinfo
);
716 printf("%s - %s\n", fname
, nt_errstr(status
));
718 printf("now try and delete %s\n", fname
);
724 * Test both the snia cifs RAW_SFILEINFO_END_OF_FILE_INFO and the undocumented
725 * pass-through RAW_SFILEINFO_END_OF_FILE_INFORMATION in the context of
729 torture_raw_sfileinfo_eof(struct torture_context
*tctx
,
730 struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
732 const char *fname
= BASEDIR
"\\test_sfileinfo_end_of_file.dat";
736 union smb_setfileinfo sfi
;
737 union smb_fileinfo qfi
;
740 if (!torture_setup_dir(cli1
, BASEDIR
)) {
745 smbcli_unlink(cli1
->tree
, fname
);
747 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
748 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
749 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
750 io
.ntcreatex
.in
.alloc_size
= 0;
751 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
752 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
753 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
754 io
.ntcreatex
.in
.create_options
= 0;
755 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
756 io
.ntcreatex
.in
.security_flags
= 0;
757 io
.ntcreatex
.in
.fname
= fname
;
758 io
.ntcreatex
.in
.flags
= 0;
760 /* Open the file sharing none. */
761 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
762 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
, ret
,
763 done
, "Status should be OK");
764 fnum
= io
.ntcreatex
.out
.file
.fnum
;
766 /* Try to sfileinfo to extend the file. */
768 sfi
.generic
.level
= RAW_SFILEINFO_END_OF_FILE_INFO
;
769 sfi
.generic
.in
.file
.path
= fname
;
770 sfi
.end_of_file_info
.in
.size
= 100;
771 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
773 /* There should be share mode contention in this case. */
774 torture_assert_ntstatus_equal_goto(tctx
, status
,
775 NT_STATUS_SHARING_VIOLATION
, ret
, done
, "Status should be "
776 "SHARING_VIOLATION");
778 /* Make sure the size is still 0. */
780 qfi
.generic
.level
= RAW_FILEINFO_STANDARD_INFO
;
781 qfi
.generic
.in
.file
.path
= fname
;
782 status
= smb_raw_pathinfo(cli2
->tree
, tctx
, &qfi
);
783 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
, ret
,
784 done
, "Status should be OK");
786 torture_assert_u64_equal(tctx
, qfi
.standard_info
.out
.size
, 0,
787 "alloc_size should be 0 since the setpathinfo failed.");
789 /* Try again with the pass through instead of documented version. */
791 sfi
.generic
.level
= RAW_SFILEINFO_END_OF_FILE_INFORMATION
;
792 sfi
.generic
.in
.file
.path
= fname
;
793 sfi
.end_of_file_info
.in
.size
= 100;
794 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
797 * Looks like a windows bug:
798 * http://lists.samba.org/archive/cifs-protocol/2009-November/001130.html
800 if (TARGET_IS_W2K8(tctx
) || TARGET_IS_WIN7(tctx
)) {
801 /* It succeeds! This is just weird! */
802 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
803 ret
, done
, "Status should be OK");
805 /* Verify that the file was actually extended to 100. */
807 qfi
.generic
.level
= RAW_FILEINFO_STANDARD_INFO
;
808 qfi
.generic
.in
.file
.path
= fname
;
809 status
= smb_raw_pathinfo(cli2
->tree
, tctx
, &qfi
);
810 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
811 ret
, done
, "Status should be OK");
813 torture_assert_u64_equal(tctx
, qfi
.standard_info
.out
.size
, 100,
814 "alloc_size should be 100 since the setpathinfo "
817 torture_assert_ntstatus_equal_goto(tctx
, status
,
818 NT_STATUS_SHARING_VIOLATION
, ret
, done
, "Status should be "
819 "SHARING_VIOLATION");
822 /* close the first file. */
823 smbcli_close(cli1
->tree
, fnum
);
826 /* Try to sfileinfo to extend the file again (non-pass-through). */
828 sfi
.generic
.level
= RAW_SFILEINFO_END_OF_FILE_INFO
;
829 sfi
.generic
.in
.file
.path
= fname
;
830 sfi
.end_of_file_info
.in
.size
= 200;
831 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
833 /* This should cause the client to retun invalid level. */
834 if (TARGET_IS_W2K8(tctx
) || TARGET_IS_WIN7(tctx
)) {
836 * Windows sends back an invalid packet that smbclient sees
837 * and returns INTERNAL_ERROR.
839 torture_assert_ntstatus_equal_goto(tctx
, status
,
840 NT_STATUS_INTERNAL_ERROR
, ret
, done
, "Status should be "
843 torture_assert_ntstatus_equal_goto(tctx
, status
,
844 NT_STATUS_INVALID_LEVEL
, ret
, done
, "Status should be "
848 /* Try to extend the file now with the passthrough level. */
849 sfi
.generic
.level
= RAW_SFILEINFO_END_OF_FILE_INFORMATION
;
850 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
851 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
, ret
,
852 done
, "Status should be OK");
854 /* Verify that the file was actually extended to 200. */
856 qfi
.generic
.level
= RAW_FILEINFO_STANDARD_INFO
;
857 qfi
.generic
.in
.file
.path
= fname
;
858 status
= smb_raw_pathinfo(cli2
->tree
, tctx
, &qfi
);
860 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
, ret
,
861 done
, "Status should be OK");
862 torture_assert_u64_equal(tctx
, qfi
.standard_info
.out
.size
, 200,
863 "alloc_size should be 200 since the setpathinfo succeeded.");
865 /* Open the file so end of file can be set by handle. */
866 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_WRITE
;
867 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
868 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
, ret
,
869 done
, "Status should be OK");
870 fnum
= io
.ntcreatex
.out
.file
.fnum
;
872 /* Try sfileinfo to extend the file by handle (non-pass-through). */
874 sfi
.generic
.level
= RAW_SFILEINFO_END_OF_FILE_INFO
;
875 sfi
.generic
.in
.file
.fnum
= fnum
;
876 sfi
.end_of_file_info
.in
.size
= 300;
877 status
= smb_raw_setfileinfo(cli1
->tree
, &sfi
);
878 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
, ret
,
879 done
, "Status should be OK");
881 /* Verify that the file was actually extended to 300. */
883 qfi
.generic
.level
= RAW_FILEINFO_STANDARD_INFO
;
884 qfi
.generic
.in
.file
.path
= fname
;
885 status
= smb_raw_pathinfo(cli1
->tree
, tctx
, &qfi
);
886 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
, ret
,
887 done
, "Status should be OK");
888 torture_assert_u64_equal(tctx
, qfi
.standard_info
.out
.size
, 300,
889 "alloc_size should be 300 since the setpathinfo succeeded.");
891 /* Try sfileinfo to extend the file by handle (pass-through). */
893 sfi
.generic
.level
= RAW_SFILEINFO_END_OF_FILE_INFORMATION
;
894 sfi
.generic
.in
.file
.fnum
= fnum
;
895 sfi
.end_of_file_info
.in
.size
= 400;
896 status
= smb_raw_setfileinfo(cli1
->tree
, &sfi
);
897 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
, ret
,
898 done
, "Status should be OK");
900 /* Verify that the file was actually extended to 300. */
902 qfi
.generic
.level
= RAW_FILEINFO_STANDARD_INFO
;
903 qfi
.generic
.in
.file
.path
= fname
;
904 status
= smb_raw_pathinfo(cli1
->tree
, tctx
, &qfi
);
905 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
, ret
,
906 done
, "Status should be OK");
907 torture_assert_u64_equal(tctx
, qfi
.standard_info
.out
.size
, 400,
908 "alloc_size should be 400 since the setpathinfo succeeded.");
911 smbcli_close(cli1
->tree
, fnum
);
915 smb_raw_exit(cli1
->session
);
916 smb_raw_exit(cli2
->session
);
917 smbcli_deltree(cli1
->tree
, BASEDIR
);
922 torture_raw_sfileinfo_eof_access(struct torture_context
*tctx
,
923 struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
925 const char *fname
= BASEDIR
"\\test_exclusive3.dat";
926 NTSTATUS status
, expected_status
;
929 union smb_setfileinfo sfi
;
931 uint32_t access_mask
= 0;
933 if (!torture_setup_dir(cli1
, BASEDIR
)) {
938 smbcli_unlink(cli1
->tree
, fname
);
941 * base ntcreatex parms
943 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
944 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
945 io
.ntcreatex
.in
.alloc_size
= 0;
946 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
947 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
948 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OVERWRITE_IF
;
949 io
.ntcreatex
.in
.create_options
= 0;
950 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
951 io
.ntcreatex
.in
.security_flags
= 0;
952 io
.ntcreatex
.in
.fname
= fname
;
953 io
.ntcreatex
.in
.flags
= 0;
956 for (access_mask
= 1; access_mask
<= 0x00001FF; access_mask
++) {
957 io
.ntcreatex
.in
.access_mask
= access_mask
;
959 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
960 if (!NT_STATUS_IS_OK(status
)) {
964 fnum
= io
.ntcreatex
.out
.file
.fnum
;
967 sfi
.generic
.level
= RAW_SFILEINFO_END_OF_FILE_INFO
;
968 sfi
.generic
.in
.file
.fnum
= fnum
;
969 sfi
.end_of_file_info
.in
.size
= 100;
971 status
= smb_raw_setfileinfo(cli1
->tree
, &sfi
);
973 expected_status
= (access_mask
& SEC_FILE_WRITE_DATA
) ?
974 NT_STATUS_OK
: NT_STATUS_ACCESS_DENIED
;
976 if (!NT_STATUS_EQUAL(expected_status
, status
)) {
977 torture_comment(tctx
, "0x%x wrong\n", access_mask
);
980 torture_assert_ntstatus_equal_goto(tctx
, status
,
981 expected_status
, ret
, done
, "Status Wrong");
983 smbcli_close(cli1
->tree
, fnum
);
987 smb_raw_exit(cli1
->session
);
988 smb_raw_exit(cli2
->session
);
989 smbcli_deltree(cli1
->tree
, BASEDIR
);
994 torture_raw_sfileinfo_archive(struct torture_context
*tctx
,
995 struct smbcli_state
*cli
)
997 const char *fname
= BASEDIR
"\\test_archive.dat";
1001 union smb_setfileinfo sfinfo
;
1002 union smb_fileinfo finfo
;
1005 if (!torture_setup_dir(cli
, BASEDIR
)) {
1010 smbcli_unlink(cli
->tree
, fname
);
1013 * create a normal file, verify archive bit
1015 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1016 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1017 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1018 io
.ntcreatex
.in
.alloc_size
= 0;
1019 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1020 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1021 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1022 io
.ntcreatex
.in
.create_options
= 0;
1023 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1024 io
.ntcreatex
.in
.security_flags
= 0;
1025 io
.ntcreatex
.in
.fname
= fname
;
1026 io
.ntcreatex
.in
.flags
= 0;
1027 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1028 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
1029 ret
, done
, "open failed");
1030 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1032 torture_assert_int_equal(tctx
,
1033 io
.ntcreatex
.out
.attrib
& ~FILE_ATTRIBUTE_NONINDEXED
,
1034 FILE_ATTRIBUTE_ARCHIVE
,
1035 "archive bit not set");
1038 * try to turn off archive bit
1040 ZERO_STRUCT(sfinfo
);
1041 sfinfo
.generic
.level
= RAW_SFILEINFO_BASIC_INFO
;
1042 sfinfo
.generic
.in
.file
.fnum
= fnum
;
1043 sfinfo
.basic_info
.in
.attrib
= FILE_ATTRIBUTE_NORMAL
;
1044 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
1045 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
1046 ret
, done
, "setfileinfo failed");
1048 finfo
.generic
.level
= RAW_FILEINFO_ALL_INFO
;
1049 finfo
.generic
.in
.file
.fnum
= fnum
;
1050 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &finfo
);
1051 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
1052 ret
, done
, "fileinfo failed");
1054 torture_assert_int_equal(tctx
,
1055 finfo
.all_info
.out
.attrib
& ~FILE_ATTRIBUTE_NONINDEXED
,
1056 FILE_ATTRIBUTE_NORMAL
,
1059 status
= smbcli_close(cli
->tree
, fnum
);
1060 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
1061 ret
, done
, "close failed");
1063 status
= smbcli_unlink(cli
->tree
, fname
);
1064 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
1065 ret
, done
, "unlink failed");
1068 * create a directory, verify no archive bit
1070 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1071 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1072 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_DIR_ALL
;
1073 io
.ntcreatex
.in
.alloc_size
= 0;
1074 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_DIRECTORY
;
1075 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1076 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1077 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
1078 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1079 io
.ntcreatex
.in
.security_flags
= 0;
1080 io
.ntcreatex
.in
.fname
= fname
;
1081 io
.ntcreatex
.in
.flags
= 0;
1082 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1083 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
1084 ret
, done
, "directory open failed");
1085 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1087 torture_assert_int_equal(tctx
,
1088 io
.ntcreatex
.out
.attrib
& ~FILE_ATTRIBUTE_NONINDEXED
,
1089 FILE_ATTRIBUTE_DIRECTORY
,
1093 * verify you can turn on archive bit
1095 sfinfo
.generic
.level
= RAW_SFILEINFO_BASIC_INFO
;
1096 sfinfo
.generic
.in
.file
.fnum
= fnum
;
1097 sfinfo
.basic_info
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
|FILE_ATTRIBUTE_ARCHIVE
;
1098 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
1099 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
1100 ret
, done
, "setfileinfo failed");
1102 finfo
.generic
.level
= RAW_FILEINFO_ALL_INFO
;
1103 finfo
.generic
.in
.file
.fnum
= fnum
;
1104 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &finfo
);
1105 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
1106 ret
, done
, "fileinfo failed");
1108 torture_assert_int_equal(tctx
,
1109 finfo
.all_info
.out
.attrib
& ~FILE_ATTRIBUTE_NONINDEXED
,
1110 FILE_ATTRIBUTE_DIRECTORY
|FILE_ATTRIBUTE_ARCHIVE
,
1111 "archive bit not set");
1114 * and try to turn it back off
1116 sfinfo
.generic
.level
= RAW_SFILEINFO_BASIC_INFO
;
1117 sfinfo
.generic
.in
.file
.fnum
= fnum
;
1118 sfinfo
.basic_info
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
1119 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
1120 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
1121 ret
, done
, "setfileinfo failed");
1123 finfo
.generic
.level
= RAW_FILEINFO_ALL_INFO
;
1124 finfo
.generic
.in
.file
.fnum
= fnum
;
1125 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &finfo
);
1126 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
1127 ret
, done
, "fileinfo failed");
1129 torture_assert_int_equal(tctx
,
1130 finfo
.all_info
.out
.attrib
& ~FILE_ATTRIBUTE_NONINDEXED
,
1131 FILE_ATTRIBUTE_DIRECTORY
,
1134 status
= smbcli_close(cli
->tree
, fnum
);
1135 torture_assert_ntstatus_equal_goto(tctx
, status
, NT_STATUS_OK
,
1136 ret
, done
, "close failed");
1139 smbcli_close(cli
->tree
, fnum
);
1140 smbcli_deltree(cli
->tree
, BASEDIR
);
1144 struct torture_suite
*torture_raw_sfileinfo(TALLOC_CTX
*mem_ctx
)
1146 struct torture_suite
*suite
= torture_suite_create(mem_ctx
,
1149 torture_suite_add_1smb_test(suite
, "BASE", torture_raw_sfileinfo_base
);
1150 torture_suite_add_1smb_test(suite
, "RENAME",
1151 torture_raw_sfileinfo_rename
);
1152 torture_suite_add_1smb_test(suite
, "BUG", torture_raw_sfileinfo_bug
);
1153 torture_suite_add_2smb_test(suite
, "END-OF-FILE",
1154 torture_raw_sfileinfo_eof
);
1155 torture_suite_add_2smb_test(suite
, "END-OF-FILE-ACCESS",
1156 torture_raw_sfileinfo_eof_access
);
1157 torture_suite_add_1smb_test(suite
, "ARCHIVE", torture_raw_sfileinfo_archive
);