1275aa81cda42a0cbf7c8eaaedf773b57897ee58
[metze/samba/wip.git] / source4 / torture / smb2 / create.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    SMB2 create test suite
5
6    Copyright (C) Andrew Tridgell 2008
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25 #include "torture/torture.h"
26 #include "torture/util.h"
27 #include "torture/smb2/proto.h"
28 #include "librpc/gen_ndr/ndr_security.h"
29 #include "libcli/security/security.h"
30
31 #include "system/filesys.h"
32 #include "auth/credentials/credentials.h"
33 #include "lib/cmdline/popt_common.h"
34 #include "librpc/gen_ndr/security.h"
35 #include "lib/events/events.h"
36
37 #define FNAME "test_create.dat"
38 #define DNAME "smb2_open"
39
40 #define CHECK_STATUS(status, correct) do { \
41         if (!NT_STATUS_EQUAL(status, correct)) { \
42                 torture_result(tctx, TORTURE_FAIL, \
43                         "(%s) Incorrect status %s - should be %s\n", \
44                          __location__, nt_errstr(status), nt_errstr(correct)); \
45                 return false; \
46         }} while (0)
47
48 #define CHECK_EQUAL(v, correct) do { \
49         if (v != correct) { \
50                 torture_result(tctx, TORTURE_FAIL, \
51                         "(%s) Incorrect value for %s 0x%08llx - " \
52                         "should be 0x%08llx\n", \
53                          __location__, #v, \
54                         (unsigned long long)v, \
55                         (unsigned long long)correct); \
56                 return false;                                   \
57         }} while (0)
58
59 #define CHECK_TIME(t, field) do { \
60         time_t t1, t2; \
61         finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
62         finfo.all_info.in.file.handle = h1; \
63         status = smb2_getinfo_file(tree, tctx, &finfo); \
64         CHECK_STATUS(status, NT_STATUS_OK); \
65         t1 = t & ~1; \
66         t2 = nt_time_to_unix(finfo.all_info.out.field) & ~1; \
67         if (abs(t1-t2) > 2) { \
68                 torture_result(tctx, TORTURE_FAIL, \
69                         "(%s) wrong time for field %s  %s - %s\n", \
70                         __location__, #field, \
71                         timestring(tctx, t1), \
72                         timestring(tctx, t2)); \
73                 dump_all_info(tctx, &finfo); \
74                 ret = false; \
75         }} while (0)
76
77 #define CHECK_NTTIME(t, field) do { \
78         NTTIME t2; \
79         finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
80         finfo.all_info.in.file.handle = h1; \
81         status = smb2_getinfo_file(tree, tctx, &finfo); \
82         CHECK_STATUS(status, NT_STATUS_OK); \
83         t2 = finfo.all_info.out.field; \
84         if (abs(t-t2) > 20000) { \
85                 torture_result(tctx, TORTURE_FAIL, \
86                         "(%s) wrong time for field %s  %s - %s\n", \
87                        __location__, #field, \
88                        nt_time_string(tctx, t), \
89                        nt_time_string(tctx, t2)); \
90                 dump_all_info(tctx, &finfo); \
91                 ret = false; \
92         }} while (0)
93
94 #define CHECK_ALL_INFO(v, field) do { \
95         finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
96         finfo.all_info.in.file.handle = h1; \
97         status = smb2_getinfo_file(tree, tctx, &finfo); \
98         CHECK_STATUS(status, NT_STATUS_OK); \
99         if ((v) != (finfo.all_info.out.field)) { \
100                torture_result(tctx, TORTURE_FAIL, \
101                         "(%s) wrong value for field %s  0x%x - 0x%x\n", \
102                         __location__, #field, (int)v,\
103                         (int)(finfo.all_info.out.field)); \
104                 dump_all_info(tctx, &finfo); \
105                 ret = false; \
106         }} while (0)
107
108 #define CHECK_VAL(v, correct) do { \
109         if ((v) != (correct)) { \
110                 torture_result(tctx, TORTURE_FAIL, \
111                         "(%s) wrong value for %s  0x%x - should be 0x%x\n", \
112                        __location__, #v, (int)(v), (int)correct); \
113                 ret = false; \
114         }} while (0)
115
116 #define SET_ATTRIB(sattrib) do { \
117         union smb_setfileinfo sfinfo; \
118         ZERO_STRUCT(sfinfo.basic_info.in); \
119         sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION; \
120         sfinfo.basic_info.in.file.handle = h1; \
121         sfinfo.basic_info.in.attrib = sattrib; \
122         status = smb2_setinfo_file(tree, &sfinfo); \
123         if (!NT_STATUS_IS_OK(status)) { \
124                 torture_comment(tctx, \
125                     "(%s) Failed to set attrib 0x%x on %s\n", \
126                        __location__, sattrib, fname); \
127         }} while (0)
128
129 /*
130   test some interesting combinations found by gentest
131  */
132 static bool test_create_gentest(struct torture_context *tctx, struct smb2_tree *tree)
133 {
134         struct smb2_create io;
135         NTSTATUS status;
136         uint32_t access_mask, file_attributes_set;
137         uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
138         uint32_t not_a_directory_mask, unexpected_mask;
139         union smb_fileinfo q;
140
141         ZERO_STRUCT(io);
142         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
143         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
144         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
145         io.in.share_access = 
146                 NTCREATEX_SHARE_ACCESS_DELETE|
147                 NTCREATEX_SHARE_ACCESS_READ|
148                 NTCREATEX_SHARE_ACCESS_WRITE;
149         io.in.create_options = 0;
150         io.in.fname = FNAME;
151
152         status = smb2_create(tree, tctx, &io);
153         CHECK_STATUS(status, NT_STATUS_OK);
154
155         status = smb2_util_close(tree, io.out.file.handle);
156         CHECK_STATUS(status, NT_STATUS_OK);
157
158         io.in.create_options = 0xF0000000;
159         status = smb2_create(tree, tctx, &io);
160         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
161
162         io.in.create_options = 0;
163
164         io.in.file_attributes = FILE_ATTRIBUTE_DEVICE;
165         status = smb2_create(tree, tctx, &io);
166         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
167
168         io.in.file_attributes = FILE_ATTRIBUTE_VOLUME;
169         status = smb2_create(tree, tctx, &io);
170         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
171
172         io.in.create_disposition = NTCREATEX_DISP_OPEN;
173         io.in.file_attributes = FILE_ATTRIBUTE_VOLUME;
174         status = smb2_create(tree, tctx, &io);
175         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
176         
177         io.in.create_disposition = NTCREATEX_DISP_CREATE;
178         io.in.desired_access = 0x08000000;
179         status = smb2_create(tree, tctx, &io);
180         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
181
182         io.in.desired_access = 0x04000000;
183         status = smb2_create(tree, tctx, &io);
184         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
185
186         io.in.file_attributes = 0;
187         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
188         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
189         ok_mask = 0;
190         not_supported_mask = 0;
191         invalid_parameter_mask = 0;
192         not_a_directory_mask = 0;
193         unexpected_mask = 0;
194         {
195                 int i;
196                 for (i=0;i<32;i++) {
197                         io.in.create_options = 1<<i;
198                         if (io.in.create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
199                                 continue;
200                         }
201                         status = smb2_create(tree, tctx, &io);
202                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
203                                 not_supported_mask |= 1<<i;
204                         } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
205                                 invalid_parameter_mask |= 1<<i;
206                         } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
207                                 not_a_directory_mask |= 1<<i;
208                         } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
209                                 ok_mask |= 1<<i;
210                                 status = smb2_util_close(tree, io.out.file.handle);
211                                 CHECK_STATUS(status, NT_STATUS_OK);
212                         } else {
213                                 unexpected_mask |= 1<<i;
214                                 torture_comment(tctx,
215                                     "create option 0x%08x returned %s\n",
216                                     1<<i, nt_errstr(status));
217                         }
218                 }
219         }
220         io.in.create_options = 0;
221
222         CHECK_EQUAL(ok_mask,                0x00efcf7e);
223         CHECK_EQUAL(not_a_directory_mask,   0x00000001);
224         CHECK_EQUAL(not_supported_mask,     0x00102080);
225         CHECK_EQUAL(invalid_parameter_mask, 0xff000000);
226         CHECK_EQUAL(unexpected_mask,        0x00000000);
227
228         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
229         io.in.file_attributes = 0;
230         access_mask = 0;
231         {
232                 int i;
233                 for (i=0;i<32;i++) {
234                         io.in.desired_access = 1<<i;
235                         status = smb2_create(tree, tctx, &io);
236                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
237                             NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
238                                 access_mask |= io.in.desired_access;
239                         } else {
240                                 CHECK_STATUS(status, NT_STATUS_OK);
241                                 status = smb2_util_close(tree, io.out.file.handle);
242                                 CHECK_STATUS(status, NT_STATUS_OK);
243                         }
244                 }
245         }
246
247         if (TARGET_IS_WIN7(tctx)) {
248                 CHECK_EQUAL(access_mask, 0x0de0fe00);
249         } else if (torture_setting_bool(tctx, "samba4", false)) {
250                 CHECK_EQUAL(access_mask, 0x0cf0fe00);
251         } else {
252                 CHECK_EQUAL(access_mask, 0x0df0fe00);
253         }
254
255         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
256         io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
257         io.in.file_attributes = 0;
258         ok_mask = 0;
259         invalid_parameter_mask = 0;
260         unexpected_mask = 0;
261         file_attributes_set = 0;
262         {
263                 int i;
264                 for (i=0;i<32;i++) {
265                         io.in.file_attributes = 1<<i;
266                         if (io.in.file_attributes & FILE_ATTRIBUTE_ENCRYPTED) {
267                                 continue;
268                         }
269                         smb2_deltree(tree, FNAME);
270                         status = smb2_create(tree, tctx, &io);
271                         if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
272                                 invalid_parameter_mask |= 1<<i;
273                         } else if (NT_STATUS_IS_OK(status)) {
274                                 uint32_t expected;
275                                 ok_mask |= 1<<i;
276
277                                 expected = (io.in.file_attributes | FILE_ATTRIBUTE_ARCHIVE) & 0x00005127;
278                                 io.out.file_attr &= ~FILE_ATTRIBUTE_NONINDEXED;
279                                 CHECK_EQUAL(io.out.file_attr, expected);
280                                 file_attributes_set |= io.out.file_attr;
281
282                                 status = smb2_util_close(tree, io.out.file.handle);
283                                 CHECK_STATUS(status, NT_STATUS_OK);
284                         } else {
285                                 unexpected_mask |= 1<<i;
286                                 torture_comment(tctx,
287                                     "file attribute 0x%08x returned %s\n",
288                                     1<<i, nt_errstr(status));
289                         }
290                 }
291         }
292
293         CHECK_EQUAL(ok_mask,                0x00003fb7);
294         CHECK_EQUAL(invalid_parameter_mask, 0xffff8048);
295         CHECK_EQUAL(unexpected_mask,        0x00000000);
296         CHECK_EQUAL(file_attributes_set,    0x00001127);
297
298         smb2_deltree(tree, FNAME);
299
300         /*
301          * Standalone servers doesn't support encryption
302          */
303         io.in.file_attributes = FILE_ATTRIBUTE_ENCRYPTED;
304         status = smb2_create(tree, tctx, &io);
305         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
306                 torture_comment(tctx,
307                     "FILE_ATTRIBUTE_ENCRYPTED returned %s\n",
308                     nt_errstr(status));
309         } else {
310                 CHECK_STATUS(status, NT_STATUS_OK);
311                 CHECK_EQUAL(io.out.file_attr, (FILE_ATTRIBUTE_ENCRYPTED | FILE_ATTRIBUTE_ARCHIVE));
312                 status = smb2_util_close(tree, io.out.file.handle);
313                 CHECK_STATUS(status, NT_STATUS_OK);
314         }
315
316         smb2_deltree(tree, FNAME);
317
318         ZERO_STRUCT(io);
319         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
320         io.in.file_attributes    = 0;
321         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
322         io.in.share_access = 
323                 NTCREATEX_SHARE_ACCESS_READ|
324                 NTCREATEX_SHARE_ACCESS_WRITE;
325         io.in.create_options = 0;
326         io.in.fname = FNAME ":stream1";
327         status = smb2_create(tree, tctx, &io);
328         CHECK_STATUS(status, NT_STATUS_OK);
329
330         status = smb2_util_close(tree, io.out.file.handle);
331         CHECK_STATUS(status, NT_STATUS_OK);
332
333         io.in.fname = FNAME;
334         io.in.file_attributes = 0x8040;
335         io.in.share_access = 
336                 NTCREATEX_SHARE_ACCESS_READ;
337         status = smb2_create(tree, tctx, &io);
338         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
339
340         io.in.fname = FNAME;
341         io.in.file_attributes = 0;
342         io.in.desired_access  = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA;
343         io.in.query_maximal_access = true;
344         status = smb2_create(tree, tctx, &io);
345         CHECK_STATUS(status, NT_STATUS_OK);
346         CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);
347
348         q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
349         q.access_information.in.file.handle = io.out.file.handle;
350         status = smb2_getinfo_file(tree, tctx, &q);
351         CHECK_STATUS(status, NT_STATUS_OK);
352         CHECK_EQUAL(q.access_information.out.access_flags, io.in.desired_access);
353
354         io.in.file_attributes = 0;
355         io.in.desired_access  = 0;
356         io.in.query_maximal_access = false;
357         io.in.share_access = 0;
358         status = smb2_create(tree, tctx, &io);
359         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
360         
361         smb2_deltree(tree, FNAME);
362
363         return true;
364 }
365
366
367 /*
368   try the various request blobs
369  */
370 static bool test_create_blob(struct torture_context *tctx, struct smb2_tree *tree)
371 {
372         struct smb2_create io;
373         NTSTATUS status;
374
375         smb2_deltree(tree, FNAME);
376
377         ZERO_STRUCT(io);
378         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
379         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
380         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
381         io.in.share_access = 
382                 NTCREATEX_SHARE_ACCESS_DELETE|
383                 NTCREATEX_SHARE_ACCESS_READ|
384                 NTCREATEX_SHARE_ACCESS_WRITE;
385         io.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
386                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
387                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
388                                           0x00200000;
389         io.in.fname = FNAME;
390
391         status = smb2_create(tree, tctx, &io);
392         CHECK_STATUS(status, NT_STATUS_OK);
393
394         status = smb2_util_close(tree, io.out.file.handle);
395         CHECK_STATUS(status, NT_STATUS_OK);
396
397         torture_comment(tctx, "Testing alloc size\n");
398         /* FIXME We use 1M cause that's the rounded size of Samba.
399          * We should ask the server for the cluser size and calulate it
400          * correctly. */
401         io.in.alloc_size = 0x00100000;
402         status = smb2_create(tree, tctx, &io);
403         CHECK_STATUS(status, NT_STATUS_OK);
404         CHECK_EQUAL(io.out.alloc_size, io.in.alloc_size);
405
406         status = smb2_util_close(tree, io.out.file.handle);
407         CHECK_STATUS(status, NT_STATUS_OK);
408
409         torture_comment(tctx, "Testing durable open\n");
410         io.in.durable_open = true;
411         status = smb2_create(tree, tctx, &io);
412         CHECK_STATUS(status, NT_STATUS_OK);
413
414         status = smb2_util_close(tree, io.out.file.handle);
415         CHECK_STATUS(status, NT_STATUS_OK);
416
417         torture_comment(tctx, "Testing query maximal access\n");
418         io.in.query_maximal_access = true;
419         status = smb2_create(tree, tctx, &io);
420         CHECK_STATUS(status, NT_STATUS_OK);
421         CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);
422
423         status = smb2_util_close(tree, io.out.file.handle);
424         CHECK_STATUS(status, NT_STATUS_OK);
425
426         torture_comment(tctx, "Testing timewarp\n");
427         io.in.timewarp = 10000;
428         status = smb2_create(tree, tctx, &io);
429         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
430         io.in.timewarp = 0;
431
432         torture_comment(tctx, "Testing query_on_disk\n");
433         io.in.query_on_disk_id = true;
434         status = smb2_create(tree, tctx, &io);
435         CHECK_STATUS(status, NT_STATUS_OK);
436
437         status = smb2_util_close(tree, io.out.file.handle);
438         CHECK_STATUS(status, NT_STATUS_OK);
439
440         torture_comment(tctx, "Testing unknown tag\n");
441         status = smb2_create_blob_add(tctx, &io.in.blobs,
442                                       "FooO", data_blob(NULL, 0));
443         CHECK_STATUS(status, NT_STATUS_OK);
444
445         status = smb2_create(tree, tctx, &io);
446         CHECK_STATUS(status, NT_STATUS_OK);
447
448         status = smb2_util_close(tree, io.out.file.handle);
449         CHECK_STATUS(status, NT_STATUS_OK);
450
451         torture_comment(tctx, "Testing bad tag length 0\n");
452         ZERO_STRUCT(io.in.blobs);
453         status = smb2_create_blob_add(tctx, &io.in.blobs,
454                                       "x", data_blob(NULL, 0));
455         CHECK_STATUS(status, NT_STATUS_OK);
456         status = smb2_create(tree, tctx, &io);
457         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
458
459         torture_comment(tctx, "Testing bad tag length 1\n");
460         ZERO_STRUCT(io.in.blobs);
461         status = smb2_create_blob_add(tctx, &io.in.blobs,
462                                       "x", data_blob(NULL, 0));
463         CHECK_STATUS(status, NT_STATUS_OK);
464         status = smb2_create(tree, tctx, &io);
465         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
466
467         torture_comment(tctx, "Testing bad tag length 2\n");
468         ZERO_STRUCT(io.in.blobs);
469         status = smb2_create_blob_add(tctx, &io.in.blobs,
470                                       "xx", data_blob(NULL, 0));
471         CHECK_STATUS(status, NT_STATUS_OK);
472         status = smb2_create(tree, tctx, &io);
473         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
474
475         torture_comment(tctx, "Testing bad tag length 3\n");
476         ZERO_STRUCT(io.in.blobs);
477         status = smb2_create_blob_add(tctx, &io.in.blobs,
478                                       "xxx", data_blob(NULL, 0));
479         CHECK_STATUS(status, NT_STATUS_OK);
480         status = smb2_create(tree, tctx, &io);
481         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
482
483         torture_comment(tctx, "Testing tag length 4\n");
484         ZERO_STRUCT(io.in.blobs);
485         status = smb2_create_blob_add(tctx, &io.in.blobs,
486                                       "xxxx", data_blob(NULL, 0));
487         CHECK_STATUS(status, NT_STATUS_OK);
488         status = smb2_create(tree, tctx, &io);
489         CHECK_STATUS(status, NT_STATUS_OK);
490
491         torture_comment(tctx, "Testing tag length 5\n");
492         ZERO_STRUCT(io.in.blobs);
493         status = smb2_create_blob_add(tctx, &io.in.blobs,
494                                       "xxxxx", data_blob(NULL, 0));
495         CHECK_STATUS(status, NT_STATUS_OK);
496         status = smb2_create(tree, tctx, &io);
497         CHECK_STATUS(status, NT_STATUS_OK);
498
499         torture_comment(tctx, "Testing tag length 6\n");
500         ZERO_STRUCT(io.in.blobs);
501         status = smb2_create_blob_add(tctx, &io.in.blobs,
502                                       "xxxxxx", data_blob(NULL, 0));
503         CHECK_STATUS(status, NT_STATUS_OK);
504         status = smb2_create(tree, tctx, &io);
505         CHECK_STATUS(status, NT_STATUS_OK);
506
507         torture_comment(tctx, "Testing tag length 7\n");
508         ZERO_STRUCT(io.in.blobs);
509         status = smb2_create_blob_add(tctx, &io.in.blobs,
510                                       "xxxxxxx", data_blob(NULL, 0));
511         CHECK_STATUS(status, NT_STATUS_OK);
512         status = smb2_create(tree, tctx, &io);
513         CHECK_STATUS(status, NT_STATUS_OK);
514
515         torture_comment(tctx, "Testing tag length 8\n");
516         ZERO_STRUCT(io.in.blobs);
517         status = smb2_create_blob_add(tctx, &io.in.blobs,
518                                       "xxxxxxxx", data_blob(NULL, 0));
519         CHECK_STATUS(status, NT_STATUS_OK);
520         status = smb2_create(tree, tctx, &io);
521         CHECK_STATUS(status, NT_STATUS_OK);
522
523         torture_comment(tctx, "Testing tag length 16\n");
524         ZERO_STRUCT(io.in.blobs);
525         status = smb2_create_blob_add(tctx, &io.in.blobs,
526                                       "xxxxxxxxxxxxxxxx", data_blob(NULL, 0));
527         CHECK_STATUS(status, NT_STATUS_OK);
528         status = smb2_create(tree, tctx, &io);
529         CHECK_STATUS(status, NT_STATUS_OK);
530
531         torture_comment(tctx, "Testing tag length 17\n");
532         ZERO_STRUCT(io.in.blobs);
533         status = smb2_create_blob_add(tctx, &io.in.blobs,
534                                       "xxxxxxxxxxxxxxxxx", data_blob(NULL, 0));
535         CHECK_STATUS(status, NT_STATUS_OK);
536         status = smb2_create(tree, tctx, &io);
537         CHECK_STATUS(status, NT_STATUS_OK);
538
539         torture_comment(tctx, "Testing tag length 34\n");
540         ZERO_STRUCT(io.in.blobs);
541         status = smb2_create_blob_add(tctx, &io.in.blobs,
542                                       "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
543                                       data_blob(NULL, 0));
544         CHECK_STATUS(status, NT_STATUS_OK);
545         status = smb2_create(tree, tctx, &io);
546         CHECK_STATUS(status, NT_STATUS_OK);
547
548         smb2_deltree(tree, FNAME);
549         
550         return true;
551 }
552
553 #define FAIL_UNLESS(__cond)                                     \
554         do {                                                    \
555                 if (__cond) {} else {                           \
556                         torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n",      \
557                                __location__, #__cond);          \
558                         ret = false; goto done;                 \
559                 }                                               \
560         } while(0)
561
562 /*
563   try creating with acls
564  */
565 static bool test_create_acl_ext(struct torture_context *tctx, struct smb2_tree *tree, bool test_dir)
566 {
567         bool ret = true;
568         struct smb2_create io;
569         NTSTATUS status;
570         struct security_ace ace;
571         struct security_descriptor *sd;
572         struct dom_sid *test_sid;
573         union smb_fileinfo q = {};
574         uint32_t attrib =
575             FILE_ATTRIBUTE_HIDDEN |
576             FILE_ATTRIBUTE_SYSTEM |
577             (test_dir ? FILE_ATTRIBUTE_DIRECTORY : 0);
578         NTSTATUS (*delete_func)(struct smb2_tree *, const char *) =
579             test_dir ? smb2_util_rmdir : smb2_util_unlink;
580
581         smb2_deltree(tree, FNAME);
582
583         ZERO_STRUCT(io);
584         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
585         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
586         io.in.create_disposition = NTCREATEX_DISP_CREATE;
587         io.in.share_access = 
588                 NTCREATEX_SHARE_ACCESS_DELETE |
589                 NTCREATEX_SHARE_ACCESS_READ |
590                 NTCREATEX_SHARE_ACCESS_WRITE;
591         io.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT | 0x00200000 |
592             (test_dir ?  NTCREATEX_OPTIONS_DIRECTORY :
593                 (NTCREATEX_OPTIONS_NON_DIRECTORY_FILE));
594
595         io.in.fname = FNAME;
596
597         torture_comment(tctx, "basic create\n");
598
599         status = smb2_create(tree, tctx, &io);
600         CHECK_STATUS(status, NT_STATUS_OK);
601
602         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
603         q.query_secdesc.in.file.handle = io.out.file.handle;
604         q.query_secdesc.in.secinfo_flags = 
605                 SECINFO_OWNER |
606                 SECINFO_GROUP |
607                 SECINFO_DACL;
608         status = smb2_getinfo_file(tree, tctx, &q);
609         CHECK_STATUS(status, NT_STATUS_OK);
610         sd = q.query_secdesc.out.sd;
611
612         status = smb2_util_close(tree, io.out.file.handle);
613         CHECK_STATUS(status, NT_STATUS_OK);
614         status = delete_func(tree, FNAME);
615         CHECK_STATUS(status, NT_STATUS_OK);
616
617         torture_comment(tctx, "adding a new ACE\n");
618         test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
619
620         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
621         ace.flags = 0;
622         ace.access_mask = SEC_STD_ALL;
623         ace.trustee = *test_sid;
624
625         status = security_descriptor_dacl_add(sd, &ace);
626         CHECK_STATUS(status, NT_STATUS_OK);
627
628         torture_comment(tctx, "creating a file with an initial ACL\n");
629
630         io.in.sec_desc = sd;
631         status = smb2_create(tree, tctx, &io);
632         CHECK_STATUS(status, NT_STATUS_OK);
633
634         FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
635
636         status = smb2_util_close(tree, io.out.file.handle);
637         CHECK_STATUS(status, NT_STATUS_OK);
638         status = delete_func(tree, FNAME);
639         CHECK_STATUS(status, NT_STATUS_OK);
640
641         torture_comment(tctx, "creating with attributes\n");
642
643         io.in.sec_desc = NULL;
644         io.in.file_attributes = attrib;
645         status = smb2_create(tree, tctx, &io);
646         CHECK_STATUS(status, NT_STATUS_OK);
647
648         FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
649
650         status = smb2_util_close(tree, io.out.file.handle);
651         CHECK_STATUS(status, NT_STATUS_OK);
652         status = delete_func(tree, FNAME);
653         CHECK_STATUS(status, NT_STATUS_OK);
654
655         torture_comment(tctx, "creating with attributes and ACL\n");
656
657         io.in.sec_desc = sd;
658         io.in.file_attributes = attrib;
659         status = smb2_create(tree, tctx, &io);
660         CHECK_STATUS(status, NT_STATUS_OK);
661
662         FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
663         FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
664         
665         status = smb2_util_close(tree, io.out.file.handle);
666         CHECK_STATUS(status, NT_STATUS_OK);
667         status = delete_func(tree, FNAME);
668         CHECK_STATUS(status, NT_STATUS_OK);
669
670         torture_comment(tctx, "creating with attributes, ACL and owner\n");
671         sd = security_descriptor_dacl_create(tctx,
672                                         0, SID_WORLD, SID_BUILTIN_USERS,
673                                         SID_WORLD,
674                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
675                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
676                                         0,
677                                         NULL);
678
679         io.in.sec_desc = sd;
680         io.in.file_attributes = attrib;
681         status = smb2_create(tree, tctx, &io);
682         CHECK_STATUS(status, NT_STATUS_OK);
683
684         FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
685         FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
686
687  done:
688         status = smb2_util_close(tree, io.out.file.handle);
689         CHECK_STATUS(status, NT_STATUS_OK);
690         status = delete_func(tree, FNAME);
691         CHECK_STATUS(status, NT_STATUS_OK);
692
693         return ret;
694 }
695
696 /*
697   test SMB2 open
698 */
699 static bool test_smb2_open(struct torture_context *tctx,
700                            struct smb2_tree *tree)
701 {
702         union smb_open io;
703         union smb_fileinfo finfo;
704         const char *fname = DNAME "\\torture_ntcreatex.txt";
705         const char *dname = DNAME "\\torture_ntcreatex.dir";
706         NTSTATUS status;
707         struct smb2_handle h, h1;
708         bool ret = true;
709         int i;
710         struct {
711                 uint32_t create_disp;
712                 bool with_file;
713                 NTSTATUS correct_status;
714         } open_funcs[] = {
715                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
716                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
717                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
718                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
719                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
720                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
721                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
722                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
723                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
724                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
725                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
726                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
727                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
728                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
729         };
730
731         torture_comment(tctx, "Checking SMB2 Open\n");
732
733         smb2_util_unlink(tree, fname);
734         smb2_util_rmdir(tree, dname);
735
736         status = torture_smb2_testdir(tree, DNAME, &h);
737         CHECK_STATUS(status, NT_STATUS_OK);
738
739         ZERO_STRUCT(io.smb2);
740         /* reasonable default parameters */
741         io.generic.level = RAW_OPEN_SMB2;
742         io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
743         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
744         io.smb2.in.alloc_size = 1024*1024;
745         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
746         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
747         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
748         io.smb2.in.create_options = 0;
749         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
750         io.smb2.in.security_flags = 0;
751         io.smb2.in.fname = fname;
752
753         /* test the create disposition */
754         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
755                 if (open_funcs[i].with_file) {
756                         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
757                         status= smb2_create(tree, tctx, &(io.smb2));
758                         if (!NT_STATUS_IS_OK(status)) {
759                                 torture_comment(tctx,
760                                     "Failed to create file %s status %s %d\n",
761                                     fname, nt_errstr(status), i);
762
763                                 ret = false;
764                                 goto done;
765                         }
766                         smb2_util_close(tree, io.smb2.out.file.handle);
767                 }
768                 io.smb2.in.create_disposition = open_funcs[i].create_disp;
769                 status = smb2_create(tree, tctx, &(io.smb2));
770                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
771                         torture_comment(tctx,
772                             "(%s) incorrect status %s should be %s (i=%d "
773                             "with_file=%d open_disp=%d)\n",
774                          __location__, nt_errstr(status),
775                         nt_errstr(open_funcs[i].correct_status),
776                         i, (int)open_funcs[i].with_file,
777                         (int)open_funcs[i].create_disp);
778
779                         ret = false;
780                         goto done;
781                 }
782                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
783                         smb2_util_close(tree, io.smb2.out.file.handle);
784                         smb2_util_unlink(tree, fname);
785                 }
786         }
787
788         /* basic field testing */
789         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
790
791         status = smb2_create(tree, tctx, &(io.smb2));
792         CHECK_STATUS(status, NT_STATUS_OK);
793         h1 = io.smb2.out.file.handle;
794
795         CHECK_VAL(io.smb2.out.oplock_level, 0);
796         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
797         CHECK_NTTIME(io.smb2.out.create_time, create_time);
798         CHECK_NTTIME(io.smb2.out.access_time, access_time);
799         CHECK_NTTIME(io.smb2.out.write_time, write_time);
800         CHECK_NTTIME(io.smb2.out.change_time, change_time);
801         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
802         CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
803         CHECK_ALL_INFO(io.smb2.out.size, size);
804
805         /* check fields when the file already existed */
806         smb2_util_close(tree, h1);
807         smb2_util_unlink(tree, fname);
808
809         status = smb2_create_complex_file(tree, fname, &h1);
810         CHECK_STATUS(status, NT_STATUS_OK);
811
812         smb2_util_close(tree, h1);
813
814         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
815         status = smb2_create(tree, tctx, &(io.smb2));
816         CHECK_STATUS(status, NT_STATUS_OK);
817         h1 = io.smb2.out.file.handle;
818
819         CHECK_VAL(io.smb2.out.oplock_level, 0);
820         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_EXISTED);
821         CHECK_NTTIME(io.smb2.out.create_time, create_time);
822         CHECK_NTTIME(io.smb2.out.access_time, access_time);
823         CHECK_NTTIME(io.smb2.out.write_time, write_time);
824         CHECK_NTTIME(io.smb2.out.change_time, change_time);
825         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
826         CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
827         CHECK_ALL_INFO(io.smb2.out.size, size);
828         smb2_util_close(tree, h1);
829         smb2_util_unlink(tree, fname);
830
831         /* create a directory */
832         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
833         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
834         io.smb2.in.alloc_size = 0;
835         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
836         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
837         io.smb2.in.create_options = 0;
838         io.smb2.in.fname = dname;
839         fname = dname;
840
841         smb2_util_rmdir(tree, fname);
842         smb2_util_unlink(tree, fname);
843
844         io.smb2.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
845         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
846         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
847         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
848                                 NTCREATEX_SHARE_ACCESS_WRITE;
849         status = smb2_create(tree, tctx, &(io.smb2));
850         CHECK_STATUS(status, NT_STATUS_OK);
851         h1 = io.smb2.out.file.handle;
852
853         CHECK_VAL(io.smb2.out.oplock_level, 0);
854         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
855         CHECK_NTTIME(io.smb2.out.create_time, create_time);
856         CHECK_NTTIME(io.smb2.out.access_time, access_time);
857         CHECK_NTTIME(io.smb2.out.write_time, write_time);
858         CHECK_NTTIME(io.smb2.out.change_time, change_time);
859         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
860         CHECK_VAL(io.smb2.out.file_attr & ~FILE_ATTRIBUTE_NONINDEXED,
861                   FILE_ATTRIBUTE_DIRECTORY);
862         CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
863         CHECK_ALL_INFO(io.smb2.out.size, size);
864         CHECK_VAL(io.smb2.out.size, 0);
865         CHECK_VAL(io.smb2.out.alloc_size, 0);
866         smb2_util_unlink(tree, fname);
867
868 done:
869         smb2_util_close(tree, h1);
870         smb2_util_unlink(tree, fname);
871         smb2_deltree(tree, DNAME);
872         return ret;
873 }
874
875 /*
876   test with an already opened and byte range locked file
877 */
878
879 static bool test_smb2_open_brlocked(struct torture_context *tctx,
880                                     struct smb2_tree *tree)
881 {
882         union smb_open io, io1;
883         union smb_lock io2;
884         struct smb2_lock_element lock[1];
885         const char *fname = DNAME "\\torture_ntcreatex.txt";
886         NTSTATUS status;
887         bool ret = true;
888         struct smb2_handle h;
889         char b = 42;
890
891         torture_comment(tctx,
892                 "Testing SMB2 open with a byte range locked file\n");
893
894         smb2_util_unlink(tree, fname);
895
896         status = torture_smb2_testdir(tree, DNAME, &h);
897         CHECK_STATUS(status, NT_STATUS_OK);
898
899         ZERO_STRUCT(io.smb2);
900         io.generic.level = RAW_OPEN_SMB2;
901         io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
902         io.smb2.in.desired_access = 0x2019f;
903         io.smb2.in.alloc_size = 0;
904         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
905         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
906                 NTCREATEX_SHARE_ACCESS_WRITE;
907         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
908         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
909         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
910         io.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
911         io.smb2.in.fname = fname;
912
913         status = smb2_create(tree, tctx, &(io.smb2));
914         CHECK_STATUS(status, NT_STATUS_OK);
915
916         status = smb2_util_write(tree, io.smb2.out.file.handle, &b, 0, 1);
917         CHECK_STATUS(status, NT_STATUS_OK);
918
919         ZERO_STRUCT(io2.smb2);
920         io2.smb2.level = RAW_LOCK_SMB2;
921         io2.smb2.in.file.handle = io.smb2.out.file.handle;
922         io2.smb2.in.lock_count = 1;
923
924         ZERO_STRUCT(lock);
925         lock[0].offset = 0;
926         lock[0].length = 1;
927         lock[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
928                         SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
929         io2.smb2.in.locks = &lock[0];
930         status = smb2_lock(tree, &(io2.smb2));
931         CHECK_STATUS(status, NT_STATUS_OK);
932
933         ZERO_STRUCT(io1.smb2);
934         io1.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
935         io1.smb2.in.desired_access = 0x20196;
936         io1.smb2.in.alloc_size = 0;
937         io1.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
938         io1.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
939                 NTCREATEX_SHARE_ACCESS_WRITE;
940         io1.smb2.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
941         io1.smb2.in.create_options = 0;
942         io1.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
943         io1.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
944         io1.smb2.in.fname = fname;
945
946         status = smb2_create(tree, tctx, &(io1.smb2));
947         CHECK_STATUS(status, NT_STATUS_OK);
948
949         smb2_util_close(tree, io.smb2.out.file.handle);
950         smb2_util_close(tree, io1.smb2.out.file.handle);
951         smb2_util_unlink(tree, fname);
952         smb2_deltree(tree, DNAME);
953
954         return ret;
955 }
956
957 /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
958
959 static bool test_smb2_open_multi(struct torture_context *tctx,
960                                 struct smb2_tree *tree)
961 {
962         const char *fname = "test_oplock.dat";
963         NTSTATUS status;
964         bool ret = true;
965         union smb_open io;
966         struct smb2_tree **trees;
967         struct smb2_request **requests;
968         union smb_open *ios;
969         int i, num_files = 3;
970         int num_ok = 0;
971         int num_collision = 0;
972
973         torture_comment(tctx,
974                 "Testing SMB2 Open with multiple connections\n");
975         trees = talloc_array(tctx, struct smb2_tree *, num_files);
976         requests = talloc_array(tctx, struct smb2_request *, num_files);
977         ios = talloc_array(tctx, union smb_open, num_files);
978         if ((tctx->ev == NULL) || (trees == NULL) || (requests == NULL) ||
979             (ios == NULL)) {
980                 torture_comment(tctx, ("talloc failed\n"));
981                 ret = false;
982                 goto done;
983         }
984
985         tree->session->transport->options.request_timeout = 60;
986
987         for (i=0; i<num_files; i++) {
988                 if (!torture_smb2_connection(tctx, &(trees[i]))) {
989                         torture_comment(tctx,
990                                 "Could not open %d'th connection\n", i);
991                         ret = false;
992                         goto done;
993                 }
994                 trees[i]->session->transport->options.request_timeout = 60;
995         }
996
997         /* cleanup */
998         smb2_util_unlink(tree, fname);
999
1000         /*
1001           base ntcreatex parms
1002         */
1003         ZERO_STRUCT(io.smb2);
1004         io.generic.level = RAW_OPEN_SMB2;
1005         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
1006         io.smb2.in.alloc_size = 0;
1007         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1008         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1009                 NTCREATEX_SHARE_ACCESS_WRITE|
1010                 NTCREATEX_SHARE_ACCESS_DELETE;
1011         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
1012         io.smb2.in.create_options = 0;
1013         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1014         io.smb2.in.security_flags = 0;
1015         io.smb2.in.fname = fname;
1016         io.smb2.in.create_flags = 0;
1017
1018         for (i=0; i<num_files; i++) {
1019                 ios[i] = io;
1020                 requests[i] = smb2_create_send(trees[i], &(ios[i].smb2));
1021                 if (requests[i] == NULL) {
1022                         torture_comment(tctx,
1023                                 "could not send %d'th request\n", i);
1024                         ret = false;
1025                         goto done;
1026                 }
1027         }
1028
1029         torture_comment(tctx, "waiting for replies\n");
1030         while (1) {
1031                 bool unreplied = false;
1032                 for (i=0; i<num_files; i++) {
1033                         if (requests[i] == NULL) {
1034                                 continue;
1035                         }
1036                         if (requests[i]->state < SMB2_REQUEST_DONE) {
1037                                 unreplied = true;
1038                                 break;
1039                         }
1040                         status = smb2_create_recv(requests[i], tctx,
1041                                                   &(ios[i].smb2));
1042
1043                         torture_comment(tctx,
1044                                 "File %d returned status %s\n", i,
1045                                 nt_errstr(status));
1046
1047                         if (NT_STATUS_IS_OK(status)) {
1048                                 num_ok += 1;
1049                         }
1050
1051                         if (NT_STATUS_EQUAL(status,
1052                                             NT_STATUS_OBJECT_NAME_COLLISION)) {
1053                                 num_collision += 1;
1054                         }
1055
1056                         requests[i] = NULL;
1057                 }
1058                 if (!unreplied) {
1059                         break;
1060                 }
1061
1062                 if (tevent_loop_once(tctx->ev) != 0) {
1063                         torture_comment(tctx, "tevent_loop_once failed\n");
1064                         ret = false;
1065                         goto done;
1066                 }
1067         }
1068
1069         if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
1070                 ret = false;
1071         }
1072 done:
1073         smb2_deltree(tree, fname);
1074
1075         return ret;
1076 }
1077
1078 /*
1079   test opening for delete on a read-only attribute file.
1080 */
1081
1082 static bool test_smb2_open_for_delete(struct torture_context *tctx,
1083                                       struct smb2_tree *tree)
1084 {
1085         union smb_open io;
1086         union smb_fileinfo finfo;
1087         const char *fname = DNAME "\\torture_open_for_delete.txt";
1088         NTSTATUS status;
1089         struct smb2_handle h, h1;
1090         bool ret = true;
1091
1092         torture_comment(tctx,
1093                 "Checking SMB2_OPEN for delete on a readonly file.\n");
1094         smb2_util_unlink(tree, fname);
1095         smb2_deltree(tree, fname);
1096
1097         status = torture_smb2_testdir(tree, DNAME, &h);
1098         CHECK_STATUS(status, NT_STATUS_OK);
1099
1100         /* reasonable default parameters */
1101         ZERO_STRUCT(io.smb2);
1102         io.generic.level = RAW_OPEN_SMB2;
1103         io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
1104         io.smb2.in.alloc_size = 0;
1105         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
1106         io.smb2.in.file_attributes = FILE_ATTRIBUTE_READONLY;
1107         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1108         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
1109         io.smb2.in.create_options = 0;
1110         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1111         io.smb2.in.security_flags = 0;
1112         io.smb2.in.fname = fname;
1113
1114         /* Create the readonly file. */
1115
1116         status = smb2_create(tree, tctx, &(io.smb2));
1117         CHECK_STATUS(status, NT_STATUS_OK);
1118         h1 = io.smb2.out.file.handle;
1119
1120         CHECK_VAL(io.smb2.out.oplock_level, 0);
1121         io.smb2.in.create_options = 0;
1122         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
1123         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
1124         smb2_util_close(tree, h1);
1125
1126         /* Now try and open for delete only - should succeed. */
1127         io.smb2.in.desired_access = SEC_STD_DELETE;
1128         io.smb2.in.file_attributes = 0;
1129         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1130                                 NTCREATEX_SHARE_ACCESS_WRITE |
1131                                 NTCREATEX_SHARE_ACCESS_DELETE;
1132         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1133         status = smb2_create(tree, tctx, &(io.smb2));
1134         CHECK_STATUS(status, NT_STATUS_OK);
1135
1136         smb2_util_unlink(tree, fname);
1137
1138         smb2_util_close(tree, h1);
1139         smb2_util_unlink(tree, fname);
1140         smb2_deltree(tree, DNAME);
1141
1142         return ret;
1143 }
1144
1145 /*
1146   test SMB2 open with a leading slash on the path.
1147   Trying to create a directory with a leading slash
1148   should give NT_STATUS_INVALID_PARAMETER error
1149 */
1150 static bool test_smb2_leading_slash(struct torture_context *tctx,
1151                                     struct smb2_tree *tree)
1152 {
1153         union smb_open io;
1154         const char *dnameslash = "\\"DNAME;
1155         NTSTATUS status;
1156         bool ret = true;
1157
1158         torture_comment(tctx,
1159                 "Trying to create a directory with leading slash on path\n");
1160         smb2_deltree(tree, dnameslash);
1161
1162         ZERO_STRUCT(io.smb2);
1163         io.generic.level = RAW_OPEN_SMB2;
1164         io.smb2.in.oplock_level = 0;
1165         io.smb2.in.desired_access = SEC_RIGHTS_DIR_ALL;
1166         io.smb2.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
1167         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1168         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1169                                 NTCREATEX_SHARE_ACCESS_WRITE |
1170                                 NTCREATEX_SHARE_ACCESS_DELETE;
1171         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1172         io.smb2.in.fname = dnameslash;
1173
1174         status = smb2_create(tree, tree, &(io.smb2));
1175         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
1176
1177         smb2_deltree(tree, dnameslash);
1178         return ret;
1179 }
1180
1181 /*
1182   test SMB2 open with an invalid impersonation level.
1183   Should give NT_STATUS_BAD_IMPERSONATION_LEVEL error
1184 */
1185 static bool test_smb2_impersonation_level(struct torture_context *tctx,
1186                                     struct smb2_tree *tree)
1187 {
1188         union smb_open io;
1189         const char *fname = DNAME "\\torture_invalid_impersonation_level.txt";
1190         NTSTATUS status;
1191         struct smb2_handle h;
1192         bool ret = true;
1193
1194         torture_comment(tctx,
1195                 "Testing SMB2 open with an invalid impersonation level.\n");
1196
1197         smb2_util_unlink(tree, fname);
1198         smb2_util_rmdir(tree, DNAME);
1199
1200         status = torture_smb2_testdir(tree, DNAME, &h);
1201         CHECK_STATUS(status, NT_STATUS_OK);
1202
1203         ZERO_STRUCT(io.smb2);
1204         io.generic.level = RAW_OPEN_SMB2;
1205         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
1206         io.smb2.in.alloc_size = 0;
1207         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1208         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1209                 NTCREATEX_SHARE_ACCESS_WRITE|
1210                 NTCREATEX_SHARE_ACCESS_DELETE;
1211         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
1212         io.smb2.in.create_options = 0;
1213         io.smb2.in.impersonation_level = 0x12345678;
1214         io.smb2.in.security_flags = 0;
1215         io.smb2.in.fname = fname;
1216         io.smb2.in.create_flags = 0;
1217
1218         status = smb2_create(tree, tree, &(io.smb2));
1219         CHECK_STATUS(status, NT_STATUS_BAD_IMPERSONATION_LEVEL);
1220
1221         smb2_util_close(tree, h);
1222         smb2_util_unlink(tree, fname);
1223         smb2_deltree(tree, DNAME);
1224         return ret;
1225 }
1226
1227 static bool test_create_acl_file(struct torture_context *tctx,
1228     struct smb2_tree *tree)
1229 {
1230         torture_comment(tctx, "Testing nttrans create with sec_desc on files\n");
1231
1232         return test_create_acl_ext(tctx, tree, false);
1233 }
1234
1235 static bool test_create_acl_dir(struct torture_context *tctx,
1236     struct smb2_tree *tree)
1237 {
1238         torture_comment(tctx, "Testing nttrans create with sec_desc on directories\n");
1239
1240         return test_create_acl_ext(tctx, tree, true);
1241 }
1242
1243 #define CHECK_ACCESS_FLAGS(_fh, flags) do { \
1244         union smb_fileinfo _q; \
1245         _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
1246         _q.access_information.in.file.handle = (_fh); \
1247         status = smb2_getinfo_file(tree, tctx, &_q); \
1248         CHECK_STATUS(status, NT_STATUS_OK); \
1249         if (_q.access_information.out.access_flags != (flags)) { \
1250                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
1251                        __location__, _q.access_information.out.access_flags, (flags)); \
1252                 ret = false; \
1253                 goto done; \
1254         } \
1255 } while (0)
1256
1257 /*
1258  * Test creating a file with a NULL DACL.
1259  */
1260 static bool test_create_null_dacl(struct torture_context *tctx,
1261     struct smb2_tree *tree)
1262 {
1263         NTSTATUS status;
1264         struct smb2_create io;
1265         const char *fname = "nulldacl.txt";
1266         bool ret = true;
1267         struct smb2_handle handle;
1268         union smb_fileinfo q;
1269         union smb_setfileinfo s;
1270         struct security_descriptor *sd = security_descriptor_initialise(tctx);
1271         struct security_acl dacl;
1272
1273         torture_comment(tctx, "TESTING SEC_DESC WITH A NULL DACL\n");
1274
1275         smb2_util_unlink(tree, fname);
1276
1277         ZERO_STRUCT(io);
1278         io.level = RAW_OPEN_SMB2;
1279         io.in.create_flags = 0;
1280         io.in.desired_access = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC
1281                 | SEC_STD_WRITE_OWNER;
1282         io.in.create_options = 0;
1283         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1284         io.in.share_access =
1285                 NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1286         io.in.alloc_size = 0;
1287         io.in.create_disposition = NTCREATEX_DISP_CREATE;
1288         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
1289         io.in.security_flags = 0;
1290         io.in.fname = fname;
1291         io.in.sec_desc = sd;
1292         /* XXX create_options ? */
1293         io.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
1294                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
1295                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
1296                                           0x00200000;
1297
1298         torture_comment(tctx, "creating a file with a empty sd\n");
1299         status = smb2_create(tree, tctx, &io);
1300         CHECK_STATUS(status, NT_STATUS_OK);
1301         handle = io.out.file.handle;
1302
1303         torture_comment(tctx, "get the original sd\n");
1304         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1305         q.query_secdesc.in.file.handle = handle;
1306         q.query_secdesc.in.secinfo_flags =
1307                 SECINFO_OWNER |
1308                 SECINFO_GROUP |
1309                 SECINFO_DACL;
1310         status = smb2_getinfo_file(tree, tctx, &q);
1311         CHECK_STATUS(status, NT_STATUS_OK);
1312
1313         /*
1314          * Testing the created DACL,
1315          * the server should add the inherited DACL
1316          * when SEC_DESC_DACL_PRESENT isn't specified
1317          */
1318         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1319                 ret = false;
1320                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1321         }
1322         if (q.query_secdesc.out.sd->dacl == NULL) {
1323                 ret = false;
1324                 torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
1325         }
1326
1327         torture_comment(tctx, "set NULL DACL\n");
1328         sd->type |= SEC_DESC_DACL_PRESENT;
1329
1330         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1331         s.set_secdesc.in.file.handle = handle;
1332         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1333         s.set_secdesc.in.sd = sd;
1334         status = smb2_setinfo_file(tree, &s);
1335         CHECK_STATUS(status, NT_STATUS_OK);
1336
1337         torture_comment(tctx, "get the sd\n");
1338         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1339         q.query_secdesc.in.file.handle = handle;
1340         q.query_secdesc.in.secinfo_flags =
1341                 SECINFO_OWNER |
1342                 SECINFO_GROUP |
1343                 SECINFO_DACL;
1344         status = smb2_getinfo_file(tree, tctx, &q);
1345         CHECK_STATUS(status, NT_STATUS_OK);
1346
1347         /* Testing the modified DACL */
1348         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1349                 ret = false;
1350                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1351         }
1352         if (q.query_secdesc.out.sd->dacl != NULL) {
1353                 ret = false;
1354                 torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
1355         }
1356
1357         io.in.create_disposition = NTCREATEX_DISP_OPEN;
1358
1359         torture_comment(tctx, "try open for read control\n");
1360         io.in.desired_access = SEC_STD_READ_CONTROL;
1361         status = smb2_create(tree, tctx, &io);
1362         CHECK_STATUS(status, NT_STATUS_OK);
1363         CHECK_ACCESS_FLAGS(io.out.file.handle,
1364                 SEC_STD_READ_CONTROL);
1365         smb2_util_close(tree, io.out.file.handle);
1366
1367         torture_comment(tctx, "try open for write\n");
1368         io.in.desired_access = SEC_FILE_WRITE_DATA;
1369         status = smb2_create(tree, tctx, &io);
1370         CHECK_STATUS(status, NT_STATUS_OK);
1371         CHECK_ACCESS_FLAGS(io.out.file.handle,
1372                 SEC_FILE_WRITE_DATA);
1373         smb2_util_close(tree, io.out.file.handle);
1374
1375         torture_comment(tctx, "try open for read\n");
1376         io.in.desired_access = SEC_FILE_READ_DATA;
1377         status = smb2_create(tree, tctx, &io);
1378         CHECK_STATUS(status, NT_STATUS_OK);
1379         CHECK_ACCESS_FLAGS(io.out.file.handle,
1380                 SEC_FILE_READ_DATA);
1381         smb2_util_close(tree, io.out.file.handle);
1382
1383         torture_comment(tctx, "try open for generic write\n");
1384         io.in.desired_access = SEC_GENERIC_WRITE;
1385         status = smb2_create(tree, tctx, &io);
1386         CHECK_STATUS(status, NT_STATUS_OK);
1387         CHECK_ACCESS_FLAGS(io.out.file.handle,
1388                 SEC_RIGHTS_FILE_WRITE);
1389         smb2_util_close(tree, io.out.file.handle);
1390
1391         torture_comment(tctx, "try open for generic read\n");
1392         io.in.desired_access = SEC_GENERIC_READ;
1393         status = smb2_create(tree, tctx, &io);
1394         CHECK_STATUS(status, NT_STATUS_OK);
1395         CHECK_ACCESS_FLAGS(io.out.file.handle,
1396                 SEC_RIGHTS_FILE_READ);
1397         smb2_util_close(tree, io.out.file.handle);
1398
1399         torture_comment(tctx, "set DACL with 0 aces\n");
1400         ZERO_STRUCT(dacl);
1401         dacl.revision = SECURITY_ACL_REVISION_NT4;
1402         dacl.num_aces = 0;
1403         sd->dacl = &dacl;
1404
1405         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1406         s.set_secdesc.in.file.handle = handle;
1407         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1408         s.set_secdesc.in.sd = sd;
1409         status = smb2_setinfo_file(tree, &s);
1410         CHECK_STATUS(status, NT_STATUS_OK);
1411
1412         torture_comment(tctx, "get the sd\n");
1413         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1414         q.query_secdesc.in.file.handle = handle;
1415         q.query_secdesc.in.secinfo_flags =
1416                 SECINFO_OWNER |
1417                 SECINFO_GROUP |
1418                 SECINFO_DACL;
1419         status = smb2_getinfo_file(tree, tctx, &q);
1420         CHECK_STATUS(status, NT_STATUS_OK);
1421
1422         /* Testing the modified DACL */
1423         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1424                 ret = false;
1425                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1426         }
1427         if (q.query_secdesc.out.sd->dacl == NULL) {
1428                 ret = false;
1429                 torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
1430         }
1431         if (q.query_secdesc.out.sd->dacl->num_aces != 0) {
1432                 torture_result(tctx, TORTURE_FAIL, "DACL has %u aces!\n",
1433                        q.query_secdesc.out.sd->dacl->num_aces);
1434                 ret = false;
1435                 goto done;
1436         }
1437
1438         torture_comment(tctx, "try open for read control\n");
1439         io.in.desired_access = SEC_STD_READ_CONTROL;
1440         status = smb2_create(tree, tctx, &io);
1441         CHECK_STATUS(status, NT_STATUS_OK);
1442         CHECK_ACCESS_FLAGS(io.out.file.handle,
1443                 SEC_STD_READ_CONTROL);
1444         smb2_util_close(tree, io.out.file.handle);
1445
1446         torture_comment(tctx, "try open for write => access_denied\n");
1447         io.in.desired_access = SEC_FILE_WRITE_DATA;
1448         status = smb2_create(tree, tctx, &io);
1449         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1450                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1451         } else {
1452                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1453         }
1454
1455         torture_comment(tctx, "try open for read => access_denied\n");
1456         io.in.desired_access = SEC_FILE_READ_DATA;
1457         status = smb2_create(tree, tctx, &io);
1458         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1459                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1460         } else {
1461                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1462         }
1463
1464         torture_comment(tctx, "try open for generic write => access_denied\n");
1465         io.in.desired_access = SEC_GENERIC_WRITE;
1466         status = smb2_create(tree, tctx, &io);
1467         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1468                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1469         } else {
1470                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1471         }
1472
1473         torture_comment(tctx, "try open for generic read => access_denied\n");
1474         io.in.desired_access = SEC_GENERIC_READ;
1475         status = smb2_create(tree, tctx, &io);
1476         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1477                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1478         } else {
1479                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1480         }
1481
1482         torture_comment(tctx, "set empty sd\n");
1483         sd->type &= ~SEC_DESC_DACL_PRESENT;
1484         sd->dacl = NULL;
1485
1486         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1487         s.set_secdesc.in.file.handle = handle;
1488         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1489         s.set_secdesc.in.sd = sd;
1490         status = smb2_setinfo_file(tree, &s);
1491         CHECK_STATUS(status, NT_STATUS_OK);
1492
1493         torture_comment(tctx, "get the sd\n");
1494         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1495         q.query_secdesc.in.file.handle = handle;
1496         q.query_secdesc.in.secinfo_flags =
1497                 SECINFO_OWNER |
1498                 SECINFO_GROUP |
1499                 SECINFO_DACL;
1500         status = smb2_getinfo_file(tree, tctx, &q);
1501         CHECK_STATUS(status, NT_STATUS_OK);
1502
1503         /* Testing the modified DACL */
1504         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1505                 ret = false;
1506                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1507         }
1508         if (q.query_secdesc.out.sd->dacl != NULL) {
1509                 ret = false;
1510                 torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
1511         }
1512 done:
1513         smb2_util_close(tree, handle);
1514         smb2_util_unlink(tree, fname);
1515         smb2_tdis(tree);
1516         smb2_logoff(tree->session);
1517         return ret;
1518 }
1519
1520 /*
1521   test SMB2 mkdir with OPEN_IF on the same name twice.
1522   Must use 2 connections to hit the race.
1523 */
1524
1525 static bool test_mkdir_dup(struct torture_context *tctx,
1526                                 struct smb2_tree *tree)
1527 {
1528         const char *fname = "mkdir_dup";
1529         NTSTATUS status;
1530         bool ret = true;
1531         union smb_open io;
1532         struct smb2_tree **trees;
1533         struct smb2_request **requests;
1534         union smb_open *ios;
1535         int i, num_files = 2;
1536         int num_ok = 0;
1537         int num_created = 0;
1538         int num_existed = 0;
1539
1540         torture_comment(tctx,
1541                 "Testing SMB2 Create Directory with multiple connections\n");
1542         trees = talloc_array(tctx, struct smb2_tree *, num_files);
1543         requests = talloc_array(tctx, struct smb2_request *, num_files);
1544         ios = talloc_array(tctx, union smb_open, num_files);
1545         if ((tctx->ev == NULL) || (trees == NULL) || (requests == NULL) ||
1546             (ios == NULL)) {
1547                 torture_fail(tctx, ("talloc failed\n"));
1548                 ret = false;
1549                 goto done;
1550         }
1551
1552         tree->session->transport->options.request_timeout = 60;
1553
1554         for (i=0; i<num_files; i++) {
1555                 if (!torture_smb2_connection(tctx, &(trees[i]))) {
1556                         torture_fail(tctx,
1557                                 talloc_asprintf(tctx,
1558                                         "Could not open %d'th connection\n", i));
1559                         ret = false;
1560                         goto done;
1561                 }
1562                 trees[i]->session->transport->options.request_timeout = 60;
1563         }
1564
1565         /* cleanup */
1566         smb2_util_unlink(tree, fname);
1567         smb2_util_rmdir(tree, fname);
1568
1569         /*
1570           base ntcreatex parms
1571         */
1572         ZERO_STRUCT(io.smb2);
1573         io.generic.level = RAW_OPEN_SMB2;
1574         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
1575         io.smb2.in.alloc_size = 0;
1576         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1577         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1578                 NTCREATEX_SHARE_ACCESS_WRITE|
1579                 NTCREATEX_SHARE_ACCESS_DELETE;
1580         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1581         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1582         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1583         io.smb2.in.security_flags = 0;
1584         io.smb2.in.fname = fname;
1585         io.smb2.in.create_flags = 0;
1586
1587         for (i=0; i<num_files; i++) {
1588                 ios[i] = io;
1589                 requests[i] = smb2_create_send(trees[i], &(ios[i].smb2));
1590                 if (requests[i] == NULL) {
1591                         torture_fail(tctx,
1592                                 talloc_asprintf(tctx,
1593                                 "could not send %d'th request\n", i));
1594                         ret = false;
1595                         goto done;
1596                 }
1597         }
1598
1599         torture_comment(tctx, "waiting for replies\n");
1600         while (1) {
1601                 bool unreplied = false;
1602                 for (i=0; i<num_files; i++) {
1603                         if (requests[i] == NULL) {
1604                                 continue;
1605                         }
1606                         if (requests[i]->state < SMB2_REQUEST_DONE) {
1607                                 unreplied = true;
1608                                 break;
1609                         }
1610                         status = smb2_create_recv(requests[i], tctx,
1611                                                   &(ios[i].smb2));
1612
1613                         if (NT_STATUS_IS_OK(status)) {
1614                                 num_ok += 1;
1615
1616                                 if (ios[i].smb2.out.create_action ==
1617                                                 NTCREATEX_ACTION_CREATED) {
1618                                         num_created++;
1619                                 }
1620                                 if (ios[i].smb2.out.create_action ==
1621                                                 NTCREATEX_ACTION_EXISTED) {
1622                                         num_existed++;
1623                                 }
1624                         } else {
1625                                 torture_fail(tctx,
1626                                         talloc_asprintf(tctx,
1627                                         "File %d returned status %s\n", i,
1628                                         nt_errstr(status)));
1629                         }
1630
1631
1632                         requests[i] = NULL;
1633                 }
1634                 if (!unreplied) {
1635                         break;
1636                 }
1637
1638                 if (tevent_loop_once(tctx->ev) != 0) {
1639                         torture_fail(tctx, "tevent_loop_once failed\n");
1640                         ret = false;
1641                         goto done;
1642                 }
1643         }
1644
1645         if (num_ok != 2) {
1646                 torture_fail(tctx,
1647                         talloc_asprintf(tctx,
1648                         "num_ok == %d\n", num_ok));
1649                 ret = false;
1650         }
1651         if (num_created != 1) {
1652                 torture_fail(tctx,
1653                         talloc_asprintf(tctx,
1654                         "num_created == %d\n", num_created));
1655                 ret = false;
1656         }
1657         if (num_existed != 1) {
1658                 torture_fail(tctx,
1659                         talloc_asprintf(tctx,
1660                         "num_existed == %d\n", num_existed));
1661                 ret = false;
1662         }
1663 done:
1664         smb2_deltree(tree, fname);
1665
1666         return ret;
1667 }
1668
1669 /*
1670   test directory creation with an initial allocation size > 0
1671 */
1672 static bool test_dir_alloc_size(struct torture_context *tctx,
1673                                 struct smb2_tree *tree)
1674 {
1675         bool ret = true;
1676         const char *dname = DNAME "\\torture_alloc_size.dir";
1677         NTSTATUS status;
1678         struct smb2_create c;
1679         struct smb2_handle h1 = {{0}}, h2;
1680
1681         torture_comment(tctx, "Checking initial allocation size on directories\n");
1682
1683         smb2_deltree(tree, dname);
1684
1685         status = torture_smb2_testdir(tree, DNAME, &h1);
1686         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
1687
1688         ZERO_STRUCT(c);
1689         c.in.create_disposition = NTCREATEX_DISP_CREATE;
1690         c.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1691         c.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1692         c.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1693         c.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1694         c.in.fname = dname;
1695         /*
1696          * An insanely large value so we can check the value is
1697          * ignored: Samba either returns 0 (current behaviour), or,
1698          * once vfswrap_get_alloc_size() is fixed to allow retrieving
1699          * the allocated size for directories, returns
1700          * smb_roundup(..., stat.st_size) which would be 1 MB by
1701          * default.
1702          *
1703          * Windows returns 0 for emtpy directories, once directories
1704          * have a few entries it starts replying with values > 0.
1705          */
1706         c.in.alloc_size = 1024*1024*1024;
1707
1708         status = smb2_create(tree, tctx, &c);
1709         h2 = c.out.file.handle;
1710         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1711                                         "dir create with initial alloc size failed");
1712
1713         smb2_util_close(tree, h2);
1714
1715         torture_comment(tctx, "Got directory alloc size: %ju\n", (uintmax_t)c.out.alloc_size);
1716
1717         /*
1718          * See above for the rational for this test
1719          */
1720         if (c.out.alloc_size > 1024*1024) {
1721                 torture_fail_goto(tctx, done, talloc_asprintf(tctx, "bad alloc size: %ju",
1722                                                               (uintmax_t)c.out.alloc_size));
1723         }
1724
1725 done:
1726         if (!smb2_util_handle_empty(h1)) {
1727                 smb2_util_close(tree, h1);
1728         }
1729         smb2_deltree(tree, DNAME);
1730         return ret;
1731 }
1732
1733 /*
1734    basic testing of SMB2 read
1735 */
1736 struct torture_suite *torture_smb2_create_init(void)
1737 {
1738         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "create");
1739
1740         torture_suite_add_1smb2_test(suite, "gentest", test_create_gentest);
1741         torture_suite_add_1smb2_test(suite, "blob", test_create_blob);
1742         torture_suite_add_1smb2_test(suite, "open", test_smb2_open);
1743         torture_suite_add_1smb2_test(suite, "brlocked", test_smb2_open_brlocked);
1744         torture_suite_add_1smb2_test(suite, "multi", test_smb2_open_multi);
1745         torture_suite_add_1smb2_test(suite, "delete", test_smb2_open_for_delete);
1746         torture_suite_add_1smb2_test(suite, "leading-slash", test_smb2_leading_slash);
1747         torture_suite_add_1smb2_test(suite, "impersonation", test_smb2_impersonation_level);
1748         torture_suite_add_1smb2_test(suite, "aclfile", test_create_acl_file);
1749         torture_suite_add_1smb2_test(suite, "acldir", test_create_acl_dir);
1750         torture_suite_add_1smb2_test(suite, "nulldacl", test_create_null_dacl);
1751         torture_suite_add_1smb2_test(suite, "mkdir-dup", test_mkdir_dup);
1752         torture_suite_add_1smb2_test(suite, "dir-alloc-size", test_dir_alloc_size);
1753
1754         suite->description = talloc_strdup(suite, "SMB2-CREATE tests");
1755
1756         return suite;
1757 }