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.
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
)
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
;
46 describe a RDWR mode as a string
48 static const char *rdwr_string(enum rdwr_mode 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";
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)); \
67 #define CREATE_FILE do { \
68 fnum = create_complex_file(cli, mem_ctx, fname); \
70 printf("(%s) Failed to create %s - %s\n", __location__, fname, smbcli_errstr(cli->tree)); \
75 #define CHECK_RDWR(fnum, correct) do { \
76 enum rdwr_mode m = check_rdwr(cli->tree, fnum); \
78 printf("(%s) Incorrect readwrite mode %s - expected %s\n", \
79 __location__, rdwr_string(m), rdwr_string(correct)); \
83 #define CHECK_TIME(t, field) do { \
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); \
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); \
100 #define CHECK_NTTIME(t, field) do { \
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; \
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); \
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); \
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); \
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); \
150 static BOOL
test_open(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
153 union smb_fileinfo finfo
;
154 const char *fname
= BASEDIR
"\\torture_open.txt";
156 int fnum
= -1, fnum2
;
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
);
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
);
251 smbcli_close(cli
->tree
, fnum
);
252 smbcli_unlink(cli
->tree
, fname
);
261 static BOOL
test_openx(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
264 union smb_fileinfo finfo
;
265 const char *fname
= BASEDIR
"\\torture_openx.txt";
267 int fnum
= -1, fnum2
;
274 NTSTATUS correct_status
;
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
);
308 d_printf("Failed to create file %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
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
);
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
);
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
));
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
);
446 smbcli_close(cli
->tree
, fnum
);
447 smbcli_unlink(cli
->tree
, fname
);
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
)
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";
472 NTSTATUS correct_status
;
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
);
490 d_printf("Failed to create file %s - %s\n", fname1
, smbcli_errstr(cli
->tree
));
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
;
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
);
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
);
553 /* windows appears to leak uninitialised memory here */
554 CHECK_VAL(io
.t2open
.out
.write_time
, 0);
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
);
600 smbcli_close(cli
->tree
, fnum
);
601 smbcli_unlink(cli
->tree
, fname
);
608 test RAW_OPEN_NTCREATEX
610 static BOOL
test_ntcreatex(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
613 union smb_fileinfo finfo
;
614 const char *fname
= BASEDIR
"\\torture_ntcreatex.txt";
615 const char *dname
= BASEDIR
"\\torture_ntcreatex.dir";
623 NTSTATUS correct_status
;
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
);
662 d_printf("Failed to create file %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
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
);
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
);
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
;
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
);
773 smbcli_close(cli
->tree
, fnum
);
774 smbcli_unlink(cli
->tree
, fname
);
781 test RAW_OPEN_NTTRANS_CREATE
783 static BOOL
test_nttrans_create(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
786 union smb_fileinfo finfo
;
787 const char *fname
= BASEDIR
"\\torture_ntcreatex.txt";
788 const char *dname
= BASEDIR
"\\torture_ntcreatex.dir";
796 NTSTATUS correct_status
;
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
);
837 d_printf("Failed to create file %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
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
);
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
);
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
;
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
);
948 smbcli_close(cli
->tree
, fnum
);
949 smbcli_unlink(cli
->tree
, fname
);
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
962 static BOOL
test_ntcreatex_brlocked(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
964 union smb_open io
, io1
;
966 struct smb_lock_entry lock
[1];
967 const char *fname
= BASEDIR
"\\torture_ntcreatex.txt";
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
;
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
);
1022 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.fnum
);
1023 smbcli_close(cli
->tree
, io1
.ntcreatex
.out
.fnum
);
1024 smbcli_unlink(cli
->tree
, fname
);
1031 static BOOL
test_mknew(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
1034 const char *fname
= BASEDIR
"\\torture_mknew.txt";
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
);
1076 smbcli_close(cli
->tree
, fnum
);
1077 smbcli_unlink(cli
->tree
, fname
);
1084 test RAW_OPEN_CREATE
1086 static BOOL
test_create(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
1089 const char *fname
= BASEDIR
"\\torture_create.txt";
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
);
1132 smbcli_close(cli
->tree
, fnum
);
1133 smbcli_unlink(cli
->tree
, fname
);
1142 static BOOL
test_ctemp(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
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
);
1173 smbcli_close(cli
->tree
, fnum
);
1175 smbcli_unlink(cli
->tree
, fname
);
1183 test chained RAW_OPEN_OPENX_READX
1185 static BOOL
test_chained(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
1188 const char *fname
= BASEDIR
"\\torture_chained.txt";
1192 const char *buf
= "test";
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");
1231 smbcli_close(cli
->tree
, fnum
);
1232 smbcli_unlink(cli
->tree
, fname
);
1238 /* basic testing of all RAW_OPEN_* calls
1240 BOOL
torture_raw_open(void)
1242 struct smbcli_state
*cli
;
1244 TALLOC_CTX
*mem_ctx
;
1246 if (!torture_open_connection(&cli
)) {
1250 mem_ctx
= talloc_init("torture_raw_open");
1252 if (!torture_setup_dir(cli
, BASEDIR
)) {
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
);