source: trunk/server/source4/torture/raw/setfileinfo.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 42.5 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 RAW_SFILEINFO_* individual test suite
4 Copyright (C) Andrew Tridgell 2003
5
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.
10
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.
15
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/>.
18*/
19
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
26#define BASEDIR "\\testsfileinfo"
27
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.
31*/
32static bool
33torture_raw_sfileinfo_base(struct torture_context *torture, struct smbcli_state *cli)
34{
35 bool ret = true;
36 int fnum = -1;
37 char *fnum_fname;
38 char *fnum_fname_new;
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;
48
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);
53
54 if (!torture_setup_dir(cli, BASEDIR)) {
55 return false;
56 }
57
58#define RECREATE_FILE(fname) do { \
59 if (fnum != -1) smbcli_close(cli->tree, fnum); \
60 fnum = create_complex_file(cli, torture, fname); \
61 if (fnum == -1) { \
62 printf("(%s) ERROR: open of %s failed (%s)\n", \
63 __location__, fname, smbcli_errstr(cli->tree)); \
64 ret = false; \
65 goto done; \
66 }} while (0)
67
68#define RECREATE_BOTH do { \
69 RECREATE_FILE(path_fname); \
70 smbcli_close(cli->tree, fnum); \
71 RECREATE_FILE(fnum_fname); \
72 } while (0)
73
74 RECREATE_BOTH;
75
76#define CHECK_CALL_FNUM(call, rightstatus) do { \
77 check_fnum = true; \
78 call_name = #call; \
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, \
85 nt_errstr(status)); \
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)); \
89 ret = false; \
90 } \
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, \
97 nt_errstr(status)); \
98 } else if (!NT_STATUS_IS_OK(status2)) { \
99 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status)); \
100 ret = false; \
101 }} while (0)
102
103#define CHECK_CALL_PATH(call, rightstatus) do { \
104 check_fnum = false; \
105 call_name = #call; \
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); \
112 } \
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)); \
120 ret = false; \
121 } \
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); \
128 } \
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)); \
135 ret = false; \
136 }} while (0)
137
138#define CHECK1(call) \
139 do { if (NT_STATUS_IS_OK(status)) { \
140 finfo2.generic.level = RAW_FILEINFO_ ## call; \
141 if (check_fnum) { \
142 finfo2.generic.in.file.fnum = fnum; \
143 status2 = smb_raw_fileinfo(cli->tree, torture, &finfo2); \
144 } else { \
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); \
150 } \
151 } \
152 if (!NT_STATUS_IS_OK(status2)) { \
153 printf("%s - %s\n", #call, nt_errstr(status2)); \
154 ret = false; \
155 } \
156 }} while (0)
157
158#define CHECK_VALUE(call, stype, field, value) do { \
159 CHECK1(call); \
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); \
165 ret = false; \
166 }} while (0)
167
168#define CHECK_TIME(call, stype, field, value) do { \
169 CHECK1(call); \
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); \
178 ret = false; \
179 }} while (0)
180
181#define CHECK_STR(call, stype, field, value) do { \
182 CHECK1(call); \
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, \
186 value, \
187 finfo2.stype.out.field); \
188 dump_all_info(torture, &finfo1); \
189 ret = false; \
190 }} while (0)
191
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)); \
196 ret = false; \
197 goto done; \
198 }} while (0)
199
200
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);
207
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);
214
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);
221
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);
230
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);
238
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);
247
248 printf("Test basic_info level\n");
249 basetime += 86400;
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);
261
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);
274
275 printf("Test basic_information level\n");
276 basetime += 86400;
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);
288
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);
295
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);
299
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);
312
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);
317
318 /* interesting - w2k3 leaves change_time as current time for 0 change time
319 in setpathinfo
320 CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
321 */
322 CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
323
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);
329
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);
334
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);
340
341 /* this would delete the file! */
342 /*
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);
346 */
347
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);
352
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);
356
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);
362
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);
367
368 RECREATE_BOTH;
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);
373
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);
377
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);
382
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);
388
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);
393
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);
397
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);
401
402 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
403 CHECK_VALUE(ALL_INFO, all_info, size, 37);
404
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);
408
409 CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
410 CHECK_VALUE(ALL_INFO, all_info, size, 7);
411
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);
416
417 CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
418 CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);
419
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);
424
425 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
426 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
427
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);
431
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);
435
436 CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
437 CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
438
439#if 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);
443
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);
447#endif
448
449done:
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));
454 }
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));
457 }
458
459 return ret;
460}
461
462/*
463 * basic testing of all RAW_SFILEINFO_RENAME call
464 */
465static bool
466torture_raw_sfileinfo_rename(struct torture_context *torture,
467 struct smbcli_state *cli)
468{
469 bool ret = true;
470 int fnum_saved, d_fnum, fnum2, fnum = -1;
471 char *fnum_fname;
472 char *fnum_fname_new;
473 char *path_fname;
474 char *path_fname_new;
475 char *path_dname;
476 char *path_dname_new;
477 char *saved_name;
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;
483 bool check_fnum;
484 int n = time(NULL) % 100;
485
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);
492
493 if (!torture_setup_dir(cli, BASEDIR)) {
494 return false;
495 }
496
497 RECREATE_BOTH;
498
499 ZERO_STRUCT(sfinfo);
500
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));
503
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);
508
509 sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
510 CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
511
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);
515
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);
520
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);
527
528 fnum_saved = fnum;
529 fnum = fnum2;
530 sfinfo.disposition_info.in.delete_on_close = 1;
531 CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
532 fnum = fnum_saved;
533
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);
538
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);
542
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);
548
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);
555
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);
560
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);
565
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);
569
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);
573
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);
582
583 printf("Trying rename directory\n");
584 if (!torture_setup_dir(cli, path_dname)) {
585 ret = false;
586 goto done;
587 }
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;
599
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");
604 goto done;
605 }
606
607 printf("Trying rename directory with a handle\n");
608 status = create_directory_handle(cli->tree, path_dname_new, &d_fnum);
609 fnum_saved = fnum;
610 fnum = 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);
621 fnum = fnum_saved;
622 fnum_fname = saved_name;
623 fnum_fname_new = saved_name_new;
624
625 printf("Trying rename by path while a handle is open\n");
626 fnum_saved = fnum;
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 */
634 check_fnum = true;
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);
640 check_fnum = false;
641 CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
642 smbcli_close(cli->tree, fnum);
643 fnum = fnum_saved;
644
645 printf("Trying rename directory by path while a handle is open\n");
646 status = create_directory_handle(cli->tree, path_dname, &d_fnum);
647 fnum_saved = fnum;
648 fnum = 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 */
665 check_fnum = true;
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;
677 check_fnum = false;
678 CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
679 smbcli_close(cli->tree, d_fnum);
680 fnum = fnum_saved;
681 path_fname = saved_name;
682 path_fname_new = saved_name_new;
683
684done:
685 smb_raw_exit(cli->session);
686 smbcli_deltree(cli->tree, BASEDIR);
687 return ret;
688}
689
690/*
691 look for the w2k3 setpathinfo STANDARD bug
692*/
693static bool torture_raw_sfileinfo_bug(struct torture_context *torture,
694 struct smbcli_state *cli)
695{
696 const char *fname = "\\bug3.txt";
697 union smb_setfileinfo sfinfo;
698 NTSTATUS status;
699 int fnum;
700
701 if (!torture_setting_bool(torture, "dangerous", false))
702 torture_skip(torture,
703 "torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n");
704
705 fnum = create_complex_file(cli, torture, fname);
706 smbcli_close(cli->tree, fnum);
707
708 sfinfo.generic.level = RAW_SFILEINFO_STANDARD;
709 sfinfo.generic.in.file.path = fname;
710
711 sfinfo.standard.in.create_time = 0;
712 sfinfo.standard.in.access_time = 0;
713 sfinfo.standard.in.write_time = 0;
714
715 status = smb_raw_setpathinfo(cli->tree, &sfinfo);
716 printf("%s - %s\n", fname, nt_errstr(status));
717
718 printf("now try and delete %s\n", fname);
719
720 return true;
721}
722
723/**
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
726 * trans2setpathinfo.
727 */
728static bool
729torture_raw_sfileinfo_eof(struct torture_context *tctx,
730 struct smbcli_state *cli1, struct smbcli_state *cli2)
731{
732 const char *fname = BASEDIR "\\test_sfileinfo_end_of_file.dat";
733 NTSTATUS status;
734 bool ret = true;
735 union smb_open io;
736 union smb_setfileinfo sfi;
737 union smb_fileinfo qfi;
738 uint16_t fnum = 0;
739
740 if (!torture_setup_dir(cli1, BASEDIR)) {
741 return false;
742 }
743
744 /* cleanup */
745 smbcli_unlink(cli1->tree, fname);
746
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;
759
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;
765
766 /* Try to sfileinfo to extend the file. */
767 ZERO_STRUCT(sfi);
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);
772
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");
777
778 /* Make sure the size is still 0. */
779 ZERO_STRUCT(qfi);
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");
785
786 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 0,
787 "alloc_size should be 0 since the setpathinfo failed.");
788
789 /* Try again with the pass through instead of documented version. */
790 ZERO_STRUCT(sfi);
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);
795
796 /*
797 * Looks like a windows bug:
798 * http://lists.samba.org/archive/cifs-protocol/2009-November/001130.html
799 */
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");
804
805 /* Verify that the file was actually extended to 100. */
806 ZERO_STRUCT(qfi);
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");
812
813 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 100,
814 "alloc_size should be 100 since the setpathinfo "
815 "succeeded.");
816 } else {
817 torture_assert_ntstatus_equal_goto(tctx, status,
818 NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
819 "SHARING_VIOLATION");
820 }
821
822 /* close the first file. */
823 smbcli_close(cli1->tree, fnum);
824 fnum = 0;
825
826 /* Try to sfileinfo to extend the file again (non-pass-through). */
827 ZERO_STRUCT(sfi);
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);
832
833 /* This should cause the client to retun invalid level. */
834 if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
835 /*
836 * Windows sends back an invalid packet that smbclient sees
837 * and returns INTERNAL_ERROR.
838 */
839 torture_assert_ntstatus_equal_goto(tctx, status,
840 NT_STATUS_INTERNAL_ERROR, ret, done, "Status should be "
841 "INTERNAL_ERROR");
842 } else {
843 torture_assert_ntstatus_equal_goto(tctx, status,
844 NT_STATUS_INVALID_LEVEL, ret, done, "Status should be "
845 "INVALID_LEVEL");
846 }
847
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");
853
854 /* Verify that the file was actually extended to 200. */
855 ZERO_STRUCT(qfi);
856 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
857 qfi.generic.in.file.path = fname;
858 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
859
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.");
864
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;
871
872 /* Try sfileinfo to extend the file by handle (non-pass-through). */
873 ZERO_STRUCT(sfi);
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");
880
881 /* Verify that the file was actually extended to 300. */
882 ZERO_STRUCT(qfi);
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.");
890
891 /* Try sfileinfo to extend the file by handle (pass-through). */
892 ZERO_STRUCT(sfi);
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");
899
900 /* Verify that the file was actually extended to 300. */
901 ZERO_STRUCT(qfi);
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.");
909 done:
910 if (fnum > 0) {
911 smbcli_close(cli1->tree, fnum);
912 fnum = 0;
913 }
914
915 smb_raw_exit(cli1->session);
916 smb_raw_exit(cli2->session);
917 smbcli_deltree(cli1->tree, BASEDIR);
918 return ret;
919}
920
921static bool
922torture_raw_sfileinfo_eof_access(struct torture_context *tctx,
923 struct smbcli_state *cli1, struct smbcli_state *cli2)
924{
925 const char *fname = BASEDIR "\\test_exclusive3.dat";
926 NTSTATUS status, expected_status;
927 bool ret = true;
928 union smb_open io;
929 union smb_setfileinfo sfi;
930 uint16_t fnum=0;
931 uint32_t access_mask = 0;
932
933 if (!torture_setup_dir(cli1, BASEDIR)) {
934 return false;
935 }
936
937 /* cleanup */
938 smbcli_unlink(cli1->tree, fname);
939
940 /*
941 * base ntcreatex parms
942 */
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;
954
955
956 for (access_mask = 1; access_mask <= 0x00001FF; access_mask++) {
957 io.ntcreatex.in.access_mask = access_mask;
958
959 status = smb_raw_open(cli1->tree, tctx, &io);
960 if (!NT_STATUS_IS_OK(status)) {
961 continue;
962 }
963
964 fnum = io.ntcreatex.out.file.fnum;
965
966 ZERO_STRUCT(sfi);
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;
970
971 status = smb_raw_setfileinfo(cli1->tree, &sfi);
972
973 expected_status = (access_mask & SEC_FILE_WRITE_DATA) ?
974 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
975
976 if (!NT_STATUS_EQUAL(expected_status, status)) {
977 torture_comment(tctx, "0x%x wrong\n", access_mask);
978 }
979
980 torture_assert_ntstatus_equal_goto(tctx, status,
981 expected_status, ret, done, "Status Wrong");
982
983 smbcli_close(cli1->tree, fnum);
984 }
985
986done:
987 smb_raw_exit(cli1->session);
988 smb_raw_exit(cli2->session);
989 smbcli_deltree(cli1->tree, BASEDIR);
990 return ret;
991}
992
993static bool
994torture_raw_sfileinfo_archive(struct torture_context *tctx,
995 struct smbcli_state *cli)
996{
997 const char *fname = BASEDIR "\\test_archive.dat";
998 NTSTATUS status;
999 bool ret = true;
1000 union smb_open io;
1001 union smb_setfileinfo sfinfo;
1002 union smb_fileinfo finfo;
1003 uint16_t fnum=0;
1004
1005 if (!torture_setup_dir(cli, BASEDIR)) {
1006 return false;
1007 }
1008
1009 /* cleanup */
1010 smbcli_unlink(cli->tree, fname);
1011
1012 /*
1013 * create a normal file, verify archive bit
1014 */
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;
1031
1032 torture_assert_int_equal(tctx,
1033 io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1034 FILE_ATTRIBUTE_ARCHIVE,
1035 "archive bit not set");
1036
1037 /*
1038 * try to turn off archive bit
1039 */
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");
1047
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");
1053
1054 torture_assert_int_equal(tctx,
1055 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1056 FILE_ATTRIBUTE_NORMAL,
1057 "archive bit set");
1058
1059 status = smbcli_close(cli->tree, fnum);
1060 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1061 ret, done, "close failed");
1062
1063 status = smbcli_unlink(cli->tree, fname);
1064 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1065 ret, done, "unlink failed");
1066
1067 /*
1068 * create a directory, verify no archive bit
1069 */
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;
1086
1087 torture_assert_int_equal(tctx,
1088 io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1089 FILE_ATTRIBUTE_DIRECTORY,
1090 "archive bit set");
1091
1092 /*
1093 * verify you can turn on archive bit
1094 */
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");
1101
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");
1107
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");
1112
1113 /*
1114 * and try to turn it back off
1115 */
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");
1122
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");
1128
1129 torture_assert_int_equal(tctx,
1130 finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1131 FILE_ATTRIBUTE_DIRECTORY,
1132 "archive bit set");
1133
1134 status = smbcli_close(cli->tree, fnum);
1135 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
1136 ret, done, "close failed");
1137
1138done:
1139 smbcli_close(cli->tree, fnum);
1140 smbcli_deltree(cli->tree, BASEDIR);
1141 return ret;
1142}
1143
1144struct torture_suite *torture_raw_sfileinfo(TALLOC_CTX *mem_ctx)
1145{
1146 struct torture_suite *suite = torture_suite_create(mem_ctx, "sfileinfo");
1147
1148 torture_suite_add_1smb_test(suite, "base", torture_raw_sfileinfo_base);
1149 torture_suite_add_1smb_test(suite, "rename", torture_raw_sfileinfo_rename);
1150 torture_suite_add_1smb_test(suite, "bug", torture_raw_sfileinfo_bug);
1151 torture_suite_add_2smb_test(suite, "end-of-file",
1152 torture_raw_sfileinfo_eof);
1153 torture_suite_add_2smb_test(suite, "end-of-file-access",
1154 torture_raw_sfileinfo_eof_access);
1155 torture_suite_add_1smb_test(suite, "archive",
1156 torture_raw_sfileinfo_archive);
1157
1158 return suite;
1159}
Note: See TracBrowser for help on using the repository browser.