r4612: make the output for the w2k3 acl bug a bit clearer
[Samba/gebeck_regimport.git] / source4 / torture / raw / open.c
blob3fa248e0a49927e5b408dad434ea0c58dac85293
1 /*
2 Unix SMB/CIFS implementation.
3 RAW_OPEN_* 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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "includes.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "system/time.h"
24 #include "librpc/gen_ndr/ndr_security.h"
26 /* enum for whether reads/writes are possible on a file */
27 enum rdwr_mode {RDWR_NONE, RDWR_RDONLY, RDWR_WRONLY, RDWR_RDWR};
29 #define BASEDIR "\\rawopen"
32 check if a open file can be read/written
34 static enum rdwr_mode check_rdwr(struct smbcli_tree *tree, int fnum)
36 uint8_t c = 1;
37 BOOL can_read = (smbcli_read(tree, fnum, &c, 0, 1) == 1);
38 BOOL can_write = (smbcli_write(tree, fnum, 0, &c, 0, 1) == 1);
39 if ( can_read && can_write) return RDWR_RDWR;
40 if ( can_read && !can_write) return RDWR_RDONLY;
41 if (!can_read && can_write) return RDWR_WRONLY;
42 return RDWR_NONE;
46 describe a RDWR mode as a string
48 static const char *rdwr_string(enum rdwr_mode m)
50 switch (m) {
51 case RDWR_NONE: return "NONE";
52 case RDWR_RDONLY: return "RDONLY";
53 case RDWR_WRONLY: return "WRONLY";
54 case RDWR_RDWR: return "RDWR";
56 return "-";
59 #define CHECK_STATUS(status, correct) do { \
60 if (!NT_STATUS_EQUAL(status, correct)) { \
61 printf("(%s) Incorrect status %s - should be %s\n", \
62 __location__, nt_errstr(status), nt_errstr(correct)); \
63 ret = False; \
64 goto done; \
65 }} while (0)
67 #define CREATE_FILE do { \
68 fnum = create_complex_file(cli, mem_ctx, fname); \
69 if (fnum == -1) { \
70 printf("(%s) Failed to create %s - %s\n", __location__, fname, smbcli_errstr(cli->tree)); \
71 ret = False; \
72 goto done; \
73 }} while (0)
75 #define CHECK_RDWR(fnum, correct) do { \
76 enum rdwr_mode m = check_rdwr(cli->tree, fnum); \
77 if (m != correct) { \
78 printf("(%s) Incorrect readwrite mode %s - expected %s\n", \
79 __location__, rdwr_string(m), rdwr_string(correct)); \
80 ret = False; \
81 }} while (0)
83 #define CHECK_TIME(t, field) do { \
84 time_t t1, t2; \
85 finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
86 finfo.all_info.in.fname = fname; \
87 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); \
88 CHECK_STATUS(status, NT_STATUS_OK); \
89 t1 = t & ~1; \
90 t2 = nt_time_to_unix(finfo.all_info.out.field) & ~1; \
91 if (ABS(t1-t2) > 2) { \
92 printf("(%s) wrong time for field %s %s - %s\n", \
93 __location__, #field, \
94 timestring(mem_ctx, t1), \
95 timestring(mem_ctx, t2)); \
96 dump_all_info(mem_ctx, &finfo); \
97 ret = False; \
98 }} while (0)
100 #define CHECK_NTTIME(t, field) do { \
101 NTTIME t2; \
102 finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
103 finfo.all_info.in.fname = fname; \
104 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); \
105 CHECK_STATUS(status, NT_STATUS_OK); \
106 t2 = finfo.all_info.out.field; \
107 if (t != t2) { \
108 printf("(%s) wrong time for field %s %s - %s\n", \
109 __location__, #field, \
110 nt_time_string(mem_ctx, t), \
111 nt_time_string(mem_ctx, t2)); \
112 dump_all_info(mem_ctx, &finfo); \
113 ret = False; \
114 }} while (0)
116 #define CHECK_ALL_INFO(v, field) do { \
117 finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
118 finfo.all_info.in.fname = fname; \
119 status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); \
120 CHECK_STATUS(status, NT_STATUS_OK); \
121 if ((v) != (finfo.all_info.out.field)) { \
122 printf("(%s) wrong value for field %s 0x%x - 0x%x\n", \
123 __location__, #field, (int)v, (int)(finfo.all_info.out.field)); \
124 dump_all_info(mem_ctx, &finfo); \
125 ret = False; \
126 }} while (0)
128 #define CHECK_VAL(v, correct) do { \
129 if ((v) != (correct)) { \
130 printf("(%s) wrong value for %s 0x%x - should be 0x%x\n", \
131 __location__, #v, (int)(v), (int)correct); \
132 ret = False; \
133 }} while (0)
135 #define SET_ATTRIB(sattrib) do { \
136 union smb_setfileinfo sfinfo; \
137 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION; \
138 sfinfo.generic.file.fname = fname; \
139 ZERO_STRUCT(sfinfo.basic_info.in); \
140 sfinfo.basic_info.in.attrib = sattrib; \
141 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
142 if (!NT_STATUS_IS_OK(status)) { \
143 printf("(%s) Failed to set attrib 0x%x on %s\n", \
144 __location__, sattrib, fname); \
145 }} while (0)
148 test RAW_OPEN_OPEN
150 static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
152 union smb_open io;
153 union smb_fileinfo finfo;
154 const char *fname = BASEDIR "\\torture_open.txt";
155 NTSTATUS status;
156 int fnum = -1, fnum2;
157 BOOL ret = True;
159 printf("Checking RAW_OPEN_OPEN\n");
161 io.openold.level = RAW_OPEN_OPEN;
162 io.openold.in.fname = fname;
163 io.openold.in.open_mode = OPEN_FLAGS_FCB;
164 io.openold.in.search_attrs = 0;
165 status = smb_raw_open(cli->tree, mem_ctx, &io);
166 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
167 fnum = io.openold.out.fnum;
169 smbcli_unlink(cli->tree, fname);
170 CREATE_FILE;
171 smbcli_close(cli->tree, fnum);
173 status = smb_raw_open(cli->tree, mem_ctx, &io);
174 CHECK_STATUS(status, NT_STATUS_OK);
175 fnum = io.openold.out.fnum;
176 CHECK_RDWR(fnum, RDWR_RDWR);
178 status = smb_raw_open(cli->tree, mem_ctx, &io);
179 CHECK_STATUS(status, NT_STATUS_OK);
180 fnum2 = io.openold.out.fnum;
181 CHECK_RDWR(fnum2, RDWR_RDWR);
182 smbcli_close(cli->tree, fnum2);
183 smbcli_close(cli->tree, fnum);
185 /* check the read/write modes */
186 io.openold.level = RAW_OPEN_OPEN;
187 io.openold.in.fname = fname;
188 io.openold.in.search_attrs = 0;
190 io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
191 status = smb_raw_open(cli->tree, mem_ctx, &io);
192 CHECK_STATUS(status, NT_STATUS_OK);
193 fnum = io.openold.out.fnum;
194 CHECK_RDWR(fnum, RDWR_RDONLY);
195 smbcli_close(cli->tree, fnum);
197 io.openold.in.open_mode = OPEN_FLAGS_OPEN_WRITE;
198 status = smb_raw_open(cli->tree, mem_ctx, &io);
199 CHECK_STATUS(status, NT_STATUS_OK);
200 fnum = io.openold.out.fnum;
201 CHECK_RDWR(fnum, RDWR_WRONLY);
202 smbcli_close(cli->tree, fnum);
204 io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR;
205 status = smb_raw_open(cli->tree, mem_ctx, &io);
206 CHECK_STATUS(status, NT_STATUS_OK);
207 fnum = io.openold.out.fnum;
208 CHECK_RDWR(fnum, RDWR_RDWR);
209 smbcli_close(cli->tree, fnum);
211 /* check the share modes roughly - not a complete matrix */
212 io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_WRITE;
213 status = smb_raw_open(cli->tree, mem_ctx, &io);
214 CHECK_STATUS(status, NT_STATUS_OK);
215 fnum = io.openold.out.fnum;
216 CHECK_RDWR(fnum, RDWR_RDWR);
218 if (io.openold.in.open_mode != io.openold.out.rmode) {
219 printf("(%s) rmode should equal open_mode - 0x%x 0x%x\n",
220 __location__, io.openold.out.rmode, io.openold.in.open_mode);
223 io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_NONE;
224 status = smb_raw_open(cli->tree, mem_ctx, &io);
225 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
227 io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ | OPEN_FLAGS_DENY_NONE;
228 status = smb_raw_open(cli->tree, mem_ctx, &io);
229 CHECK_STATUS(status, NT_STATUS_OK);
230 fnum2 = io.openold.out.fnum;
231 CHECK_RDWR(fnum2, RDWR_RDONLY);
232 smbcli_close(cli->tree, fnum);
233 smbcli_close(cli->tree, fnum2);
236 /* check the returned write time */
237 io.openold.level = RAW_OPEN_OPEN;
238 io.openold.in.fname = fname;
239 io.openold.in.search_attrs = 0;
240 io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
241 status = smb_raw_open(cli->tree, mem_ctx, &io);
242 CHECK_STATUS(status, NT_STATUS_OK);
243 fnum = io.openold.out.fnum;
245 /* check other reply fields */
246 CHECK_TIME(io.openold.out.write_time, write_time);
247 CHECK_ALL_INFO(io.openold.out.size, size);
248 CHECK_ALL_INFO(io.openold.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
250 done:
251 smbcli_close(cli->tree, fnum);
252 smbcli_unlink(cli->tree, fname);
254 return ret;
259 test RAW_OPEN_OPENX
261 static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
263 union smb_open io;
264 union smb_fileinfo finfo;
265 const char *fname = BASEDIR "\\torture_openx.txt";
266 NTSTATUS status;
267 int fnum = -1, fnum2;
268 BOOL ret = True;
269 int i;
270 struct timeval tv;
271 struct {
272 uint16_t open_func;
273 BOOL with_file;
274 NTSTATUS correct_status;
275 } open_funcs[] = {
276 { OPENX_OPEN_FUNC_OPEN, True, NT_STATUS_OK },
277 { OPENX_OPEN_FUNC_OPEN, False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
278 { OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE, True, NT_STATUS_OK },
279 { OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OK },
280 { OPENX_OPEN_FUNC_FAIL, True, NT_STATUS_INVALID_LOCK_SEQUENCE },
281 { OPENX_OPEN_FUNC_FAIL, False, NT_STATUS_INVALID_LOCK_SEQUENCE },
282 { OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE, True, NT_STATUS_OBJECT_NAME_COLLISION },
283 { OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OK },
284 { OPENX_OPEN_FUNC_TRUNC, True, NT_STATUS_OK },
285 { OPENX_OPEN_FUNC_TRUNC, False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
286 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, True, NT_STATUS_OK },
287 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OK },
290 printf("Checking RAW_OPEN_OPENX\n");
291 smbcli_unlink(cli->tree, fname);
293 io.openx.level = RAW_OPEN_OPENX;
294 io.openx.in.fname = fname;
295 io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
296 io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
297 io.openx.in.search_attrs = 0;
298 io.openx.in.file_attrs = 0;
299 io.openx.in.write_time = 0;
300 io.openx.in.size = 1024*1024;
301 io.openx.in.timeout = 0;
303 /* check all combinations of open_func */
304 for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
305 if (open_funcs[i].with_file) {
306 fnum = create_complex_file(cli, mem_ctx, fname);
307 if (fnum == -1) {
308 d_printf("Failed to create file %s - %s\n", fname, smbcli_errstr(cli->tree));
309 ret = False;
310 goto done;
312 smbcli_close(cli->tree, fnum);
314 io.openx.in.open_func = open_funcs[i].open_func;
315 status = smb_raw_open(cli->tree, mem_ctx, &io);
316 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
317 printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_func=0x%x)\n",
318 __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
319 i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_func);
320 ret = False;
322 if (NT_STATUS_IS_OK(status)) {
323 smbcli_close(cli->tree, io.openx.out.fnum);
325 if (open_funcs[i].with_file) {
326 smbcli_unlink(cli->tree, fname);
330 smbcli_unlink(cli->tree, fname);
332 /* check the basic return fields */
333 io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
334 status = smb_raw_open(cli->tree, mem_ctx, &io);
335 CHECK_STATUS(status, NT_STATUS_OK);
336 fnum = io.openx.out.fnum;
338 CHECK_ALL_INFO(io.openx.out.size, size);
339 CHECK_TIME(io.openx.out.write_time, write_time);
340 CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
341 CHECK_VAL(io.openx.out.access, OPENX_MODE_ACCESS_RDWR);
342 CHECK_VAL(io.openx.out.ftype, 0);
343 CHECK_VAL(io.openx.out.devstate, 0);
344 CHECK_VAL(io.openx.out.action, OPENX_ACTION_CREATED);
345 CHECK_VAL(io.openx.out.size, 1024*1024);
346 CHECK_ALL_INFO(io.openx.in.size, size);
347 smbcli_close(cli->tree, fnum);
348 smbcli_unlink(cli->tree, fname);
350 /* check the fields when the file already existed */
351 fnum2 = create_complex_file(cli, mem_ctx, fname);
352 if (fnum2 == -1) {
353 ret = False;
354 goto done;
356 smbcli_close(cli->tree, fnum2);
358 io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
359 status = smb_raw_open(cli->tree, mem_ctx, &io);
360 CHECK_STATUS(status, NT_STATUS_OK);
361 fnum = io.openx.out.fnum;
363 CHECK_ALL_INFO(io.openx.out.size, size);
364 CHECK_TIME(io.openx.out.write_time, write_time);
365 CHECK_VAL(io.openx.out.action, OPENX_ACTION_EXISTED);
366 CHECK_VAL(io.openx.out.unknown, 0);
367 CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
368 smbcli_close(cli->tree, fnum);
370 /* now check the search attrib for hidden files - win2003 ignores this? */
371 SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
372 CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
374 io.openx.in.search_attrs = FILE_ATTRIBUTE_HIDDEN;
375 status = smb_raw_open(cli->tree, mem_ctx, &io);
376 CHECK_STATUS(status, NT_STATUS_OK);
377 smbcli_close(cli->tree, io.openx.out.fnum);
379 io.openx.in.search_attrs = 0;
380 status = smb_raw_open(cli->tree, mem_ctx, &io);
381 CHECK_STATUS(status, NT_STATUS_OK);
382 smbcli_close(cli->tree, io.openx.out.fnum);
384 SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
385 smbcli_unlink(cli->tree, fname);
387 /* and check attrib on create */
388 io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
389 io.openx.in.search_attrs = 0;
390 io.openx.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
391 status = smb_raw_open(cli->tree, mem_ctx, &io);
392 CHECK_STATUS(status, NT_STATUS_OK);
393 CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE,
394 attrib & ~FILE_ATTRIBUTE_NONINDEXED);
395 smbcli_close(cli->tree, io.openx.out.fnum);
396 smbcli_unlink(cli->tree, fname);
398 /* check timeout on create - win2003 ignores the timeout! */
399 io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
400 io.openx.in.file_attrs = 0;
401 io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
402 status = smb_raw_open(cli->tree, mem_ctx, &io);
403 CHECK_STATUS(status, NT_STATUS_OK);
404 fnum = io.openx.out.fnum;
406 io.openx.in.timeout = 20000;
407 tv = timeval_current();
408 io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_NONE;
409 status = smb_raw_open(cli->tree, mem_ctx, &io);
410 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
411 if (timeval_elapsed(&tv) > 3.0) {
412 printf("(%s) Incorrect timing in openx with timeout - waited %.2f seconds\n",
413 __location__, timeval_elapsed(&tv));
414 ret = False;
416 smbcli_close(cli->tree, fnum);
417 smbcli_unlink(cli->tree, fname);
419 /* now this is a really weird one - open for execute implies create?! */
420 io.openx.in.fname = fname;
421 io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
422 io.openx.in.open_mode = OPENX_MODE_ACCESS_EXEC | OPENX_MODE_DENY_NONE;
423 io.openx.in.search_attrs = 0;
424 io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL;
425 io.openx.in.file_attrs = 0;
426 io.openx.in.write_time = 0;
427 io.openx.in.size = 0;
428 io.openx.in.timeout = 0;
429 status = smb_raw_open(cli->tree, mem_ctx, &io);
430 CHECK_STATUS(status, NT_STATUS_OK);
431 smbcli_close(cli->tree, io.openx.out.fnum);
433 /* check the extended return flag */
434 io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO | OPENX_FLAGS_EXTENDED_RETURN;
435 io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
436 status = smb_raw_open(cli->tree, mem_ctx, &io);
437 CHECK_STATUS(status, NT_STATUS_OK);
438 CHECK_VAL(io.openx.out.access_mask, SEC_STD_ALL);
439 smbcli_close(cli->tree, io.openx.out.fnum);
441 io.openx.in.fname = "\\A.+,;=[].B";
442 status = smb_raw_open(cli->tree, mem_ctx, &io);
443 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
445 done:
446 smbcli_close(cli->tree, fnum);
447 smbcli_unlink(cli->tree, fname);
449 return ret;
454 test RAW_OPEN_T2OPEN
456 many thanks to kukks for a sniff showing how this works with os2->w2k
458 static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
460 union smb_open io;
461 union smb_fileinfo finfo;
462 const char *fname1 = BASEDIR "\\torture_t2open_yes.txt";
463 const char *fname2 = BASEDIR "\\torture_t2open_no.txt";
464 const char *fname = BASEDIR "\\torture_t2open_3.txt";
465 NTSTATUS status;
466 int fnum;
467 BOOL ret = True;
468 int i;
469 struct {
470 uint16_t open_func;
471 BOOL with_file;
472 NTSTATUS correct_status;
473 } open_funcs[] = {
474 { OPENX_OPEN_FUNC_OPEN, True, NT_STATUS_OK },
475 { OPENX_OPEN_FUNC_OPEN, False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
476 { OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE, True, NT_STATUS_OK },
477 { OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OK },
478 { OPENX_OPEN_FUNC_FAIL, True, NT_STATUS_OBJECT_NAME_COLLISION },
479 { OPENX_OPEN_FUNC_FAIL, False, NT_STATUS_OBJECT_NAME_COLLISION },
480 { OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE, True, NT_STATUS_OBJECT_NAME_COLLISION },
481 { OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OBJECT_NAME_COLLISION },
482 { OPENX_OPEN_FUNC_TRUNC, True, NT_STATUS_OK },
483 { OPENX_OPEN_FUNC_TRUNC, False, NT_STATUS_OK },
484 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, True, NT_STATUS_OK },
485 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OK },
488 fnum = create_complex_file(cli, mem_ctx, fname1);
489 if (fnum == -1) {
490 d_printf("Failed to create file %s - %s\n", fname1, smbcli_errstr(cli->tree));
491 ret = False;
492 goto done;
494 smbcli_close(cli->tree, fnum);
496 printf("Checking RAW_OPEN_T2OPEN\n");
498 io.t2open.level = RAW_OPEN_T2OPEN;
499 io.t2open.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
500 io.t2open.in.open_mode = OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR;
501 io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
502 io.t2open.in.search_attrs = 0;
503 io.t2open.in.file_attrs = 0;
504 io.t2open.in.write_time = 0;
505 io.t2open.in.size = 0;
506 io.t2open.in.timeout = 0;
508 io.t2open.in.num_eas = 3;
509 io.t2open.in.eas = talloc_array_p(mem_ctx, struct ea_struct, io.t2open.in.num_eas);
510 io.t2open.in.eas[0].flags = 0;
511 io.t2open.in.eas[0].name.s = ".CLASSINFO";
512 io.t2open.in.eas[0].value = data_blob_talloc(mem_ctx, "first value", 11);
513 io.t2open.in.eas[1].flags = 0;
514 io.t2open.in.eas[1].name.s = "EA TWO";
515 io.t2open.in.eas[1].value = data_blob_talloc(mem_ctx, "foo", 3);
516 io.t2open.in.eas[2].flags = 0;
517 io.t2open.in.eas[2].name.s = "X THIRD";
518 io.t2open.in.eas[2].value = data_blob_talloc(mem_ctx, "xy", 2);
520 /* check all combinations of open_func */
521 for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
522 if (open_funcs[i].with_file) {
523 io.t2open.in.fname = fname1;
524 } else {
525 io.t2open.in.fname = fname2;
527 io.t2open.in.open_func = open_funcs[i].open_func;
528 status = smb_raw_open(cli->tree, mem_ctx, &io);
529 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
530 printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_func=0x%x)\n",
531 __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
532 i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_func);
533 ret = False;
535 if (NT_STATUS_IS_OK(status)) {
536 smbcli_close(cli->tree, io.t2open.out.fnum);
540 smbcli_unlink(cli->tree, fname1);
541 smbcli_unlink(cli->tree, fname2);
543 /* check the basic return fields */
544 io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
545 io.t2open.in.write_time = 0;
546 io.t2open.in.fname = fname;
547 status = smb_raw_open(cli->tree, mem_ctx, &io);
548 CHECK_STATUS(status, NT_STATUS_OK);
549 fnum = io.t2open.out.fnum;
551 CHECK_ALL_INFO(io.t2open.out.size, size);
552 #if 0
553 /* windows appears to leak uninitialised memory here */
554 CHECK_VAL(io.t2open.out.write_time, 0);
555 #endif
556 CHECK_ALL_INFO(io.t2open.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
557 CHECK_VAL(io.t2open.out.access, OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR);
558 CHECK_VAL(io.t2open.out.ftype, 0);
559 CHECK_VAL(io.t2open.out.devstate, 0);
560 CHECK_VAL(io.t2open.out.action, OPENX_ACTION_CREATED);
561 smbcli_close(cli->tree, fnum);
563 status = torture_check_ea(cli, fname, ".CLASSINFO", "first value");
564 CHECK_STATUS(status, NT_STATUS_OK);
565 status = torture_check_ea(cli, fname, "EA TWO", "foo");
566 CHECK_STATUS(status, NT_STATUS_OK);
567 status = torture_check_ea(cli, fname, "X THIRD", "xy");
568 CHECK_STATUS(status, NT_STATUS_OK);
570 /* now check the search attrib for hidden files - win2003 ignores this? */
571 SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
572 CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
574 status = smb_raw_open(cli->tree, mem_ctx, &io);
575 CHECK_STATUS(status, NT_STATUS_OK);
576 smbcli_close(cli->tree, io.t2open.out.fnum);
578 status = smb_raw_open(cli->tree, mem_ctx, &io);
579 CHECK_STATUS(status, NT_STATUS_OK);
580 smbcli_close(cli->tree, io.t2open.out.fnum);
582 SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
583 smbcli_unlink(cli->tree, fname);
585 /* and check attrib on create */
586 io.t2open.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
587 io.t2open.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
588 status = smb_raw_open(cli->tree, mem_ctx, &io);
589 CHECK_STATUS(status, NT_STATUS_OK);
591 /* check timeout on create - win2003 ignores the timeout! */
592 io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
593 io.t2open.in.file_attrs = 0;
594 io.t2open.in.timeout = 20000;
595 io.t2open.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
596 status = smb_raw_open(cli->tree, mem_ctx, &io);
597 CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
599 done:
600 smbcli_close(cli->tree, fnum);
601 smbcli_unlink(cli->tree, fname);
603 return ret;
608 test RAW_OPEN_NTCREATEX
610 static BOOL test_ntcreatex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
612 union smb_open io;
613 union smb_fileinfo finfo;
614 const char *fname = BASEDIR "\\torture_ntcreatex.txt";
615 const char *dname = BASEDIR "\\torture_ntcreatex.dir";
616 NTSTATUS status;
617 int fnum = -1;
618 BOOL ret = True;
619 int i;
620 struct {
621 uint32_t open_disp;
622 BOOL with_file;
623 NTSTATUS correct_status;
624 } open_funcs[] = {
625 { NTCREATEX_DISP_SUPERSEDE, True, NT_STATUS_OK },
626 { NTCREATEX_DISP_SUPERSEDE, False, NT_STATUS_OK },
627 { NTCREATEX_DISP_OPEN, True, NT_STATUS_OK },
628 { NTCREATEX_DISP_OPEN, False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
629 { NTCREATEX_DISP_CREATE, True, NT_STATUS_OBJECT_NAME_COLLISION },
630 { NTCREATEX_DISP_CREATE, False, NT_STATUS_OK },
631 { NTCREATEX_DISP_OPEN_IF, True, NT_STATUS_OK },
632 { NTCREATEX_DISP_OPEN_IF, False, NT_STATUS_OK },
633 { NTCREATEX_DISP_OVERWRITE, True, NT_STATUS_OK },
634 { NTCREATEX_DISP_OVERWRITE, False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
635 { NTCREATEX_DISP_OVERWRITE_IF, True, NT_STATUS_OK },
636 { NTCREATEX_DISP_OVERWRITE_IF, False, NT_STATUS_OK },
637 { 6, True, NT_STATUS_INVALID_PARAMETER },
638 { 6, False, NT_STATUS_INVALID_PARAMETER },
641 printf("Checking RAW_OPEN_NTCREATEX\n");
643 /* reasonable default parameters */
644 io.generic.level = RAW_OPEN_NTCREATEX;
645 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
646 io.ntcreatex.in.root_fid = 0;
647 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
648 io.ntcreatex.in.alloc_size = 1024*1024;
649 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
650 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
651 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
652 io.ntcreatex.in.create_options = 0;
653 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
654 io.ntcreatex.in.security_flags = 0;
655 io.ntcreatex.in.fname = fname;
657 /* test the open disposition */
658 for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
659 if (open_funcs[i].with_file) {
660 fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
661 if (fnum == -1) {
662 d_printf("Failed to create file %s - %s\n", fname, smbcli_errstr(cli->tree));
663 ret = False;
664 goto done;
666 smbcli_close(cli->tree, fnum);
668 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
669 status = smb_raw_open(cli->tree, mem_ctx, &io);
670 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
671 printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_disp=%d)\n",
672 __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
673 i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_disp);
674 ret = False;
676 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
677 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
678 smbcli_unlink(cli->tree, fname);
682 /* basic field testing */
683 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
685 status = smb_raw_open(cli->tree, mem_ctx, &io);
686 CHECK_STATUS(status, NT_STATUS_OK);
687 fnum = io.ntcreatex.out.fnum;
689 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
690 CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
691 CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
692 CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
693 CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
694 CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
695 CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
696 CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
697 CHECK_ALL_INFO(io.ntcreatex.out.size, size);
698 CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
699 CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
701 /* check fields when the file already existed */
702 smbcli_close(cli->tree, fnum);
703 smbcli_unlink(cli->tree, fname);
704 fnum = create_complex_file(cli, mem_ctx, fname);
705 if (fnum == -1) {
706 ret = False;
707 goto done;
709 smbcli_close(cli->tree, fnum);
711 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
712 status = smb_raw_open(cli->tree, mem_ctx, &io);
713 CHECK_STATUS(status, NT_STATUS_OK);
714 fnum = io.ntcreatex.out.fnum;
716 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
717 CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
718 CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
719 CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
720 CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
721 CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
722 CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
723 CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
724 CHECK_ALL_INFO(io.ntcreatex.out.size, size);
725 CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
726 CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
727 smbcli_close(cli->tree, fnum);
728 smbcli_unlink(cli->tree, fname);
731 /* create a directory */
732 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
733 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
734 io.ntcreatex.in.alloc_size = 0;
735 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
736 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
737 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
738 io.ntcreatex.in.create_options = 0;
739 io.ntcreatex.in.fname = dname;
740 fname = dname;
742 smbcli_rmdir(cli->tree, fname);
743 smbcli_unlink(cli->tree, fname);
745 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
746 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
747 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
748 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
749 status = smb_raw_open(cli->tree, mem_ctx, &io);
750 CHECK_STATUS(status, NT_STATUS_OK);
751 fnum = io.ntcreatex.out.fnum;
753 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
754 CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
755 CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
756 CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
757 CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
758 CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
759 CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
760 CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
761 FILE_ATTRIBUTE_DIRECTORY);
762 CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
763 CHECK_ALL_INFO(io.ntcreatex.out.size, size);
764 CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
765 CHECK_VAL(io.ntcreatex.out.is_directory, 1);
766 CHECK_VAL(io.ntcreatex.out.size, 0);
767 CHECK_VAL(io.ntcreatex.out.alloc_size, 0);
768 CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
769 smbcli_unlink(cli->tree, fname);
772 done:
773 smbcli_close(cli->tree, fnum);
774 smbcli_unlink(cli->tree, fname);
776 return ret;
781 test RAW_OPEN_NTTRANS_CREATE
783 static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
785 union smb_open io;
786 union smb_fileinfo finfo;
787 const char *fname = BASEDIR "\\torture_ntcreatex.txt";
788 const char *dname = BASEDIR "\\torture_ntcreatex.dir";
789 NTSTATUS status;
790 int fnum = -1;
791 BOOL ret = True;
792 int i;
793 struct {
794 uint32_t open_disp;
795 BOOL with_file;
796 NTSTATUS correct_status;
797 } open_funcs[] = {
798 { NTCREATEX_DISP_SUPERSEDE, True, NT_STATUS_OK },
799 { NTCREATEX_DISP_SUPERSEDE, False, NT_STATUS_OK },
800 { NTCREATEX_DISP_OPEN, True, NT_STATUS_OK },
801 { NTCREATEX_DISP_OPEN, False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
802 { NTCREATEX_DISP_CREATE, True, NT_STATUS_OBJECT_NAME_COLLISION },
803 { NTCREATEX_DISP_CREATE, False, NT_STATUS_OK },
804 { NTCREATEX_DISP_OPEN_IF, True, NT_STATUS_OK },
805 { NTCREATEX_DISP_OPEN_IF, False, NT_STATUS_OK },
806 { NTCREATEX_DISP_OVERWRITE, True, NT_STATUS_OK },
807 { NTCREATEX_DISP_OVERWRITE, False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
808 { NTCREATEX_DISP_OVERWRITE_IF, True, NT_STATUS_OK },
809 { NTCREATEX_DISP_OVERWRITE_IF, False, NT_STATUS_OK },
810 { 6, True, NT_STATUS_INVALID_PARAMETER },
811 { 6, False, NT_STATUS_INVALID_PARAMETER },
814 printf("Checking RAW_OPEN_NTTRANS_CREATE\n");
816 /* reasonable default parameters */
817 io.generic.level = RAW_OPEN_NTTRANS_CREATE;
818 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
819 io.ntcreatex.in.root_fid = 0;
820 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
821 io.ntcreatex.in.alloc_size = 1024*1024;
822 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
823 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
824 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
825 io.ntcreatex.in.create_options = 0;
826 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
827 io.ntcreatex.in.security_flags = 0;
828 io.ntcreatex.in.fname = fname;
829 io.ntcreatex.in.sec_desc = NULL;
830 io.ntcreatex.in.ea_list = NULL;
832 /* test the open disposition */
833 for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
834 if (open_funcs[i].with_file) {
835 fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
836 if (fnum == -1) {
837 d_printf("Failed to create file %s - %s\n", fname, smbcli_errstr(cli->tree));
838 ret = False;
839 goto done;
841 smbcli_close(cli->tree, fnum);
843 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
844 status = smb_raw_open(cli->tree, mem_ctx, &io);
845 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
846 printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_disp=%d)\n",
847 __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
848 i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_disp);
849 ret = False;
851 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
852 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
853 smbcli_unlink(cli->tree, fname);
857 /* basic field testing */
858 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
860 status = smb_raw_open(cli->tree, mem_ctx, &io);
861 CHECK_STATUS(status, NT_STATUS_OK);
862 fnum = io.ntcreatex.out.fnum;
864 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
865 CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
866 CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
867 CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
868 CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
869 CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
870 CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
871 CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
872 CHECK_ALL_INFO(io.ntcreatex.out.size, size);
873 CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
874 CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
876 /* check fields when the file already existed */
877 smbcli_close(cli->tree, fnum);
878 smbcli_unlink(cli->tree, fname);
879 fnum = create_complex_file(cli, mem_ctx, fname);
880 if (fnum == -1) {
881 ret = False;
882 goto done;
884 smbcli_close(cli->tree, fnum);
886 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
887 status = smb_raw_open(cli->tree, mem_ctx, &io);
888 CHECK_STATUS(status, NT_STATUS_OK);
889 fnum = io.ntcreatex.out.fnum;
891 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
892 CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
893 CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
894 CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
895 CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
896 CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
897 CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
898 CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
899 CHECK_ALL_INFO(io.ntcreatex.out.size, size);
900 CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
901 CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
902 smbcli_close(cli->tree, fnum);
903 smbcli_unlink(cli->tree, fname);
906 /* create a directory */
907 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
908 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
909 io.ntcreatex.in.alloc_size = 0;
910 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
911 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
912 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
913 io.ntcreatex.in.create_options = 0;
914 io.ntcreatex.in.fname = dname;
915 fname = dname;
917 smbcli_rmdir(cli->tree, fname);
918 smbcli_unlink(cli->tree, fname);
920 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
921 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
922 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
923 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
924 status = smb_raw_open(cli->tree, mem_ctx, &io);
925 CHECK_STATUS(status, NT_STATUS_OK);
926 fnum = io.ntcreatex.out.fnum;
928 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
929 CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
930 CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
931 CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
932 CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
933 CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
934 CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
935 CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
936 FILE_ATTRIBUTE_DIRECTORY);
937 CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
938 CHECK_ALL_INFO(io.ntcreatex.out.size, size);
939 CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
940 CHECK_VAL(io.ntcreatex.out.is_directory, 1);
941 CHECK_VAL(io.ntcreatex.out.size, 0);
942 CHECK_VAL(io.ntcreatex.out.alloc_size, 0);
943 CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
944 smbcli_unlink(cli->tree, fname);
947 done:
948 smbcli_close(cli->tree, fnum);
949 smbcli_unlink(cli->tree, fname);
951 return ret;
955 test RAW_OPEN_NTCREATEX with an already opened and byte range locked file
957 I've got an application that does a similar sequence of ntcreate&x,
958 locking&x and another ntcreate&x with
959 open_disposition==NTCREATEX_DISP_OVERWRITE_IF. Windows 2003 allows the
960 second open.
962 static BOOL test_ntcreatex_brlocked(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
964 union smb_open io, io1;
965 union smb_lock io2;
966 struct smb_lock_entry lock[1];
967 const char *fname = BASEDIR "\\torture_ntcreatex.txt";
968 NTSTATUS status;
969 BOOL ret = True;
971 /* reasonable default parameters */
972 io.generic.level = RAW_OPEN_NTCREATEX;
973 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
974 io.ntcreatex.in.root_fid = 0;
975 io.ntcreatex.in.access_mask = 0x2019f;
976 io.ntcreatex.in.alloc_size = 0;
977 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
978 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
979 NTCREATEX_SHARE_ACCESS_WRITE;
980 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
981 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
982 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
983 io.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
984 NTCREATEX_SECURITY_ALL;
985 io.ntcreatex.in.fname = fname;
987 status = smb_raw_open(cli->tree, mem_ctx, &io);
988 CHECK_STATUS(status, NT_STATUS_OK);
990 io2.lockx.level = RAW_LOCK_LOCKX;
991 io2.lockx.in.fnum = io.ntcreatex.out.fnum;
992 io2.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
993 io2.lockx.in.timeout = 0;
994 io2.lockx.in.ulock_cnt = 0;
995 io2.lockx.in.lock_cnt = 1;
996 lock[0].pid = cli->session->pid;
997 lock[0].offset = 0;
998 lock[0].count = 0x1;
999 io2.lockx.in.locks = &lock[0];
1000 status = smb_raw_lock(cli->tree, &io2);
1001 CHECK_STATUS(status, NT_STATUS_OK);
1003 io1.generic.level = RAW_OPEN_NTCREATEX;
1004 io1.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1005 io1.ntcreatex.in.root_fid = 0;
1006 io1.ntcreatex.in.access_mask = 0x20196;
1007 io1.ntcreatex.in.alloc_size = 0;
1008 io1.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1009 io1.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1010 NTCREATEX_SHARE_ACCESS_WRITE;
1011 io1.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1012 io1.ntcreatex.in.create_options = 0;
1013 io1.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1014 io1.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
1015 NTCREATEX_SECURITY_ALL;
1016 io1.ntcreatex.in.fname = fname;
1018 status = smb_raw_open(cli->tree, mem_ctx, &io1);
1019 CHECK_STATUS(status, NT_STATUS_OK);
1021 done:
1022 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
1023 smbcli_close(cli->tree, io1.ntcreatex.out.fnum);
1024 smbcli_unlink(cli->tree, fname);
1025 return ret;
1029 test RAW_OPEN_MKNEW
1031 static BOOL test_mknew(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
1033 union smb_open io;
1034 const char *fname = BASEDIR "\\torture_mknew.txt";
1035 NTSTATUS status;
1036 int fnum = -1;
1037 BOOL ret = True;
1038 time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1039 union smb_fileinfo finfo;
1041 printf("Checking RAW_OPEN_MKNEW\n");
1043 io.mknew.level = RAW_OPEN_MKNEW;
1044 io.mknew.in.attrib = 0;
1045 io.mknew.in.write_time = 0;
1046 io.mknew.in.fname = fname;
1047 status = smb_raw_open(cli->tree, mem_ctx, &io);
1048 CHECK_STATUS(status, NT_STATUS_OK);
1049 fnum = io.mknew.out.fnum;
1051 status = smb_raw_open(cli->tree, mem_ctx, &io);
1052 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
1054 smbcli_close(cli->tree, fnum);
1055 smbcli_unlink(cli->tree, fname);
1057 /* make sure write_time works */
1058 io.mknew.in.write_time = basetime;
1059 status = smb_raw_open(cli->tree, mem_ctx, &io);
1060 CHECK_STATUS(status, NT_STATUS_OK);
1061 fnum = io.mknew.out.fnum;
1062 CHECK_TIME(basetime, write_time);
1064 smbcli_close(cli->tree, fnum);
1065 smbcli_unlink(cli->tree, fname);
1067 /* make sure file_attrs works */
1068 io.mknew.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1069 status = smb_raw_open(cli->tree, mem_ctx, &io);
1070 CHECK_STATUS(status, NT_STATUS_OK);
1071 fnum = io.mknew.out.fnum;
1072 CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE,
1073 attrib & ~FILE_ATTRIBUTE_NONINDEXED);
1075 done:
1076 smbcli_close(cli->tree, fnum);
1077 smbcli_unlink(cli->tree, fname);
1079 return ret;
1084 test RAW_OPEN_CREATE
1086 static BOOL test_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
1088 union smb_open io;
1089 const char *fname = BASEDIR "\\torture_create.txt";
1090 NTSTATUS status;
1091 int fnum = -1;
1092 BOOL ret = True;
1093 time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1094 union smb_fileinfo finfo;
1096 printf("Checking RAW_OPEN_CREATE\n");
1098 io.create.level = RAW_OPEN_CREATE;
1099 io.create.in.attrib = 0;
1100 io.create.in.write_time = 0;
1101 io.create.in.fname = fname;
1102 status = smb_raw_open(cli->tree, mem_ctx, &io);
1103 CHECK_STATUS(status, NT_STATUS_OK);
1104 fnum = io.create.out.fnum;
1106 status = smb_raw_open(cli->tree, mem_ctx, &io);
1107 CHECK_STATUS(status, NT_STATUS_OK);
1109 smbcli_close(cli->tree, io.create.out.fnum);
1110 smbcli_close(cli->tree, fnum);
1111 smbcli_unlink(cli->tree, fname);
1113 /* make sure write_time works */
1114 io.create.in.write_time = basetime;
1115 status = smb_raw_open(cli->tree, mem_ctx, &io);
1116 CHECK_STATUS(status, NT_STATUS_OK);
1117 fnum = io.create.out.fnum;
1118 CHECK_TIME(basetime, write_time);
1120 smbcli_close(cli->tree, fnum);
1121 smbcli_unlink(cli->tree, fname);
1123 /* make sure file_attrs works */
1124 io.create.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1125 status = smb_raw_open(cli->tree, mem_ctx, &io);
1126 CHECK_STATUS(status, NT_STATUS_OK);
1127 fnum = io.create.out.fnum;
1128 CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE,
1129 attrib & ~FILE_ATTRIBUTE_NONINDEXED);
1131 done:
1132 smbcli_close(cli->tree, fnum);
1133 smbcli_unlink(cli->tree, fname);
1135 return ret;
1140 test RAW_OPEN_CTEMP
1142 static BOOL test_ctemp(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
1144 union smb_open io;
1145 NTSTATUS status;
1146 int fnum = -1;
1147 BOOL ret = True;
1148 time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1149 union smb_fileinfo finfo;
1150 const char *name, *fname = NULL;
1152 printf("Checking RAW_OPEN_CTEMP\n");
1154 io.ctemp.level = RAW_OPEN_CTEMP;
1155 io.ctemp.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1156 io.ctemp.in.write_time = basetime;
1157 io.ctemp.in.directory = BASEDIR;
1158 status = smb_raw_open(cli->tree, mem_ctx, &io);
1159 CHECK_STATUS(status, NT_STATUS_OK);
1160 fnum = io.ctemp.out.fnum;
1162 name = io.ctemp.out.name;
1164 finfo.generic.level = RAW_FILEINFO_NAME_INFO;
1165 finfo.generic.in.fnum = fnum;
1166 status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
1167 CHECK_STATUS(status, NT_STATUS_OK);
1169 fname = finfo.name_info.out.fname.s;
1170 d_printf("ctemp name=%s real name=%s\n", name, fname);
1172 done:
1173 smbcli_close(cli->tree, fnum);
1174 if (fname) {
1175 smbcli_unlink(cli->tree, fname);
1178 return ret;
1183 test chained RAW_OPEN_OPENX_READX
1185 static BOOL test_chained(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
1187 union smb_open io;
1188 const char *fname = BASEDIR "\\torture_chained.txt";
1189 NTSTATUS status;
1190 int fnum = -1;
1191 BOOL ret = True;
1192 const char *buf = "test";
1193 char buf2[4];
1195 printf("Checking RAW_OPEN_OPENX chained with READX\n");
1196 smbcli_unlink(cli->tree, fname);
1198 fnum = create_complex_file(cli, mem_ctx, fname);
1200 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1202 smbcli_close(cli->tree, fnum);
1204 io.openxreadx.level = RAW_OPEN_OPENX_READX;
1205 io.openxreadx.in.fname = fname;
1206 io.openxreadx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1207 io.openxreadx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1208 io.openxreadx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1209 io.openxreadx.in.search_attrs = 0;
1210 io.openxreadx.in.file_attrs = 0;
1211 io.openxreadx.in.write_time = 0;
1212 io.openxreadx.in.size = 1024*1024;
1213 io.openxreadx.in.timeout = 0;
1215 io.openxreadx.in.offset = 0;
1216 io.openxreadx.in.mincnt = sizeof(buf);
1217 io.openxreadx.in.maxcnt = sizeof(buf);
1218 io.openxreadx.in.remaining = 0;
1219 io.openxreadx.out.data = buf2;
1221 status = smb_raw_open(cli->tree, mem_ctx, &io);
1222 CHECK_STATUS(status, NT_STATUS_OK);
1223 fnum = io.openxreadx.out.fnum;
1225 if (memcmp(buf, buf2, sizeof(buf)) != 0) {
1226 d_printf("wrong data in reply buffer\n");
1227 ret = False;
1230 done:
1231 smbcli_close(cli->tree, fnum);
1232 smbcli_unlink(cli->tree, fname);
1234 return ret;
1238 /* basic testing of all RAW_OPEN_* calls
1240 BOOL torture_raw_open(void)
1242 struct smbcli_state *cli;
1243 BOOL ret = True;
1244 TALLOC_CTX *mem_ctx;
1246 if (!torture_open_connection(&cli)) {
1247 return False;
1250 mem_ctx = talloc_init("torture_raw_open");
1252 if (!torture_setup_dir(cli, BASEDIR)) {
1253 return False;
1256 ret &= test_ntcreatex_brlocked(cli, mem_ctx);
1257 ret &= test_open(cli, mem_ctx);
1258 ret &= test_openx(cli, mem_ctx);
1259 ret &= test_ntcreatex(cli, mem_ctx);
1260 ret &= test_nttrans_create(cli, mem_ctx);
1261 ret &= test_t2open(cli, mem_ctx);
1262 ret &= test_mknew(cli, mem_ctx);
1263 ret &= test_create(cli, mem_ctx);
1264 ret &= test_ctemp(cli, mem_ctx);
1265 ret &= test_chained(cli, mem_ctx);
1267 smb_raw_exit(cli->session);
1268 smbcli_deltree(cli->tree, BASEDIR);
1270 torture_close_connection(cli);
1271 talloc_destroy(mem_ctx);
1272 return ret;