s4-smbtorture: Make test names lowercase and dot-separated.
[garming/samba-autobuild/.git] / source4 / torture / raw / open.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RAW_OPEN_* 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 "libcli/raw/libcliraw.h"
22 #include "system/time.h"
23 #include "system/filesys.h"
24 #include "lib/events/events.h"
25 #include "libcli/libcli.h"
26 #include "torture/util.h"
27
28 /* enum for whether reads/writes are possible on a file */
29 enum rdwr_mode {RDWR_NONE, RDWR_RDONLY, RDWR_WRONLY, RDWR_RDWR};
30
31 #define BASEDIR "\\rawopen"
32
33 /*
34   check if a open file can be read/written
35 */
36 static enum rdwr_mode check_rdwr(struct smbcli_tree *tree, int fnum)
37 {
38         uint8_t c = 1;
39         bool can_read  = (smbcli_read(tree, fnum, &c, 0, 1) == 1);
40         bool can_write = (smbcli_write(tree, fnum, 0, &c, 0, 1) == 1);
41         if ( can_read &&  can_write) return RDWR_RDWR;
42         if ( can_read && !can_write) return RDWR_RDONLY;
43         if (!can_read &&  can_write) return RDWR_WRONLY;
44         return RDWR_NONE;
45 }
46
47 /*
48   describe a RDWR mode as a string
49 */
50 static const char *rdwr_string(enum rdwr_mode m)
51 {
52         switch (m) {
53         case RDWR_NONE: return "NONE";
54         case RDWR_RDONLY: return "RDONLY";
55         case RDWR_WRONLY: return "WRONLY";
56         case RDWR_RDWR: return "RDWR";
57         }
58         return "-";
59 }
60
61 #define CHECK_STATUS(status, correct) do { \
62         if (!NT_STATUS_EQUAL(status, correct)) { \
63                 torture_result(tctx, TORTURE_FAIL, \
64                         "(%s) Incorrect status %s - should be %s\n", \
65                        __location__, nt_errstr(status), nt_errstr(correct)); \
66                 ret = false; \
67                 goto done; \
68         }} while (0)
69
70 #define CREATE_FILE do { \
71         fnum = create_complex_file(cli, tctx, fname); \
72         if (fnum == -1) { \
73                 torture_result(tctx, TORTURE_FAIL, \
74                         "(%s) Failed to create %s - %s\n", \
75                          __location__, fname, smbcli_errstr(cli->tree)); \
76                 ret = false; \
77                 goto done; \
78         }} while (0)
79
80 #define CHECK_RDWR(fnum, correct) do { \
81         enum rdwr_mode m = check_rdwr(cli->tree, fnum); \
82         if (m != correct) { \
83                 torture_result(tctx, TORTURE_FAIL, \
84                        "(%s) Incorrect readwrite mode %s - expected %s\n", \
85                        __location__, rdwr_string(m), rdwr_string(correct)); \
86                 ret = false; \
87         }} while (0)
88
89 #define CHECK_TIME(t, field) do { \
90         time_t t1, t2; \
91         finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
92         finfo.all_info.in.file.path = fname; \
93         status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
94         CHECK_STATUS(status, NT_STATUS_OK); \
95         t1 = t & ~1; \
96         t2 = nt_time_to_unix(finfo.all_info.out.field) & ~1; \
97         if (abs(t1-t2) > 2) { \
98                 torture_result(tctx, TORTURE_FAIL, \
99                        "(%s) wrong time for field %s  %s - %s\n", \
100                        __location__, #field, \
101                        timestring(tctx, t1), \
102                        timestring(tctx, t2)); \
103                 dump_all_info(tctx, &finfo); \
104                 ret = false; \
105         }} while (0)
106
107 #define CHECK_NTTIME(t, field) do { \
108         NTTIME t2; \
109         finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
110         finfo.all_info.in.file.path = fname; \
111         status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
112         CHECK_STATUS(status, NT_STATUS_OK); \
113         t2 = finfo.all_info.out.field; \
114         if (t != t2) { \
115                 torture_result(tctx, TORTURE_FAIL, \
116                        "(%s) wrong time for field %s  %s - %s\n", \
117                        __location__, #field, \
118                        nt_time_string(tctx, t), \
119                        nt_time_string(tctx, t2)); \
120                 dump_all_info(tctx, &finfo); \
121                 ret = false; \
122         }} while (0)
123
124 #define CHECK_ALL_INFO(v, field) do { \
125         finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
126         finfo.all_info.in.file.path = fname; \
127         status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
128         CHECK_STATUS(status, NT_STATUS_OK); \
129         if ((v) != (finfo.all_info.out.field)) { \
130                 torture_result(tctx, TORTURE_FAIL, \
131                        "(%s) wrong value for field %s  0x%x - 0x%x\n", \
132                        __location__, #field, (int)v, (int)(finfo.all_info.out.field)); \
133                 dump_all_info(tctx, &finfo); \
134                 ret = false; \
135         }} while (0)
136
137 #define CHECK_VAL(v, correct) do { \
138         if ((v) != (correct)) { \
139                 torture_result(tctx, TORTURE_FAIL, \
140                        "(%s) wrong value for %s  0x%x - should be 0x%x\n", \
141                        __location__, #v, (int)(v), (int)correct); \
142                 ret = false; \
143         }} while (0)
144
145 #define SET_ATTRIB(sattrib) do { \
146         union smb_setfileinfo sfinfo; \
147         ZERO_STRUCT(sfinfo.basic_info.in); \
148         sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION; \
149         sfinfo.basic_info.in.file.path = fname; \
150         sfinfo.basic_info.in.attrib = sattrib; \
151         status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
152         if (!NT_STATUS_IS_OK(status)) { \
153                 torture_warning(tctx, "(%s) Failed to set attrib 0x%x on %s\n", \
154                        __location__, sattrib, fname); \
155         }} while (0)
156
157 /*
158   test RAW_OPEN_OPEN
159 */
160 static bool test_open(struct torture_context *tctx, struct smbcli_state *cli)
161 {
162         union smb_open io;
163         union smb_fileinfo finfo;
164         const char *fname = BASEDIR "\\torture_open.txt";
165         NTSTATUS status;
166         int fnum = -1, fnum2;
167         bool ret = true;
168
169         if (!torture_setup_dir(cli, BASEDIR)) {
170                 return false;
171         }
172
173         io.openold.level = RAW_OPEN_OPEN;
174         io.openold.in.fname = fname;
175         io.openold.in.open_mode = OPEN_FLAGS_FCB;
176         io.openold.in.search_attrs = 0;
177         status = smb_raw_open(cli->tree, tctx, &io);
178         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
179         fnum = io.openold.out.file.fnum;
180
181         smbcli_unlink(cli->tree, fname);
182         CREATE_FILE;
183         smbcli_close(cli->tree, fnum);
184
185         status = smb_raw_open(cli->tree, tctx, &io);
186         CHECK_STATUS(status, NT_STATUS_OK);
187         fnum = io.openold.out.file.fnum;
188         CHECK_RDWR(fnum, RDWR_RDWR);
189
190         status = smb_raw_open(cli->tree, tctx, &io);
191         CHECK_STATUS(status, NT_STATUS_OK);
192         fnum2 = io.openold.out.file.fnum;
193         CHECK_RDWR(fnum2, RDWR_RDWR);
194         smbcli_close(cli->tree, fnum2);
195         smbcli_close(cli->tree, fnum);
196
197         /* check the read/write modes */
198         io.openold.level = RAW_OPEN_OPEN;
199         io.openold.in.fname = fname;
200         io.openold.in.search_attrs = 0;
201
202         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
203         status = smb_raw_open(cli->tree, tctx, &io);
204         CHECK_STATUS(status, NT_STATUS_OK);
205         fnum = io.openold.out.file.fnum;
206         CHECK_RDWR(fnum, RDWR_RDONLY);
207         smbcli_close(cli->tree, fnum);
208
209         io.openold.in.open_mode = OPEN_FLAGS_OPEN_WRITE;
210         status = smb_raw_open(cli->tree, tctx, &io);
211         CHECK_STATUS(status, NT_STATUS_OK);
212         fnum = io.openold.out.file.fnum;
213         CHECK_RDWR(fnum, RDWR_WRONLY);
214         smbcli_close(cli->tree, fnum);
215
216         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR;
217         status = smb_raw_open(cli->tree, tctx, &io);
218         CHECK_STATUS(status, NT_STATUS_OK);
219         fnum = io.openold.out.file.fnum;
220         CHECK_RDWR(fnum, RDWR_RDWR);
221         smbcli_close(cli->tree, fnum);
222
223         /* check the share modes roughly - not a complete matrix */
224         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_WRITE;
225         status = smb_raw_open(cli->tree, tctx, &io);
226         CHECK_STATUS(status, NT_STATUS_OK);
227         fnum = io.openold.out.file.fnum;
228         CHECK_RDWR(fnum, RDWR_RDWR);
229         
230         if (io.openold.in.open_mode != io.openold.out.rmode) {
231                 torture_warning(tctx, "(%s) rmode should equal open_mode - 0x%x 0x%x\n",
232                        __location__, io.openold.out.rmode, io.openold.in.open_mode);
233         }
234
235         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_NONE;
236         status = smb_raw_open(cli->tree, tctx, &io);
237         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
238
239         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ | OPEN_FLAGS_DENY_NONE;
240         status = smb_raw_open(cli->tree, tctx, &io);
241         CHECK_STATUS(status, NT_STATUS_OK);
242         fnum2 = io.openold.out.file.fnum;
243         CHECK_RDWR(fnum2, RDWR_RDONLY);
244         smbcli_close(cli->tree, fnum);
245         smbcli_close(cli->tree, fnum2);
246
247
248         /* check the returned write time */
249         io.openold.level = RAW_OPEN_OPEN;
250         io.openold.in.fname = fname;
251         io.openold.in.search_attrs = 0;
252         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
253         status = smb_raw_open(cli->tree, tctx, &io);
254         CHECK_STATUS(status, NT_STATUS_OK);
255         fnum = io.openold.out.file.fnum;
256
257         /* check other reply fields */
258         CHECK_TIME(io.openold.out.write_time, write_time);
259         CHECK_ALL_INFO(io.openold.out.size, size);
260         CHECK_ALL_INFO(io.openold.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
261
262 done:
263         smbcli_close(cli->tree, fnum);
264         smbcli_deltree(cli->tree, BASEDIR);
265
266         return ret;
267 }
268
269
270 /*
271   test RAW_OPEN_OPENX
272 */
273 static bool test_openx(struct torture_context *tctx, struct smbcli_state *cli)
274 {
275         union smb_open io;
276         union smb_fileinfo finfo;
277         const char *fname = BASEDIR "\\torture_openx.txt";
278         const char *fname_exe = BASEDIR "\\torture_openx.exe";
279         NTSTATUS status;
280         int fnum = -1, fnum2;
281         bool ret = true;
282         int i;
283         struct timeval tv;
284         struct {
285                 uint16_t open_func;
286                 bool with_file;
287                 NTSTATUS correct_status;
288         } open_funcs[] = {
289                 { OPENX_OPEN_FUNC_OPEN,                           true,  NT_STATUS_OK },
290                 { OPENX_OPEN_FUNC_OPEN,                           false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
291                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
292                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
293                 { OPENX_OPEN_FUNC_FAIL,                           true,  NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
294                 { OPENX_OPEN_FUNC_FAIL,                           false, NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
295                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OBJECT_NAME_COLLISION },
296                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
297                 { OPENX_OPEN_FUNC_TRUNC,                          true,  NT_STATUS_OK },
298                 { OPENX_OPEN_FUNC_TRUNC,                          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
299                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
300                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
301         };
302
303         if (!torture_setup_dir(cli, BASEDIR)) {
304                 return false;
305         }
306
307         io.openx.level = RAW_OPEN_OPENX;
308         io.openx.in.fname = fname;
309         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
310         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
311         io.openx.in.search_attrs = 0;
312         io.openx.in.file_attrs = 0;
313         io.openx.in.write_time = 0;
314         io.openx.in.size = 1024*1024;
315         io.openx.in.timeout = 0;
316
317         /* check all combinations of open_func */
318         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
319                 if (open_funcs[i].with_file) {
320                         fnum = create_complex_file(cli, tctx, fname);
321                         if (fnum == -1) {
322                                 torture_result(tctx, TORTURE_FAIL,
323                                         "Failed to create file %s - %s\n",
324                                         fname, smbcli_errstr(cli->tree));
325                                 ret = false;
326                                 goto done;
327                         }
328                         smbcli_close(cli->tree, fnum);
329                 }
330                 io.openx.in.open_func = open_funcs[i].open_func;
331                 status = smb_raw_open(cli->tree, tctx, &io);
332                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
333                         torture_result(tctx, TORTURE_FAIL,
334                                 "(%s) incorrect status %s should be %s "
335                                 "(i=%d with_file=%d open_func=0x%x)\n",
336                                 __location__, nt_errstr(status),
337                                 nt_errstr(open_funcs[i].correct_status),
338                                 i, (int)open_funcs[i].with_file,
339                                 (int)open_funcs[i].open_func);
340                         ret = false;
341                 }
342                 if (NT_STATUS_IS_OK(status)) {
343                         smbcli_close(cli->tree, io.openx.out.file.fnum);
344                 }
345                 if (open_funcs[i].with_file) {
346                         smbcli_unlink(cli->tree, fname);
347                 }
348         }
349
350         smbcli_unlink(cli->tree, fname);
351
352         /* check the basic return fields */
353         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
354         status = smb_raw_open(cli->tree, tctx, &io);
355         CHECK_STATUS(status, NT_STATUS_OK);
356         fnum = io.openx.out.file.fnum;
357
358         CHECK_ALL_INFO(io.openx.out.size, size);
359         CHECK_TIME(io.openx.out.write_time, write_time);
360         CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
361         CHECK_VAL(io.openx.out.access, OPENX_MODE_ACCESS_RDWR);
362         CHECK_VAL(io.openx.out.ftype, 0);
363         CHECK_VAL(io.openx.out.devstate, 0);
364         CHECK_VAL(io.openx.out.action, OPENX_ACTION_CREATED);
365         CHECK_VAL(io.openx.out.size, 1024*1024);
366         CHECK_ALL_INFO(io.openx.in.size, size);
367         smbcli_close(cli->tree, fnum);
368         smbcli_unlink(cli->tree, fname);
369
370         /* check the fields when the file already existed */
371         fnum2 = create_complex_file(cli, tctx, fname);
372         if (fnum2 == -1) {
373                 ret = false;
374                 goto done;
375         }
376         smbcli_close(cli->tree, fnum2);
377
378         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
379         status = smb_raw_open(cli->tree, tctx, &io);
380         CHECK_STATUS(status, NT_STATUS_OK);
381         fnum = io.openx.out.file.fnum;
382
383         CHECK_ALL_INFO(io.openx.out.size, size);
384         CHECK_TIME(io.openx.out.write_time, write_time);
385         CHECK_VAL(io.openx.out.action, OPENX_ACTION_EXISTED);
386         CHECK_VAL(io.openx.out.unknown, 0);
387         CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
388         smbcli_close(cli->tree, fnum);
389
390         /* now check the search attrib for hidden files - win2003 ignores this? */
391         SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
392         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
393
394         io.openx.in.search_attrs = FILE_ATTRIBUTE_HIDDEN;
395         status = smb_raw_open(cli->tree, tctx, &io);
396         CHECK_STATUS(status, NT_STATUS_OK);
397         smbcli_close(cli->tree, io.openx.out.file.fnum);
398
399         io.openx.in.search_attrs = 0;
400         status = smb_raw_open(cli->tree, tctx, &io);
401         CHECK_STATUS(status, NT_STATUS_OK);
402         smbcli_close(cli->tree, io.openx.out.file.fnum);
403
404         SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
405         smbcli_unlink(cli->tree, fname);
406
407         /* and check attrib on create */
408         io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
409         io.openx.in.search_attrs = 0;
410         io.openx.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
411         status = smb_raw_open(cli->tree, tctx, &io);
412         CHECK_STATUS(status, NT_STATUS_OK);
413         if (torture_setting_bool(tctx, "samba3", false)) {
414                 CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE, 
415                                attrib & ~(FILE_ATTRIBUTE_NONINDEXED|
416                                           FILE_ATTRIBUTE_SPARSE));
417         }
418         else {
419                 CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE, 
420                                attrib & ~(FILE_ATTRIBUTE_NONINDEXED));
421         }
422         smbcli_close(cli->tree, io.openx.out.file.fnum);
423         smbcli_unlink(cli->tree, fname);
424
425         /* check timeout on create - win2003 ignores the timeout! */
426         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
427         io.openx.in.file_attrs = 0;
428         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
429         status = smb_raw_open(cli->tree, tctx, &io);
430         CHECK_STATUS(status, NT_STATUS_OK);
431         fnum = io.openx.out.file.fnum;
432
433         io.openx.in.timeout = 20000;
434         tv = timeval_current();
435         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_NONE;
436         status = smb_raw_open(cli->tree, tctx, &io);
437         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
438         if (timeval_elapsed(&tv) > 3.0) {
439                 torture_result(tctx, TORTURE_FAIL,
440                         "(%s) Incorrect timing in openx with timeout "
441                         "- waited %.2f seconds\n",
442                         __location__, timeval_elapsed(&tv));
443                 ret = false;
444         }
445         smbcli_close(cli->tree, fnum);
446         smbcli_unlink(cli->tree, fname);
447
448         /* now this is a really weird one - open for execute implies create?! */
449         io.openx.in.fname = fname;
450         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
451         io.openx.in.open_mode = OPENX_MODE_ACCESS_EXEC | OPENX_MODE_DENY_NONE;
452         io.openx.in.search_attrs = 0;
453         io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL;
454         io.openx.in.file_attrs = 0;
455         io.openx.in.write_time = 0;
456         io.openx.in.size = 0;
457         io.openx.in.timeout = 0;
458         status = smb_raw_open(cli->tree, tctx, &io);
459         CHECK_STATUS(status, NT_STATUS_OK);
460         smbcli_close(cli->tree, io.openx.out.file.fnum);
461
462         /* check the extended return flag */
463         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO | OPENX_FLAGS_EXTENDED_RETURN;
464         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
465         status = smb_raw_open(cli->tree, tctx, &io);
466         CHECK_STATUS(status, NT_STATUS_OK);
467         CHECK_VAL(io.openx.out.access_mask, SEC_STD_ALL);
468         smbcli_close(cli->tree, io.openx.out.file.fnum);
469
470         io.openx.in.fname = "\\A.+,;=[].B";
471         status = smb_raw_open(cli->tree, tctx, &io);
472         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
473
474         /* Check the mapping for open exec. */
475
476         /* First create an .exe file. */
477         smbcli_unlink(cli->tree, fname_exe);
478         fnum = create_complex_file(cli, tctx, fname_exe);
479         smbcli_close(cli->tree, fnum);
480
481         io.openx.level = RAW_OPEN_OPENX;
482         io.openx.in.fname = fname_exe;
483         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
484         io.openx.in.open_mode = OPENX_MODE_ACCESS_EXEC | OPENX_MODE_DENY_NONE;
485         io.openx.in.search_attrs = 0;
486         io.openx.in.file_attrs = 0;
487         io.openx.in.write_time = 0;
488         io.openx.in.size = 0;
489         io.openx.in.timeout = 0;
490         status = smb_raw_open(cli->tree, tctx, &io);
491         CHECK_STATUS(status, NT_STATUS_OK);
492
493         /* Can we read and write ? */
494         CHECK_RDWR(io.openx.out.file.fnum, RDWR_RDONLY);
495         smbcli_close(cli->tree, io.openx.out.file.fnum);
496         smbcli_unlink(cli->tree, fname);
497
498 done:
499         smbcli_close(cli->tree, fnum);
500         smbcli_deltree(cli->tree, BASEDIR);
501
502         return ret;
503 }
504
505
506 /*
507   test RAW_OPEN_T2OPEN
508
509   many thanks to kukks for a sniff showing how this works with os2->w2k
510 */
511 static bool test_t2open(struct torture_context *tctx, struct smbcli_state *cli)
512 {
513         union smb_open io;
514         union smb_fileinfo finfo;
515         const char *fname1 = BASEDIR "\\torture_t2open_yes.txt";
516         const char *fname2 = BASEDIR "\\torture_t2open_no.txt";
517         const char *fname = BASEDIR "\\torture_t2open_3.txt";
518         NTSTATUS status;
519         int fnum;
520         bool ret = true;
521         int i;
522         struct {
523                 uint16_t open_func;
524                 bool with_file;
525                 NTSTATUS correct_status;
526         } open_funcs[] = {
527                 { OPENX_OPEN_FUNC_OPEN,                           true,  NT_STATUS_OK },
528                 { OPENX_OPEN_FUNC_OPEN,                           false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
529                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
530                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
531                 { OPENX_OPEN_FUNC_FAIL,                           true,  NT_STATUS_OBJECT_NAME_COLLISION },
532                 { OPENX_OPEN_FUNC_FAIL,                           false, NT_STATUS_OBJECT_NAME_COLLISION },
533                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OBJECT_NAME_COLLISION },
534                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OBJECT_NAME_COLLISION },
535                 { OPENX_OPEN_FUNC_TRUNC,                          true,  NT_STATUS_OK },
536                 { OPENX_OPEN_FUNC_TRUNC,                          false, NT_STATUS_OK },
537                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
538                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
539         };
540
541         if (!torture_setup_dir(cli, BASEDIR)) {
542                 return false;
543         }
544
545         fnum = create_complex_file(cli, tctx, fname1);
546         if (fnum == -1) {
547                 torture_result(tctx, TORTURE_FAIL,
548                         "(%s): Failed to create file %s - %s\n",
549                         __location__, fname1, smbcli_errstr(cli->tree));
550                 ret = false;
551                 goto done;
552         }
553         smbcli_close(cli->tree, fnum);
554
555         io.t2open.level = RAW_OPEN_T2OPEN;
556         io.t2open.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
557         io.t2open.in.open_mode = OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR;
558         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
559         io.t2open.in.search_attrs = 0;
560         io.t2open.in.file_attrs = 0;
561         io.t2open.in.write_time = 0;
562         io.t2open.in.size = 0;
563         io.t2open.in.timeout = 0;
564
565         io.t2open.in.num_eas = 3;
566         io.t2open.in.eas = talloc_array(tctx, struct ea_struct, io.t2open.in.num_eas);
567         io.t2open.in.eas[0].flags = 0;
568         io.t2open.in.eas[0].name.s = ".CLASSINFO";
569         io.t2open.in.eas[0].value = data_blob_talloc(tctx, "first value", 11);
570         io.t2open.in.eas[1].flags = 0;
571         io.t2open.in.eas[1].name.s = "EA TWO";
572         io.t2open.in.eas[1].value = data_blob_talloc(tctx, "foo", 3);
573         io.t2open.in.eas[2].flags = 0;
574         io.t2open.in.eas[2].name.s = "X THIRD";
575         io.t2open.in.eas[2].value = data_blob_talloc(tctx, "xy", 2);
576
577         /* check all combinations of open_func */
578         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
579         again:
580                 if (open_funcs[i].with_file) {
581                         io.t2open.in.fname = fname1;
582                 } else {
583                         io.t2open.in.fname = fname2;
584                 }
585                 io.t2open.in.open_func = open_funcs[i].open_func;
586                 status = smb_raw_open(cli->tree, tctx, &io);
587                 if ((io.t2open.in.num_eas != 0)
588                     && NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
589                     && torture_setting_bool(tctx, "samba3", false)) {
590                         torture_warning(tctx, "(%s) EAs not supported, not "
591                                 "treating as fatal in Samba3 test\n",
592                                 __location__);
593                         io.t2open.in.num_eas = 0;
594                         goto again;
595                 }
596
597                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
598                         torture_result(tctx, TORTURE_FAIL,
599                                 "(%s) incorrect status %s should be %s "
600                                 "(i=%d with_file=%d open_func=0x%x)\n",
601                                  __location__, nt_errstr(status),
602                                 nt_errstr(open_funcs[i].correct_status),
603                                 i, (int)open_funcs[i].with_file,
604                                 (int)open_funcs[i].open_func);
605                         ret = false;
606                 }
607                 if (NT_STATUS_IS_OK(status)) {
608                         smbcli_close(cli->tree, io.t2open.out.file.fnum);
609                 }
610         }
611
612         smbcli_unlink(cli->tree, fname1);
613         smbcli_unlink(cli->tree, fname2);
614
615         /* check the basic return fields */
616         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
617         io.t2open.in.write_time = 0;
618         io.t2open.in.fname = fname;
619         status = smb_raw_open(cli->tree, tctx, &io);
620         CHECK_STATUS(status, NT_STATUS_OK);
621         fnum = io.t2open.out.file.fnum;
622
623         CHECK_ALL_INFO(io.t2open.out.size, size);
624 #if 0
625         /* windows appears to leak uninitialised memory here */
626         CHECK_VAL(io.t2open.out.write_time, 0);
627 #endif
628         CHECK_ALL_INFO(io.t2open.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
629         CHECK_VAL(io.t2open.out.access, OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR);
630         CHECK_VAL(io.t2open.out.ftype, 0);
631         CHECK_VAL(io.t2open.out.devstate, 0);
632         CHECK_VAL(io.t2open.out.action, OPENX_ACTION_CREATED);
633         smbcli_close(cli->tree, fnum);
634
635         status = torture_check_ea(cli, fname, ".CLASSINFO", "first value");
636         CHECK_STATUS(status, io.t2open.in.num_eas
637                      ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
638         status = torture_check_ea(cli, fname, "EA TWO", "foo");
639         CHECK_STATUS(status, io.t2open.in.num_eas
640                      ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
641         status = torture_check_ea(cli, fname, "X THIRD", "xy");
642         CHECK_STATUS(status, io.t2open.in.num_eas
643                      ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
644
645         /* now check the search attrib for hidden files - win2003 ignores this? */
646         SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
647         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
648
649         status = smb_raw_open(cli->tree, tctx, &io);
650         CHECK_STATUS(status, NT_STATUS_OK);
651         smbcli_close(cli->tree, io.t2open.out.file.fnum);
652
653         status = smb_raw_open(cli->tree, tctx, &io);
654         CHECK_STATUS(status, NT_STATUS_OK);
655         smbcli_close(cli->tree, io.t2open.out.file.fnum);
656
657         SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
658         smbcli_unlink(cli->tree, fname);
659
660         /* and check attrib on create */
661         io.t2open.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
662         io.t2open.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
663         status = smb_raw_open(cli->tree, tctx, &io);
664         CHECK_STATUS(status, NT_STATUS_OK);
665
666         /* check timeout on create - win2003 ignores the timeout! */
667         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
668         io.t2open.in.file_attrs = 0;
669         io.t2open.in.timeout = 20000;
670         io.t2open.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
671         status = smb_raw_open(cli->tree, tctx, &io);
672         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
673
674 done:
675         smbcli_close(cli->tree, fnum);
676         smbcli_deltree(cli->tree, BASEDIR);
677
678         return ret;
679 }
680         
681
682 /*
683   test RAW_OPEN_NTCREATEX
684 */
685 static bool test_ntcreatex(struct torture_context *tctx, struct smbcli_state *cli)
686 {
687         union smb_open io;
688         union smb_fileinfo finfo;
689         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
690         const char *dname = BASEDIR "\\torture_ntcreatex.dir";
691         NTSTATUS status;
692         int fnum = -1;
693         bool ret = true;
694         int i;
695         struct {
696                 uint32_t open_disp;
697                 bool with_file;
698                 NTSTATUS correct_status;
699         } open_funcs[] = {
700                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
701                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
702                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
703                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
704                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
705                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
706                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
707                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
708                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
709                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
710                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
711                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
712                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
713                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
714         };
715
716         if (!torture_setup_dir(cli, BASEDIR)) {
717                 return false;
718         }
719
720         /* reasonable default parameters */
721         io.generic.level = RAW_OPEN_NTCREATEX;
722         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
723         io.ntcreatex.in.root_fid.fnum = 0;
724         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
725         io.ntcreatex.in.alloc_size = 1024*1024;
726         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
727         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
728         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
729         io.ntcreatex.in.create_options = 0;
730         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
731         io.ntcreatex.in.security_flags = 0;
732         io.ntcreatex.in.fname = fname;
733
734         /* test the open disposition */
735         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
736                 if (open_funcs[i].with_file) {
737                         fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
738                         if (fnum == -1) {
739                                 torture_result(tctx, TORTURE_FAIL,
740                                         "Failed to create file %s - %s\n",
741                                         fname, smbcli_errstr(cli->tree));
742                                 ret = false;
743                                 goto done;
744                         }
745                         smbcli_close(cli->tree, fnum);
746                 }
747                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
748                 status = smb_raw_open(cli->tree, tctx, &io);
749                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
750                         torture_result(tctx, TORTURE_FAIL,
751                                 "(%s) incorrect status %s should be %s "
752                                 "(i=%d with_file=%d open_disp=%d)\n",
753                                 __location__, nt_errstr(status),
754                                 nt_errstr(open_funcs[i].correct_status),
755                                 i, (int)open_funcs[i].with_file,
756                                 (int)open_funcs[i].open_disp);
757                         ret = false;
758                 }
759                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
760                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
761                         smbcli_unlink(cli->tree, fname);
762                 }
763         }
764
765         /* basic field testing */
766         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
767
768         status = smb_raw_open(cli->tree, tctx, &io);
769         CHECK_STATUS(status, NT_STATUS_OK);
770         fnum = io.ntcreatex.out.file.fnum;
771
772         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
773         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
774         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
775         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
776         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
777         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
778         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
779         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
780         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
781         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
782         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
783
784         /* check fields when the file already existed */
785         smbcli_close(cli->tree, fnum);
786         smbcli_unlink(cli->tree, fname);
787         fnum = create_complex_file(cli, tctx, fname);
788         if (fnum == -1) {
789                 ret = false;
790                 goto done;
791         }
792         smbcli_close(cli->tree, fnum);
793
794         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
795         status = smb_raw_open(cli->tree, tctx, &io);
796         CHECK_STATUS(status, NT_STATUS_OK);
797         fnum = io.ntcreatex.out.file.fnum;
798
799         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
800         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
801         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
802         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
803         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
804         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
805         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
806         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
807         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
808         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
809         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
810         smbcli_close(cli->tree, fnum);
811         smbcli_unlink(cli->tree, fname);
812
813
814         /* create a directory */
815         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
816         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
817         io.ntcreatex.in.alloc_size = 0;
818         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
819         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
820         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
821         io.ntcreatex.in.create_options = 0;
822         io.ntcreatex.in.fname = dname;
823         fname = dname;
824
825         smbcli_rmdir(cli->tree, fname);
826         smbcli_unlink(cli->tree, fname);
827
828         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
829         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
830         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
831         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
832         status = smb_raw_open(cli->tree, tctx, &io);
833         CHECK_STATUS(status, NT_STATUS_OK);
834         fnum = io.ntcreatex.out.file.fnum;
835
836         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
837         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
838         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
839         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
840         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
841         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
842         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
843         CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED, 
844                   FILE_ATTRIBUTE_DIRECTORY);
845         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
846         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
847         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
848         CHECK_VAL(io.ntcreatex.out.is_directory, 1);
849         CHECK_VAL(io.ntcreatex.out.size, 0);
850         CHECK_VAL(io.ntcreatex.out.alloc_size, 0);
851         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
852         smbcli_unlink(cli->tree, fname);
853         
854
855 done:
856         smbcli_close(cli->tree, fnum);
857         smbcli_deltree(cli->tree, BASEDIR);
858
859         return ret;
860 }
861
862
863 /*
864   test RAW_OPEN_NTTRANS_CREATE
865 */
866 static bool test_nttrans_create(struct torture_context *tctx, struct smbcli_state *cli)
867 {
868         union smb_open io;
869         union smb_fileinfo finfo;
870         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
871         const char *dname = BASEDIR "\\torture_ntcreatex.dir";
872         NTSTATUS status;
873         int fnum = -1;
874         bool ret = true;
875         int i;
876         uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
877         uint32_t not_a_directory_mask, unexpected_mask;
878         struct {
879                 uint32_t open_disp;
880                 bool with_file;
881                 NTSTATUS correct_status;
882         } open_funcs[] = {
883                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
884                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
885                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
886                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
887                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
888                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
889                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
890                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
891                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
892                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
893                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
894                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
895                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
896                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
897         };
898
899         if (!torture_setup_dir(cli, BASEDIR)) {
900                 return false;
901         }
902
903         /* reasonable default parameters */
904         io.generic.level = RAW_OPEN_NTTRANS_CREATE;
905         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
906         io.ntcreatex.in.root_fid.fnum = 0;
907         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
908         io.ntcreatex.in.alloc_size = 1024*1024;
909         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
910         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
911         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
912         io.ntcreatex.in.create_options = 0;
913         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
914         io.ntcreatex.in.security_flags = 0;
915         io.ntcreatex.in.fname = fname;
916         io.ntcreatex.in.sec_desc = NULL;
917         io.ntcreatex.in.ea_list = NULL;
918
919         /* test the open disposition */
920         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
921                 if (open_funcs[i].with_file) {
922                         fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
923                         if (fnum == -1) {
924                                 torture_result(tctx, TORTURE_FAIL,
925                                         "Failed to create file %s - %s\n",
926                                         fname, smbcli_errstr(cli->tree));
927                                 ret = false;
928                                 goto done;
929                         }
930                         smbcli_close(cli->tree, fnum);
931                 }
932                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
933                 status = smb_raw_open(cli->tree, tctx, &io);
934                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
935                         torture_result(tctx, TORTURE_FAIL,
936                                 "(%s) incorrect status %s should be %s "
937                                 "(i=%d with_file=%d open_disp=%d)\n",
938                                 __location__, nt_errstr(status),
939                                 nt_errstr(open_funcs[i].correct_status),
940                                 i, (int)open_funcs[i].with_file,
941                                 (int)open_funcs[i].open_disp);
942                         ret = false;
943                 }
944                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
945                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
946                         smbcli_unlink(cli->tree, fname);
947                 }
948         }
949
950         /* basic field testing */
951         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
952
953         status = smb_raw_open(cli->tree, tctx, &io);
954         CHECK_STATUS(status, NT_STATUS_OK);
955         fnum = io.ntcreatex.out.file.fnum;
956
957         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
958         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
959         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
960         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
961         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
962         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
963         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
964         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
965         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
966         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
967         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
968
969         /* check fields when the file already existed */
970         smbcli_close(cli->tree, fnum);
971         smbcli_unlink(cli->tree, fname);
972         fnum = create_complex_file(cli, tctx, fname);
973         if (fnum == -1) {
974                 ret = false;
975                 goto done;
976         }
977         smbcli_close(cli->tree, fnum);
978
979         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
980         status = smb_raw_open(cli->tree, tctx, &io);
981         CHECK_STATUS(status, NT_STATUS_OK);
982         fnum = io.ntcreatex.out.file.fnum;
983
984         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
985         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
986         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
987         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
988         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
989         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
990         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
991         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
992         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
993         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
994         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
995         smbcli_close(cli->tree, fnum);
996
997         /* check no-recall - don't pull a file from tape on a HSM */
998         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NO_RECALL;
999         status = smb_raw_open(cli->tree, tctx, &io);
1000         CHECK_STATUS(status, NT_STATUS_OK);
1001         fnum = io.ntcreatex.out.file.fnum;
1002
1003         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1004         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
1005         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
1006         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
1007         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
1008         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
1009         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1010         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
1011         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
1012         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
1013         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
1014         smbcli_close(cli->tree, fnum);
1015
1016         /* Check some create options (these all should be ignored) */
1017         for (i=0; i < 32; i++) {
1018                 uint32_t create_option = (1 << i) & NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
1019                 if (create_option == 0) {
1020                         continue;
1021                 }
1022                 io.ntcreatex.in.create_options = create_option;
1023                 status = smb_raw_open(cli->tree, tctx, &io);
1024                 if (!NT_STATUS_IS_OK(status)) {
1025                         torture_warning(tctx, "ntcreatex create option 0x%08x "
1026                                 "gave %s - should give NT_STATUS_OK\n",
1027                                 create_option, nt_errstr(status));
1028                 }
1029                 CHECK_STATUS(status, NT_STATUS_OK);
1030                 fnum = io.ntcreatex.out.file.fnum;
1031
1032                 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1033                 CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
1034                 CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
1035                 CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
1036                 CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
1037                 CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
1038                 CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1039                 CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
1040                 CHECK_ALL_INFO(io.ntcreatex.out.size, size);
1041                 CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
1042                 CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
1043                 smbcli_close(cli->tree, fnum);
1044         }
1045
1046         io.ntcreatex.in.file_attr = 0;
1047         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1048         io.ntcreatex.in.access_mask     = SEC_FLAG_MAXIMUM_ALLOWED;
1049
1050         /* Check for options that should return NOT_SUPPORTED, OK or INVALID_PARAMETER */
1051         ok_mask = 0;
1052         not_supported_mask = 0;
1053         invalid_parameter_mask = 0;
1054         not_a_directory_mask = 0;
1055         unexpected_mask = 0;
1056         for (i=0; i < 32; i++) {
1057                 uint32_t create_option = 1<<i;
1058                 if (create_option & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
1059                         continue;
1060                 }
1061                 io.ntcreatex.in.create_options = create_option;
1062                 status = smb_raw_open(cli->tree, tctx, &io);
1063                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1064                         not_supported_mask |= create_option;
1065                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1066                         ok_mask |= create_option;
1067                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1068                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1069                         invalid_parameter_mask |= create_option;
1070                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
1071                         not_a_directory_mask |= 1<<i;
1072                 } else {
1073                         unexpected_mask |= 1<<i;
1074                         torture_comment(tctx, "create option 0x%08x returned %s\n",
1075                                         create_option, nt_errstr(status));
1076                 }
1077         }
1078
1079         CHECK_VAL(ok_mask,                0x00efcfce);
1080         CHECK_VAL(not_a_directory_mask,   0x00000001);
1081         CHECK_VAL(not_supported_mask,     0x00002000);
1082         CHECK_VAL(invalid_parameter_mask, 0xff100030);
1083         CHECK_VAL(unexpected_mask,        0x00000000);
1084
1085         smbcli_unlink(cli->tree, fname);
1086
1087
1088         /* create a directory */
1089         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1090         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1091         io.ntcreatex.in.alloc_size = 0;
1092         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1093         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1094         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1095         io.ntcreatex.in.create_options = 0;
1096         io.ntcreatex.in.fname = dname;
1097         fname = dname;
1098
1099         smbcli_rmdir(cli->tree, fname);
1100         smbcli_unlink(cli->tree, fname);
1101
1102         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1103         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1104         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1105         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1106         status = smb_raw_open(cli->tree, tctx, &io);
1107         CHECK_STATUS(status, NT_STATUS_OK);
1108         fnum = io.ntcreatex.out.file.fnum;
1109
1110         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1111         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
1112         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
1113         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
1114         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
1115         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
1116         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1117         CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED, 
1118                   FILE_ATTRIBUTE_DIRECTORY);
1119         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
1120         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
1121         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
1122         CHECK_VAL(io.ntcreatex.out.is_directory, 1);
1123         CHECK_VAL(io.ntcreatex.out.size, 0);
1124         CHECK_VAL(io.ntcreatex.out.alloc_size, 0);
1125         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
1126         smbcli_unlink(cli->tree, fname);
1127         
1128
1129 done:
1130         smbcli_close(cli->tree, fnum);
1131         smbcli_deltree(cli->tree, BASEDIR);
1132
1133         return ret;
1134 }
1135
1136 /*
1137   test RAW_OPEN_NTCREATEX with an already opened and byte range locked file
1138
1139   I've got an application that does a similar sequence of ntcreate&x,
1140   locking&x and another ntcreate&x with
1141   open_disposition==NTCREATEX_DISP_OVERWRITE_IF. Windows 2003 allows the
1142   second open.
1143 */
1144 static bool test_ntcreatex_brlocked(struct torture_context *tctx, struct smbcli_state *cli)
1145 {
1146         union smb_open io, io1;
1147         union smb_lock io2;
1148         struct smb_lock_entry lock[1];
1149         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
1150         NTSTATUS status;
1151         bool ret = true;
1152
1153         if (!torture_setup_dir(cli, BASEDIR)) {
1154                 return false;
1155         }
1156
1157         torture_comment(tctx, "Testing ntcreatex with a byte range locked file\n");
1158
1159         io.generic.level = RAW_OPEN_NTCREATEX;
1160         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1161         io.ntcreatex.in.root_fid.fnum = 0;
1162         io.ntcreatex.in.access_mask = 0x2019f;
1163         io.ntcreatex.in.alloc_size = 0;
1164         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1165         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1166                 NTCREATEX_SHARE_ACCESS_WRITE;
1167         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1168         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
1169         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1170         io.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
1171                 NTCREATEX_SECURITY_ALL;
1172         io.ntcreatex.in.fname = fname;
1173
1174         status = smb_raw_open(cli->tree, tctx, &io);
1175         CHECK_STATUS(status, NT_STATUS_OK);
1176
1177         io2.lockx.level = RAW_LOCK_LOCKX;
1178         io2.lockx.in.file.fnum = io.ntcreatex.out.file.fnum;
1179         io2.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
1180         io2.lockx.in.timeout = 0;
1181         io2.lockx.in.ulock_cnt = 0;
1182         io2.lockx.in.lock_cnt = 1;
1183         lock[0].pid = cli->session->pid;
1184         lock[0].offset = 0;
1185         lock[0].count = 0x1;
1186         io2.lockx.in.locks = &lock[0];
1187         status = smb_raw_lock(cli->tree, &io2);
1188         CHECK_STATUS(status, NT_STATUS_OK);
1189
1190         io1.generic.level = RAW_OPEN_NTCREATEX;
1191         io1.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1192         io1.ntcreatex.in.root_fid.fnum = 0;
1193         io1.ntcreatex.in.access_mask = 0x20196;
1194         io1.ntcreatex.in.alloc_size = 0;
1195         io1.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1196         io1.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1197                 NTCREATEX_SHARE_ACCESS_WRITE;
1198         io1.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1199         io1.ntcreatex.in.create_options = 0;
1200         io1.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1201         io1.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
1202                 NTCREATEX_SECURITY_ALL;
1203         io1.ntcreatex.in.fname = fname;
1204
1205         status = smb_raw_open(cli->tree, tctx, &io1);
1206         CHECK_STATUS(status, NT_STATUS_OK);
1207
1208  done:
1209         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1210         smbcli_close(cli->tree, io1.ntcreatex.out.file.fnum);
1211         smbcli_deltree(cli->tree, BASEDIR);
1212         return ret;
1213 }
1214
1215 /*
1216   test RAW_OPEN_MKNEW
1217 */
1218 static bool test_mknew(struct torture_context *tctx, struct smbcli_state *cli)
1219 {
1220         union smb_open io;
1221         const char *fname = BASEDIR "\\torture_mknew.txt";
1222         NTSTATUS status;
1223         int fnum = -1;
1224         bool ret = true;
1225         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1226         union smb_fileinfo finfo;
1227
1228         if (!torture_setup_dir(cli, BASEDIR)) {
1229                 return false;
1230         }
1231
1232         io.mknew.level = RAW_OPEN_MKNEW;
1233         io.mknew.in.attrib = 0;
1234         io.mknew.in.write_time = 0;
1235         io.mknew.in.fname = fname;
1236         status = smb_raw_open(cli->tree, tctx, &io);
1237         CHECK_STATUS(status, NT_STATUS_OK);
1238         fnum = io.mknew.out.file.fnum;
1239
1240         status = smb_raw_open(cli->tree, tctx, &io);
1241         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
1242
1243         smbcli_close(cli->tree, fnum);
1244         smbcli_unlink(cli->tree, fname);
1245
1246         /* make sure write_time works */
1247         io.mknew.in.write_time = basetime;
1248         status = smb_raw_open(cli->tree, tctx, &io);
1249         CHECK_STATUS(status, NT_STATUS_OK);
1250         fnum = io.mknew.out.file.fnum;
1251         CHECK_TIME(basetime, write_time);
1252
1253         smbcli_close(cli->tree, fnum);
1254         smbcli_unlink(cli->tree, fname);
1255
1256         /* make sure file_attrs works */
1257         io.mknew.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1258         status = smb_raw_open(cli->tree, tctx, &io);
1259         CHECK_STATUS(status, NT_STATUS_OK);
1260         fnum = io.mknew.out.file.fnum;
1261         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
1262                        attrib & ~FILE_ATTRIBUTE_NONINDEXED);
1263         
1264 done:
1265         smbcli_close(cli->tree, fnum);
1266         smbcli_deltree(cli->tree, BASEDIR);
1267
1268         return ret;
1269 }
1270
1271
1272 /*
1273   test RAW_OPEN_CREATE
1274 */
1275 static bool test_create(struct torture_context *tctx, struct smbcli_state *cli)
1276 {
1277         union smb_open io;
1278         const char *fname = BASEDIR "\\torture_create.txt";
1279         NTSTATUS status;
1280         int fnum = -1;
1281         bool ret = true;
1282         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1283         union smb_fileinfo finfo;
1284
1285         if (!torture_setup_dir(cli, BASEDIR)) {
1286                 return false;
1287         }
1288
1289         io.create.level = RAW_OPEN_CREATE;
1290         io.create.in.attrib = 0;
1291         io.create.in.write_time = 0;
1292         io.create.in.fname = fname;
1293         status = smb_raw_open(cli->tree, tctx, &io);
1294         CHECK_STATUS(status, NT_STATUS_OK);
1295         fnum = io.create.out.file.fnum;
1296
1297         status = smb_raw_open(cli->tree, tctx, &io);
1298         CHECK_STATUS(status, NT_STATUS_OK);
1299
1300         smbcli_close(cli->tree, io.create.out.file.fnum);
1301         smbcli_close(cli->tree, fnum);
1302         smbcli_unlink(cli->tree, fname);
1303
1304         /* make sure write_time works */
1305         io.create.in.write_time = basetime;
1306         status = smb_raw_open(cli->tree, tctx, &io);
1307         CHECK_STATUS(status, NT_STATUS_OK);
1308         fnum = io.create.out.file.fnum;
1309         CHECK_TIME(basetime, write_time);
1310
1311         smbcli_close(cli->tree, fnum);
1312         smbcli_unlink(cli->tree, fname);
1313
1314         /* make sure file_attrs works */
1315         io.create.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1316         status = smb_raw_open(cli->tree, tctx, &io);
1317         CHECK_STATUS(status, NT_STATUS_OK);
1318         fnum = io.create.out.file.fnum;
1319         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
1320                        attrib & ~FILE_ATTRIBUTE_NONINDEXED);
1321         
1322 done:
1323         smbcli_close(cli->tree, fnum);
1324         smbcli_deltree(cli->tree, BASEDIR);
1325
1326         return ret;
1327 }
1328
1329
1330 /*
1331   test RAW_OPEN_CTEMP
1332 */
1333 static bool test_ctemp(struct torture_context *tctx, struct smbcli_state *cli)
1334 {
1335         union smb_open io;
1336         NTSTATUS status;
1337         int fnum = -1;
1338         bool ret = true;
1339         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1340         union smb_fileinfo finfo;
1341         const char *name, *fname = NULL;
1342
1343         if (!torture_setup_dir(cli, BASEDIR)) {
1344                 return false;
1345         }
1346
1347         io.ctemp.level = RAW_OPEN_CTEMP;
1348         io.ctemp.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1349         io.ctemp.in.write_time = basetime;
1350         io.ctemp.in.directory = BASEDIR;
1351         status = smb_raw_open(cli->tree, tctx, &io);
1352         CHECK_STATUS(status, NT_STATUS_OK);
1353         fnum = io.ctemp.out.file.fnum;
1354
1355         name = io.ctemp.out.name;
1356
1357         finfo.generic.level = RAW_FILEINFO_NAME_INFO;
1358         finfo.generic.in.file.fnum = fnum;
1359         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1360         CHECK_STATUS(status, NT_STATUS_OK);
1361
1362         fname = finfo.name_info.out.fname.s;
1363         torture_comment(tctx, "ctemp name=%s  real name=%s\n", name, fname);
1364
1365 done:
1366         smbcli_close(cli->tree, fnum);
1367         smbcli_deltree(cli->tree, BASEDIR);
1368
1369         return ret;
1370 }
1371
1372
1373 /*
1374   test chained RAW_OPEN_OPENX_READX
1375 */
1376 static bool test_chained(struct torture_context *tctx, struct smbcli_state *cli)
1377 {
1378         union smb_open io;
1379         const char *fname = BASEDIR "\\torture_chained.txt";
1380         NTSTATUS status;
1381         int fnum = -1;
1382         bool ret = true;
1383         const char *buf = "test";
1384         char buf2[4];
1385
1386         if (!torture_setup_dir(cli, BASEDIR)) {
1387                 return false;
1388         }
1389
1390         fnum = create_complex_file(cli, tctx, fname);
1391
1392         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1393
1394         smbcli_close(cli->tree, fnum);  
1395
1396         io.openxreadx.level = RAW_OPEN_OPENX_READX;
1397         io.openxreadx.in.fname = fname;
1398         io.openxreadx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1399         io.openxreadx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1400         io.openxreadx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1401         io.openxreadx.in.search_attrs = 0;
1402         io.openxreadx.in.file_attrs = 0;
1403         io.openxreadx.in.write_time = 0;
1404         io.openxreadx.in.size = 1024*1024;
1405         io.openxreadx.in.timeout = 0;
1406         
1407         io.openxreadx.in.offset = 0;
1408         io.openxreadx.in.mincnt = sizeof(buf);
1409         io.openxreadx.in.maxcnt = sizeof(buf);
1410         io.openxreadx.in.remaining = 0;
1411         io.openxreadx.out.data = (uint8_t *)buf2;
1412
1413         status = smb_raw_open(cli->tree, tctx, &io);
1414         CHECK_STATUS(status, NT_STATUS_OK);
1415         fnum = io.openxreadx.out.file.fnum;
1416
1417         if (memcmp(buf, buf2, sizeof(buf)) != 0) {
1418                 torture_result(tctx, TORTURE_FAIL,
1419                         "wrong data in reply buffer\n");
1420                 ret = false;
1421         }
1422
1423 done:
1424         smbcli_close(cli->tree, fnum);
1425         smbcli_deltree(cli->tree, BASEDIR);
1426
1427         return ret;
1428 }
1429
1430 /*
1431   test RAW_OPEN_OPENX without a leading slash on the path.
1432   NetApp filers are known to fail on this.
1433   
1434 */
1435 static bool test_no_leading_slash(struct torture_context *tctx, struct smbcli_state *cli)
1436 {
1437         union smb_open io;
1438         const char *fname = BASEDIR "\\torture_no_leading_slash.txt";
1439         NTSTATUS status;
1440         int fnum = -1;
1441         bool ret = true;
1442         const char *buf = "test";
1443
1444         if (!torture_setup_dir(cli, BASEDIR)) {
1445                 return false;
1446         }
1447
1448         smbcli_unlink(cli->tree, fname);
1449
1450         /* Create the file */
1451         fnum = create_complex_file(cli, tctx, fname);
1452         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1453         smbcli_close(cli->tree, fnum);  
1454
1455         /* Prepare to open the file using path without leading slash */
1456         io.openx.level = RAW_OPEN_OPENX;
1457         io.openx.in.fname = fname + 1;
1458         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1459         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1460         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1461         io.openx.in.search_attrs = 0;
1462         io.openx.in.file_attrs = 0;
1463         io.openx.in.write_time = 0;
1464         io.openx.in.size = 1024*1024;
1465         io.openx.in.timeout = 0;
1466
1467         status = smb_raw_open(cli->tree, tctx, &io);
1468         CHECK_STATUS(status, NT_STATUS_OK);
1469         fnum = io.openx.out.file.fnum;
1470
1471 done:
1472         smbcli_close(cli->tree, fnum);
1473         smbcli_deltree(cli->tree, BASEDIR);
1474
1475         return ret;
1476 }
1477
1478 /*
1479   test RAW_OPEN_OPENX against an existing directory to
1480   ensure it returns NT_STATUS_FILE_IS_A_DIRECTORY.
1481   Samba 3.2.0 - 3.2.6 are known to fail this.
1482   
1483 */
1484 static bool test_openx_over_dir(struct torture_context *tctx, struct smbcli_state *cli)
1485 {
1486         union smb_open io;
1487         const char *fname = BASEDIR "\\openx_over_dir";
1488         NTSTATUS status;
1489         int d_fnum = -1;
1490         int fnum = -1;
1491         bool ret = true;
1492
1493         if (!torture_setup_dir(cli, BASEDIR)) {
1494                 return false;
1495         }
1496
1497         /* Create the Directory */
1498         status = create_directory_handle(cli->tree, fname, &d_fnum);
1499         smbcli_close(cli->tree, d_fnum);        
1500
1501         /* Prepare to open the file over the directory. */
1502         io.openx.level = RAW_OPEN_OPENX;
1503         io.openx.in.fname = fname;
1504         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1505         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1506         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1507         io.openx.in.search_attrs = 0;
1508         io.openx.in.file_attrs = 0;
1509         io.openx.in.write_time = 0;
1510         io.openx.in.size = 1024*1024;
1511         io.openx.in.timeout = 0;
1512
1513         status = smb_raw_open(cli->tree, tctx, &io);
1514         CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
1515         fnum = io.openx.out.file.fnum;
1516
1517 done:
1518         smbcli_close(cli->tree, fnum);
1519         smbcli_deltree(cli->tree, BASEDIR);
1520
1521         return ret;
1522 }
1523
1524
1525 /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
1526
1527 static bool test_raw_open_multi(struct torture_context *tctx, struct smbcli_state *cli_ignored)
1528 {
1529         struct smbcli_state *cli;
1530         TALLOC_CTX *mem_ctx = talloc_init("torture_test_oplock_multi");
1531         const char *fname = "\\test_oplock.dat";
1532         NTSTATUS status;
1533         bool ret = true;
1534         union smb_open io;
1535         struct smbcli_state **clients;
1536         struct smbcli_request **requests;
1537         union smb_open *ios;
1538         const char *host = torture_setting_string(tctx, "host", NULL);
1539         const char *share = torture_setting_string(tctx, "share", NULL);
1540         int i, num_files = 3;
1541         int num_ok = 0;
1542         int num_collision = 0;
1543         
1544         clients = talloc_array(mem_ctx, struct smbcli_state *, num_files);
1545         requests = talloc_array(mem_ctx, struct smbcli_request *, num_files);
1546         ios = talloc_array(mem_ctx, union smb_open, num_files);
1547         if ((tctx->ev == NULL) || (clients == NULL) || (requests == NULL) ||
1548             (ios == NULL)) {
1549                 torture_result(tctx, TORTURE_FAIL, "(%s): talloc failed\n",
1550                                 __location__);
1551                 return false;
1552         }
1553
1554         if (!torture_open_connection_share(mem_ctx, &cli, tctx, host, share, tctx->ev)) {
1555                 return false;
1556         }
1557
1558         cli->tree->session->transport->options.request_timeout = 60;
1559
1560         for (i=0; i<num_files; i++) {
1561                 if (!torture_open_connection_share(mem_ctx, &(clients[i]),
1562                                                    tctx, host, share, tctx->ev)) {
1563                         torture_result(tctx, TORTURE_FAIL,
1564                                        "(%s): Could not open %d'th connection\n",
1565                                        __location__, i);
1566                         return false;
1567                 }
1568                 clients[i]->tree->session->transport->options.request_timeout = 60;
1569         }
1570
1571         /* cleanup */
1572         smbcli_unlink(cli->tree, fname);
1573
1574         /*
1575           base ntcreatex parms
1576         */
1577         io.generic.level = RAW_OPEN_NTCREATEX;
1578         io.ntcreatex.in.root_fid.fnum = 0;
1579         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1580         io.ntcreatex.in.alloc_size = 0;
1581         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1582         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1583                 NTCREATEX_SHARE_ACCESS_WRITE|
1584                 NTCREATEX_SHARE_ACCESS_DELETE;
1585         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1586         io.ntcreatex.in.create_options = 0;
1587         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1588         io.ntcreatex.in.security_flags = 0;
1589         io.ntcreatex.in.fname = fname;
1590         io.ntcreatex.in.flags = 0;
1591
1592         for (i=0; i<num_files; i++) {
1593                 ios[i] = io;
1594                 requests[i] = smb_raw_open_send(clients[i]->tree, &ios[i]);
1595                 if (requests[i] == NULL) {
1596                         torture_result(tctx, TORTURE_FAIL,
1597                                 "(%s): could not send %d'th request\n",
1598                                 __location__, i);
1599                         return false;
1600                 }
1601         }
1602
1603         torture_comment(tctx, "waiting for replies\n");
1604         while (1) {
1605                 bool unreplied = false;
1606                 for (i=0; i<num_files; i++) {
1607                         if (requests[i] == NULL) {
1608                                 continue;
1609                         }
1610                         if (requests[i]->state < SMBCLI_REQUEST_DONE) {
1611                                 unreplied = true;
1612                                 break;
1613                         }
1614                         status = smb_raw_open_recv(requests[i], mem_ctx,
1615                                                    &ios[i]);
1616
1617                         torture_comment(tctx, "File %d returned status %s\n", i,
1618                                   nt_errstr(status));
1619
1620                         if (NT_STATUS_IS_OK(status)) {
1621                                 num_ok += 1;
1622                         } 
1623
1624                         if (NT_STATUS_EQUAL(status,
1625                                             NT_STATUS_OBJECT_NAME_COLLISION)) {
1626                                 num_collision += 1;
1627                         }
1628
1629                         requests[i] = NULL;
1630                 }
1631                 if (!unreplied) {
1632                         break;
1633                 }
1634
1635                 if (event_loop_once(tctx->ev) != 0) {
1636                         torture_result(tctx, TORTURE_FAIL,
1637                                 "(%s): event_loop_once failed\n", __location__);
1638                         return false;
1639                 }
1640         }
1641
1642         if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
1643                 ret = false;
1644         }
1645
1646         for (i=0; i<num_files; i++) {
1647                 torture_close_connection(clients[i]);
1648         }
1649         talloc_free(mem_ctx);
1650         return ret;
1651 }
1652
1653 /*
1654   test opening for delete on a read-only attribute file.
1655 */
1656 static bool test_open_for_delete(struct torture_context *tctx, struct smbcli_state *cli)
1657 {
1658         union smb_open io;
1659         union smb_fileinfo finfo;
1660         const char *fname = BASEDIR "\\torture_open_for_delete.txt";
1661         NTSTATUS status;
1662         int fnum = -1;
1663         bool ret = true;
1664
1665         if (!torture_setup_dir(cli, BASEDIR)) {
1666                 return false;
1667         }
1668
1669         /* reasonable default parameters */
1670         io.generic.level = RAW_OPEN_NTCREATEX;
1671         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1672         io.ntcreatex.in.root_fid.fnum = 0;
1673         io.ntcreatex.in.alloc_size = 0;
1674         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1675         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_READONLY;
1676         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1677         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1678         io.ntcreatex.in.create_options = 0;
1679         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1680         io.ntcreatex.in.security_flags = 0;
1681         io.ntcreatex.in.fname = fname;
1682
1683         /* Create the readonly file. */
1684
1685         status = smb_raw_open(cli->tree, tctx, &io);
1686         CHECK_STATUS(status, NT_STATUS_OK);
1687         fnum = io.ntcreatex.out.file.fnum;
1688
1689         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1690         io.ntcreatex.in.create_options = 0;
1691         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
1692         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1693         smbcli_close(cli->tree, fnum);
1694
1695         /* Now try and open for delete only - should succeed. */
1696         io.ntcreatex.in.access_mask = SEC_STD_DELETE;
1697         io.ntcreatex.in.file_attr = 0;
1698         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
1699         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1700         status = smb_raw_open(cli->tree, tctx, &io);
1701         CHECK_STATUS(status, NT_STATUS_OK);
1702
1703         smbcli_unlink(cli->tree, fname);
1704
1705 done:
1706         smbcli_close(cli->tree, fnum);
1707         smbcli_deltree(cli->tree, BASEDIR);
1708
1709         return ret;
1710 }
1711
1712 /*
1713   test chained RAW_OPEN_NTCREATEX_READX
1714   Send chained NTCREATEX_READX on a file that doesn't exist, then create
1715   the file and try again.
1716 */
1717 static bool test_chained_ntcreatex_readx(struct torture_context *tctx, struct smbcli_state *cli)
1718 {
1719         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1720         union smb_open io;
1721         const char *fname = BASEDIR "\\torture_chained.txt";
1722         NTSTATUS status;
1723         int fnum = -1;
1724         bool ret = true;
1725         const char *buf = "test";
1726         char buf2[4];
1727
1728         if (!torture_setup_dir(cli, BASEDIR)) {
1729                 return false;
1730         }
1731
1732         torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
1733                               "non-existant file \n");
1734
1735         /* ntcreatex parameters */
1736         io.generic.level = RAW_OPEN_NTCREATEX_READX;
1737         io.ntcreatexreadx.in.flags = 0;
1738         io.ntcreatexreadx.in.root_fid.fnum = 0;
1739         io.ntcreatexreadx.in.access_mask = SEC_FILE_READ_DATA;
1740         io.ntcreatexreadx.in.alloc_size = 0;
1741         io.ntcreatexreadx.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1742         io.ntcreatexreadx.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1743                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
1744         io.ntcreatexreadx.in.open_disposition = NTCREATEX_DISP_OPEN;
1745         io.ntcreatexreadx.in.create_options = 0;
1746         io.ntcreatexreadx.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1747         io.ntcreatexreadx.in.security_flags = 0;
1748         io.ntcreatexreadx.in.fname = fname;
1749
1750         /* readx parameters */
1751         io.ntcreatexreadx.in.offset = 0;
1752         io.ntcreatexreadx.in.mincnt = sizeof(buf);
1753         io.ntcreatexreadx.in.maxcnt = sizeof(buf);
1754         io.ntcreatexreadx.in.remaining = 0;
1755         io.ntcreatexreadx.out.data = (uint8_t *)buf2;
1756
1757         /* try to open the non-existant file */
1758         status = smb_raw_open(cli->tree, mem_ctx, &io);
1759         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1760         fnum = io.ntcreatexreadx.out.file.fnum;
1761
1762         smbcli_close(cli->tree, fnum);
1763         smbcli_unlink(cli->tree, fname);
1764
1765         torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
1766                               "existing file \n");
1767
1768         fnum = create_complex_file(cli, mem_ctx, fname);
1769         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1770         smbcli_close(cli->tree, fnum);
1771
1772         status = smb_raw_open(cli->tree, mem_ctx, &io);
1773         CHECK_STATUS(status, NT_STATUS_OK);
1774         fnum = io.ntcreatexreadx.out.file.fnum;
1775
1776         if (memcmp(buf, buf2, sizeof(buf)) != 0) {
1777                 torture_result(tctx, TORTURE_FAIL,
1778                         "(%s): wrong data in reply buffer\n", __location__);
1779                 ret = false;
1780         }
1781
1782 done:
1783         smbcli_close(cli->tree, fnum);
1784         smbcli_deltree(cli->tree, BASEDIR);
1785         talloc_free(mem_ctx);
1786
1787         return ret;
1788 }
1789
1790 static bool test_ntcreatex_opendisp_dir(struct torture_context *tctx,
1791                                         struct smbcli_state *cli)
1792 {
1793         const char *dname = BASEDIR "\\torture_ntcreatex_opendisp_dir";
1794         NTSTATUS status;
1795         bool ret = true;
1796         int i;
1797         struct {
1798                 uint32_t open_disp;
1799                 bool dir_exists;
1800                 NTSTATUS correct_status;
1801         } open_funcs_dir[] = {
1802                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_INVALID_PARAMETER },
1803                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_INVALID_PARAMETER },
1804                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
1805                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
1806                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
1807                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
1808                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
1809                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
1810                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_INVALID_PARAMETER },
1811                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_INVALID_PARAMETER },
1812                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_INVALID_PARAMETER },
1813                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_INVALID_PARAMETER },
1814                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
1815                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
1816         };
1817         union smb_open io;
1818
1819         ZERO_STRUCT(io);
1820         io.generic.level = RAW_OPEN_NTCREATEX;
1821         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1822         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1823         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1824         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1825         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1826         io.ntcreatex.in.fname = dname;
1827
1828         if (!torture_setup_dir(cli, BASEDIR)) {
1829                 return false;
1830         }
1831
1832         smbcli_rmdir(cli->tree, dname);
1833         smbcli_unlink(cli->tree, dname);
1834
1835         /* test the open disposition for directories */
1836         torture_comment(tctx, "Testing open dispositions for directories...\n");
1837
1838         for (i=0; i<ARRAY_SIZE(open_funcs_dir); i++) {
1839                 if (open_funcs_dir[i].dir_exists) {
1840                         status = smbcli_mkdir(cli->tree, dname);
1841                         if (!NT_STATUS_IS_OK(status)) {
1842                                 torture_result(tctx, TORTURE_FAIL,
1843                                         "(%s): Failed to make directory "
1844                                         "%s - %s\n", __location__, dname,
1845                                         smbcli_errstr(cli->tree));
1846                                 ret = false;
1847                                 goto done;
1848                         }
1849                 }
1850
1851                 io.ntcreatex.in.open_disposition = open_funcs_dir[i].open_disp;
1852                 status = smb_raw_open(cli->tree, tctx, &io);
1853                 if (!NT_STATUS_EQUAL(status, open_funcs_dir[i].correct_status)) {
1854                         torture_result(tctx, TORTURE_FAIL,
1855                                 "(%s) incorrect status %s should be %s "
1856                                 "(i=%d dir_exists=%d open_disp=%d)\n",
1857                                 __location__, nt_errstr(status),
1858                                 nt_errstr(open_funcs_dir[i].correct_status),
1859                                 i, (int)open_funcs_dir[i].dir_exists,
1860                                 (int)open_funcs_dir[i].open_disp);
1861                         ret = false;
1862                 }
1863                 if (NT_STATUS_IS_OK(status) || open_funcs_dir[i].dir_exists) {
1864                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1865                         smbcli_rmdir(cli->tree, dname);
1866                 }
1867         }
1868
1869 done:
1870         smbcli_deltree(cli->tree, BASEDIR);
1871
1872         return ret;
1873 }
1874
1875 /**
1876  * Test what happens when trying to open a file with directory parameters and
1877  * vice-versa.  Also test that NTCREATEX_OPTIONS_DIRECTORY is treated as
1878  * mandatory and FILE_ATTRIBUTE_DIRECTORY is advisory for directory
1879  * creation/opening.
1880  */
1881 static bool test_ntcreatexdir(struct torture_context *tctx,
1882     struct smbcli_state *cli)
1883 {
1884         union smb_open io;
1885         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
1886         const char *dname = BASEDIR "\\torture_ntcreatex_dir";
1887         NTSTATUS status;
1888         int i;
1889
1890         struct {
1891                 uint32_t open_disp;
1892                 uint32_t file_attr;
1893                 uint32_t create_options;
1894                 NTSTATUS correct_status;
1895         } open_funcs[] = {
1896                 { NTCREATEX_DISP_SUPERSEDE,     0, NTCREATEX_OPTIONS_DIRECTORY,
1897                   NT_STATUS_INVALID_PARAMETER },
1898                 { NTCREATEX_DISP_OPEN,          0, NTCREATEX_OPTIONS_DIRECTORY,
1899                   NT_STATUS_OBJECT_NAME_NOT_FOUND },
1900                 { NTCREATEX_DISP_CREATE,        0, NTCREATEX_OPTIONS_DIRECTORY,
1901                   NT_STATUS_OK },
1902                 { NTCREATEX_DISP_OPEN_IF,       0, NTCREATEX_OPTIONS_DIRECTORY,
1903                   NT_STATUS_OK },
1904                 { NTCREATEX_DISP_OVERWRITE,     0, NTCREATEX_OPTIONS_DIRECTORY,
1905                   NT_STATUS_INVALID_PARAMETER },
1906                 { NTCREATEX_DISP_OVERWRITE_IF,  0, NTCREATEX_OPTIONS_DIRECTORY,
1907                   NT_STATUS_INVALID_PARAMETER },
1908                 { NTCREATEX_DISP_SUPERSEDE,     FILE_ATTRIBUTE_DIRECTORY, 0,
1909                   NT_STATUS_OK },
1910                 { NTCREATEX_DISP_OPEN,          FILE_ATTRIBUTE_DIRECTORY, 0,
1911                   NT_STATUS_OBJECT_NAME_NOT_FOUND },
1912                 { NTCREATEX_DISP_CREATE,        FILE_ATTRIBUTE_DIRECTORY, 0,
1913                   NT_STATUS_OK },
1914                 { NTCREATEX_DISP_OPEN_IF,       FILE_ATTRIBUTE_DIRECTORY, 0,
1915                   NT_STATUS_OK },
1916                 { NTCREATEX_DISP_OVERWRITE,     FILE_ATTRIBUTE_DIRECTORY, 0,
1917                   NT_STATUS_OBJECT_NAME_NOT_FOUND },
1918                 { NTCREATEX_DISP_OVERWRITE_IF,  FILE_ATTRIBUTE_DIRECTORY, 0,
1919                   NT_STATUS_OK },
1920
1921         };
1922
1923         if (!torture_setup_dir(cli, BASEDIR)) {
1924                 return false;
1925         }
1926
1927         /* setup some base params. */
1928         io.generic.level = RAW_OPEN_NTCREATEX;
1929         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1930         io.ntcreatex.in.root_fid.fnum = 0;
1931         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1932         io.ntcreatex.in.alloc_size = 0;
1933         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1934         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1935         io.ntcreatex.in.security_flags = 0;
1936         io.ntcreatex.in.fname = fname;
1937
1938         /*
1939          * Test the validity checking for create dispositions, which is done
1940          * against the requested parameters rather than what's actually on
1941          * disk.
1942          */
1943         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
1944                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
1945                 io.ntcreatex.in.file_attr = open_funcs[i].file_attr;
1946                 io.ntcreatex.in.create_options = open_funcs[i].create_options;
1947                 status = smb_raw_open(cli->tree, tctx, &io);
1948                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
1949                         torture_result(tctx, TORTURE_FAIL,
1950                                 "(%s) incorrect status %s should be %s "
1951                                 "(i=%d open_disp=%d)\n",
1952                                 __location__, nt_errstr(status),
1953                                 nt_errstr(open_funcs[i].correct_status),
1954                                 i, (int)open_funcs[i].open_disp);
1955                         return false;
1956                 }
1957                 /* Close and delete the file. */
1958                 if (NT_STATUS_IS_OK(status)) {
1959                         if (open_funcs[i].create_options != 0) {
1960                                 /* out attrib should be a directory. */
1961                                 torture_assert_int_equal(tctx,
1962                                     io.ntcreatex.out.attrib,
1963                                     FILE_ATTRIBUTE_DIRECTORY, "should have "
1964                                     "created a directory");
1965
1966                                 smbcli_close(cli->tree,
1967                                     io.ntcreatex.out.file.fnum);
1968
1969                                 /* Make sure unlink fails. */
1970                                 status = smbcli_unlink(cli->tree, fname);
1971                                 torture_assert_ntstatus_equal(tctx, status,
1972                                     NT_STATUS_FILE_IS_A_DIRECTORY,
1973                                     "unlink should fail for a directory");
1974
1975                                 status = smbcli_rmdir(cli->tree, fname);
1976                                 torture_assert_ntstatus_ok(tctx, status,
1977                                     "rmdir failed");
1978                         } else {
1979                                 torture_assert_int_equal(tctx,
1980                                     io.ntcreatex.out.attrib,
1981                                     FILE_ATTRIBUTE_ARCHIVE, "should not have "
1982                                     "created a directory");
1983
1984                                 smbcli_close(cli->tree,
1985                                     io.ntcreatex.out.file.fnum);
1986
1987                                 /* Make sure rmdir fails. */
1988                                 status = smbcli_rmdir(cli->tree, fname);
1989                                 torture_assert_ntstatus_equal(tctx, status,
1990                                     NT_STATUS_NOT_A_DIRECTORY,
1991                                     "rmdir should fail for a file");
1992
1993                                 status = smbcli_unlink(cli->tree, fname);
1994                                 torture_assert_ntstatus_ok(tctx, status,
1995                                     "unlink failed");
1996                         }
1997                 }
1998         }
1999
2000         /* Create a file. */
2001         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2002         io.ntcreatex.in.create_options = 0;
2003         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2004         status = smb_raw_open(cli->tree, tctx, &io);
2005         torture_assert_ntstatus_ok(tctx, status, "Failed to create file.");
2006         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2007
2008         /* Try and open the file with file_attr_dir and check the error. */
2009         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
2010         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2011
2012         status = smb_raw_open(cli->tree, tctx, &io);
2013         torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_DIRECTORY "
2014             "doesn't produce a hard failure.");
2015         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2016
2017         /* Try and open file with createx_option_dir and check the error. */
2018         io.ntcreatex.in.file_attr = 0;
2019         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2020
2021         status = smb_raw_open(cli->tree, tctx, &io);
2022         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_A_DIRECTORY,
2023             "NTCREATEX_OPTIONS_DIRECTORY will a file from being opened.");
2024         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2025
2026         /* Delete the file and move onto directory testing. */
2027         smbcli_unlink(cli->tree, fname);
2028
2029         /* Now try some tests on a directory. */
2030         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2031         io.ntcreatex.in.file_attr = 0;
2032         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2033         io.ntcreatex.in.fname = dname;
2034
2035         status = smb_raw_open(cli->tree, tctx, &io);
2036         torture_assert_ntstatus_ok(tctx, status, "Failed to create dir.");
2037
2038         /* out attrib should be a directory. */
2039         torture_assert_int_equal(tctx, io.ntcreatex.out.attrib,
2040             FILE_ATTRIBUTE_DIRECTORY, "should have created a directory");
2041
2042         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2043
2044         /* Try and open it with normal attr and check the error. */
2045         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2046         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2047
2048         status = smb_raw_open(cli->tree, tctx, &io);
2049         torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_NORMAL "
2050             "doesn't produce a hard failure.");
2051         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2052
2053         /* Try and open it with file create_options and check the error. */
2054         io.ntcreatex.in.file_attr = 0;
2055         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2056
2057         status = smb_raw_open(cli->tree, tctx, &io);
2058         torture_assert_ntstatus_equal(tctx, status,
2059             NT_STATUS_FILE_IS_A_DIRECTORY,
2060             "NTCREATEX_OPTIONS_NON_DIRECTORY_FILE should be returned ");
2061         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2062
2063         smbcli_deltree(cli->tree, BASEDIR);
2064
2065         return true;
2066 }
2067
2068 /* basic testing of all RAW_OPEN_* calls
2069 */
2070 struct torture_suite *torture_raw_open(TALLOC_CTX *mem_ctx)
2071 {
2072         struct torture_suite *suite = torture_suite_create(mem_ctx, "open");
2073
2074         torture_suite_add_1smb_test(suite, "brlocked", test_ntcreatex_brlocked);
2075         torture_suite_add_1smb_test(suite, "open", test_open);
2076         torture_suite_add_1smb_test(suite, "open-multi", test_raw_open_multi);
2077         torture_suite_add_1smb_test(suite, "openx", test_openx);
2078         torture_suite_add_1smb_test(suite, "ntcreatex", test_ntcreatex);
2079         torture_suite_add_1smb_test(suite, "nttrans-create", test_nttrans_create);
2080         torture_suite_add_1smb_test(suite, "t2open", test_t2open);
2081         torture_suite_add_1smb_test(suite, "mknew", test_mknew);
2082         torture_suite_add_1smb_test(suite, "create", test_create);
2083         torture_suite_add_1smb_test(suite, "ctemp", test_ctemp);
2084         torture_suite_add_1smb_test(suite, "chained-openx", test_chained);
2085         torture_suite_add_1smb_test(suite, "chained-ntcreatex", test_chained_ntcreatex_readx);
2086         torture_suite_add_1smb_test(suite, "no-leading-slash", test_no_leading_slash);
2087         torture_suite_add_1smb_test(suite, "openx-over-dir", test_openx_over_dir);
2088         torture_suite_add_1smb_test(suite, "open-for-delete", test_open_for_delete);
2089         torture_suite_add_1smb_test(suite, "opendisp-dir", test_ntcreatex_opendisp_dir);
2090         torture_suite_add_1smb_test(suite, "ntcreatedir", test_ntcreatexdir);
2091
2092         return suite;
2093 }