s4: torture: Add a TALLOC_CTX * to torture_smb2_create_init().
[vlendec/samba-autobuild/.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         ZERO_STRUCT(ace);
582
583         smb2_deltree(tree, FNAME);
584
585         ZERO_STRUCT(io);
586         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
587         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
588         io.in.create_disposition = NTCREATEX_DISP_CREATE;
589         io.in.share_access = 
590                 NTCREATEX_SHARE_ACCESS_DELETE |
591                 NTCREATEX_SHARE_ACCESS_READ |
592                 NTCREATEX_SHARE_ACCESS_WRITE;
593         io.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT | 0x00200000 |
594             (test_dir ?  NTCREATEX_OPTIONS_DIRECTORY :
595                 (NTCREATEX_OPTIONS_NON_DIRECTORY_FILE));
596
597         io.in.fname = FNAME;
598
599         torture_comment(tctx, "basic create\n");
600
601         status = smb2_create(tree, tctx, &io);
602         CHECK_STATUS(status, NT_STATUS_OK);
603
604         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
605         q.query_secdesc.in.file.handle = io.out.file.handle;
606         q.query_secdesc.in.secinfo_flags = 
607                 SECINFO_OWNER |
608                 SECINFO_GROUP |
609                 SECINFO_DACL;
610         status = smb2_getinfo_file(tree, tctx, &q);
611         CHECK_STATUS(status, NT_STATUS_OK);
612         sd = q.query_secdesc.out.sd;
613
614         status = smb2_util_close(tree, io.out.file.handle);
615         CHECK_STATUS(status, NT_STATUS_OK);
616         status = delete_func(tree, FNAME);
617         CHECK_STATUS(status, NT_STATUS_OK);
618
619         torture_comment(tctx, "adding a new ACE\n");
620         test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
621
622         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
623         ace.flags = 0;
624         ace.access_mask = SEC_STD_ALL;
625         ace.trustee = *test_sid;
626
627         status = security_descriptor_dacl_add(sd, &ace);
628         CHECK_STATUS(status, NT_STATUS_OK);
629
630         torture_comment(tctx, "creating a file with an initial ACL\n");
631
632         io.in.sec_desc = sd;
633         status = smb2_create(tree, tctx, &io);
634         CHECK_STATUS(status, NT_STATUS_OK);
635
636         FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
637
638         status = smb2_util_close(tree, io.out.file.handle);
639         CHECK_STATUS(status, NT_STATUS_OK);
640         status = delete_func(tree, FNAME);
641         CHECK_STATUS(status, NT_STATUS_OK);
642
643         torture_comment(tctx, "creating with attributes\n");
644
645         io.in.sec_desc = NULL;
646         io.in.file_attributes = attrib;
647         status = smb2_create(tree, tctx, &io);
648         CHECK_STATUS(status, NT_STATUS_OK);
649
650         FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
651
652         status = smb2_util_close(tree, io.out.file.handle);
653         CHECK_STATUS(status, NT_STATUS_OK);
654         status = delete_func(tree, FNAME);
655         CHECK_STATUS(status, NT_STATUS_OK);
656
657         torture_comment(tctx, "creating with attributes and ACL\n");
658
659         io.in.sec_desc = sd;
660         io.in.file_attributes = attrib;
661         status = smb2_create(tree, tctx, &io);
662         CHECK_STATUS(status, NT_STATUS_OK);
663
664         FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
665         FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
666         
667         status = smb2_util_close(tree, io.out.file.handle);
668         CHECK_STATUS(status, NT_STATUS_OK);
669         status = delete_func(tree, FNAME);
670         CHECK_STATUS(status, NT_STATUS_OK);
671
672         torture_comment(tctx, "creating with attributes, ACL and owner\n");
673         sd = security_descriptor_dacl_create(tctx,
674                                         0, SID_WORLD, SID_BUILTIN_USERS,
675                                         SID_WORLD,
676                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
677                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
678                                         0,
679                                         NULL);
680
681         io.in.sec_desc = sd;
682         io.in.file_attributes = attrib;
683         status = smb2_create(tree, tctx, &io);
684         CHECK_STATUS(status, NT_STATUS_OK);
685
686         FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
687         FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
688
689  done:
690         status = smb2_util_close(tree, io.out.file.handle);
691         CHECK_STATUS(status, NT_STATUS_OK);
692         status = delete_func(tree, FNAME);
693         CHECK_STATUS(status, NT_STATUS_OK);
694
695         return ret;
696 }
697
698 /*
699   test SMB2 open
700 */
701 static bool test_smb2_open(struct torture_context *tctx,
702                            struct smb2_tree *tree)
703 {
704         union smb_open io;
705         union smb_fileinfo finfo;
706         const char *fname = DNAME "\\torture_ntcreatex.txt";
707         const char *dname = DNAME "\\torture_ntcreatex.dir";
708         NTSTATUS status;
709         struct smb2_handle h = {{0}};
710         struct smb2_handle h1 = {{0}};
711         bool ret = true;
712         int i;
713         struct {
714                 uint32_t create_disp;
715                 bool with_file;
716                 NTSTATUS correct_status;
717         } open_funcs[] = {
718                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
719                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
720                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
721                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
722                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
723                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
724                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
725                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
726                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
727                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
728                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
729                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
730                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
731                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
732         };
733
734         torture_comment(tctx, "Checking SMB2 Open\n");
735
736         smb2_util_unlink(tree, fname);
737         smb2_util_rmdir(tree, dname);
738
739         status = torture_smb2_testdir(tree, DNAME, &h);
740         CHECK_STATUS(status, NT_STATUS_OK);
741
742         ZERO_STRUCT(io.smb2);
743         /* reasonable default parameters */
744         io.generic.level = RAW_OPEN_SMB2;
745         io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
746         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
747         io.smb2.in.alloc_size = 1024*1024;
748         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
749         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
750         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
751         io.smb2.in.create_options = 0;
752         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
753         io.smb2.in.security_flags = 0;
754         io.smb2.in.fname = fname;
755
756         /* test the create disposition */
757         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
758                 if (open_funcs[i].with_file) {
759                         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
760                         status= smb2_create(tree, tctx, &(io.smb2));
761                         if (!NT_STATUS_IS_OK(status)) {
762                                 torture_comment(tctx,
763                                     "Failed to create file %s status %s %d\n",
764                                     fname, nt_errstr(status), i);
765
766                                 ret = false;
767                                 goto done;
768                         }
769                         smb2_util_close(tree, io.smb2.out.file.handle);
770                 }
771                 io.smb2.in.create_disposition = open_funcs[i].create_disp;
772                 status = smb2_create(tree, tctx, &(io.smb2));
773                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
774                         torture_comment(tctx,
775                             "(%s) incorrect status %s should be %s (i=%d "
776                             "with_file=%d open_disp=%d)\n",
777                          __location__, nt_errstr(status),
778                         nt_errstr(open_funcs[i].correct_status),
779                         i, (int)open_funcs[i].with_file,
780                         (int)open_funcs[i].create_disp);
781
782                         ret = false;
783                         goto done;
784                 }
785                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
786                         smb2_util_close(tree, io.smb2.out.file.handle);
787                         smb2_util_unlink(tree, fname);
788                 }
789         }
790
791         /* basic field testing */
792         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
793
794         status = smb2_create(tree, tctx, &(io.smb2));
795         CHECK_STATUS(status, NT_STATUS_OK);
796         h1 = io.smb2.out.file.handle;
797
798         CHECK_VAL(io.smb2.out.oplock_level, 0);
799         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
800         CHECK_NTTIME(io.smb2.out.create_time, create_time);
801         CHECK_NTTIME(io.smb2.out.access_time, access_time);
802         CHECK_NTTIME(io.smb2.out.write_time, write_time);
803         CHECK_NTTIME(io.smb2.out.change_time, change_time);
804         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
805         CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
806         CHECK_ALL_INFO(io.smb2.out.size, size);
807
808         /* check fields when the file already existed */
809         smb2_util_close(tree, h1);
810         smb2_util_unlink(tree, fname);
811
812         status = smb2_create_complex_file(tctx, tree, fname, &h1);
813         CHECK_STATUS(status, NT_STATUS_OK);
814
815         smb2_util_close(tree, h1);
816
817         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
818         status = smb2_create(tree, tctx, &(io.smb2));
819         CHECK_STATUS(status, NT_STATUS_OK);
820         h1 = io.smb2.out.file.handle;
821
822         CHECK_VAL(io.smb2.out.oplock_level, 0);
823         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_EXISTED);
824         CHECK_NTTIME(io.smb2.out.create_time, create_time);
825         CHECK_NTTIME(io.smb2.out.access_time, access_time);
826         CHECK_NTTIME(io.smb2.out.write_time, write_time);
827         CHECK_NTTIME(io.smb2.out.change_time, change_time);
828         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
829         CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
830         CHECK_ALL_INFO(io.smb2.out.size, size);
831         smb2_util_close(tree, h1);
832         smb2_util_unlink(tree, fname);
833
834         /* create a directory */
835         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
836         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
837         io.smb2.in.alloc_size = 0;
838         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
839         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
840         io.smb2.in.create_options = 0;
841         io.smb2.in.fname = dname;
842         fname = dname;
843
844         smb2_util_rmdir(tree, fname);
845         smb2_util_unlink(tree, fname);
846
847         io.smb2.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
848         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
849         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
850         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
851                                 NTCREATEX_SHARE_ACCESS_WRITE;
852         status = smb2_create(tree, tctx, &(io.smb2));
853         CHECK_STATUS(status, NT_STATUS_OK);
854         h1 = io.smb2.out.file.handle;
855
856         CHECK_VAL(io.smb2.out.oplock_level, 0);
857         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
858         CHECK_NTTIME(io.smb2.out.create_time, create_time);
859         CHECK_NTTIME(io.smb2.out.access_time, access_time);
860         CHECK_NTTIME(io.smb2.out.write_time, write_time);
861         CHECK_NTTIME(io.smb2.out.change_time, change_time);
862         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
863         CHECK_VAL(io.smb2.out.file_attr & ~FILE_ATTRIBUTE_NONINDEXED,
864                   FILE_ATTRIBUTE_DIRECTORY);
865         CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
866         CHECK_ALL_INFO(io.smb2.out.size, size);
867         CHECK_VAL(io.smb2.out.size, 0);
868         CHECK_VAL(io.smb2.out.alloc_size, 0);
869         smb2_util_unlink(tree, fname);
870
871 done:
872         smb2_util_close(tree, h1);
873         smb2_util_unlink(tree, fname);
874         smb2_deltree(tree, DNAME);
875         return ret;
876 }
877
878 /*
879   test with an already opened and byte range locked file
880 */
881
882 static bool test_smb2_open_brlocked(struct torture_context *tctx,
883                                     struct smb2_tree *tree)
884 {
885         union smb_open io, io1;
886         union smb_lock io2;
887         struct smb2_lock_element lock[1];
888         const char *fname = DNAME "\\torture_ntcreatex.txt";
889         NTSTATUS status;
890         bool ret = true;
891         struct smb2_handle h;
892         char b = 42;
893
894         torture_comment(tctx,
895                 "Testing SMB2 open with a byte range locked file\n");
896
897         smb2_util_unlink(tree, fname);
898
899         status = torture_smb2_testdir(tree, DNAME, &h);
900         CHECK_STATUS(status, NT_STATUS_OK);
901
902         ZERO_STRUCT(io.smb2);
903         io.generic.level = RAW_OPEN_SMB2;
904         io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
905         io.smb2.in.desired_access = 0x2019f;
906         io.smb2.in.alloc_size = 0;
907         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
908         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
909                 NTCREATEX_SHARE_ACCESS_WRITE;
910         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
911         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
912         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
913         io.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
914         io.smb2.in.fname = fname;
915
916         status = smb2_create(tree, tctx, &(io.smb2));
917         CHECK_STATUS(status, NT_STATUS_OK);
918
919         status = smb2_util_write(tree, io.smb2.out.file.handle, &b, 0, 1);
920         CHECK_STATUS(status, NT_STATUS_OK);
921
922         ZERO_STRUCT(io2.smb2);
923         io2.smb2.level = RAW_LOCK_SMB2;
924         io2.smb2.in.file.handle = io.smb2.out.file.handle;
925         io2.smb2.in.lock_count = 1;
926
927         ZERO_STRUCT(lock);
928         lock[0].offset = 0;
929         lock[0].length = 1;
930         lock[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
931                         SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
932         io2.smb2.in.locks = &lock[0];
933         status = smb2_lock(tree, &(io2.smb2));
934         CHECK_STATUS(status, NT_STATUS_OK);
935
936         ZERO_STRUCT(io1.smb2);
937         io1.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
938         io1.smb2.in.desired_access = 0x20196;
939         io1.smb2.in.alloc_size = 0;
940         io1.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
941         io1.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
942                 NTCREATEX_SHARE_ACCESS_WRITE;
943         io1.smb2.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
944         io1.smb2.in.create_options = 0;
945         io1.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
946         io1.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
947         io1.smb2.in.fname = fname;
948
949         status = smb2_create(tree, tctx, &(io1.smb2));
950         CHECK_STATUS(status, NT_STATUS_OK);
951
952         smb2_util_close(tree, io.smb2.out.file.handle);
953         smb2_util_close(tree, io1.smb2.out.file.handle);
954         smb2_util_unlink(tree, fname);
955         smb2_deltree(tree, DNAME);
956
957         return ret;
958 }
959
960 /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
961
962 static bool test_smb2_open_multi(struct torture_context *tctx,
963                                 struct smb2_tree *tree)
964 {
965         const char *fname = "test_oplock.dat";
966         NTSTATUS status;
967         bool ret = true;
968         union smb_open io;
969         struct smb2_tree **trees;
970         struct smb2_request **requests;
971         union smb_open *ios;
972         int i, num_files = 3;
973         int num_ok = 0;
974         int num_collision = 0;
975
976         torture_comment(tctx,
977                 "Testing SMB2 Open with multiple connections\n");
978         trees = talloc_array(tctx, struct smb2_tree *, num_files);
979         requests = talloc_array(tctx, struct smb2_request *, num_files);
980         ios = talloc_array(tctx, union smb_open, num_files);
981         if ((tctx->ev == NULL) || (trees == NULL) || (requests == NULL) ||
982             (ios == NULL)) {
983                 torture_comment(tctx, ("talloc failed\n"));
984                 ret = false;
985                 goto done;
986         }
987
988         tree->session->transport->options.request_timeout = 60;
989
990         for (i=0; i<num_files; i++) {
991                 if (!torture_smb2_connection(tctx, &(trees[i]))) {
992                         torture_comment(tctx,
993                                 "Could not open %d'th connection\n", i);
994                         ret = false;
995                         goto done;
996                 }
997                 trees[i]->session->transport->options.request_timeout = 60;
998         }
999
1000         /* cleanup */
1001         smb2_util_unlink(tree, fname);
1002
1003         /*
1004           base ntcreatex parms
1005         */
1006         ZERO_STRUCT(io.smb2);
1007         io.generic.level = RAW_OPEN_SMB2;
1008         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
1009         io.smb2.in.alloc_size = 0;
1010         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1011         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1012                 NTCREATEX_SHARE_ACCESS_WRITE|
1013                 NTCREATEX_SHARE_ACCESS_DELETE;
1014         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
1015         io.smb2.in.create_options = 0;
1016         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1017         io.smb2.in.security_flags = 0;
1018         io.smb2.in.fname = fname;
1019         io.smb2.in.create_flags = 0;
1020
1021         for (i=0; i<num_files; i++) {
1022                 ios[i] = io;
1023                 requests[i] = smb2_create_send(trees[i], &(ios[i].smb2));
1024                 if (requests[i] == NULL) {
1025                         torture_comment(tctx,
1026                                 "could not send %d'th request\n", i);
1027                         ret = false;
1028                         goto done;
1029                 }
1030         }
1031
1032         torture_comment(tctx, "waiting for replies\n");
1033         while (1) {
1034                 bool unreplied = false;
1035                 for (i=0; i<num_files; i++) {
1036                         if (requests[i] == NULL) {
1037                                 continue;
1038                         }
1039                         if (requests[i]->state < SMB2_REQUEST_DONE) {
1040                                 unreplied = true;
1041                                 break;
1042                         }
1043                         status = smb2_create_recv(requests[i], tctx,
1044                                                   &(ios[i].smb2));
1045
1046                         torture_comment(tctx,
1047                                 "File %d returned status %s\n", i,
1048                                 nt_errstr(status));
1049
1050                         if (NT_STATUS_IS_OK(status)) {
1051                                 num_ok += 1;
1052                         }
1053
1054                         if (NT_STATUS_EQUAL(status,
1055                                             NT_STATUS_OBJECT_NAME_COLLISION)) {
1056                                 num_collision += 1;
1057                         }
1058
1059                         requests[i] = NULL;
1060                 }
1061                 if (!unreplied) {
1062                         break;
1063                 }
1064
1065                 if (tevent_loop_once(tctx->ev) != 0) {
1066                         torture_comment(tctx, "tevent_loop_once failed\n");
1067                         ret = false;
1068                         goto done;
1069                 }
1070         }
1071
1072         if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
1073                 ret = false;
1074         }
1075 done:
1076         smb2_deltree(tree, fname);
1077
1078         return ret;
1079 }
1080
1081 /*
1082   test opening for delete on a read-only attribute file.
1083 */
1084
1085 static bool test_smb2_open_for_delete(struct torture_context *tctx,
1086                                       struct smb2_tree *tree)
1087 {
1088         union smb_open io;
1089         union smb_fileinfo finfo;
1090         const char *fname = DNAME "\\torture_open_for_delete.txt";
1091         NTSTATUS status;
1092         struct smb2_handle h, h1;
1093         bool ret = true;
1094
1095         torture_comment(tctx,
1096                 "Checking SMB2_OPEN for delete on a readonly file.\n");
1097         smb2_util_unlink(tree, fname);
1098         smb2_deltree(tree, fname);
1099
1100         status = torture_smb2_testdir(tree, DNAME, &h);
1101         CHECK_STATUS(status, NT_STATUS_OK);
1102
1103         /* reasonable default parameters */
1104         ZERO_STRUCT(io.smb2);
1105         io.generic.level = RAW_OPEN_SMB2;
1106         io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
1107         io.smb2.in.alloc_size = 0;
1108         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
1109         io.smb2.in.file_attributes = FILE_ATTRIBUTE_READONLY;
1110         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1111         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
1112         io.smb2.in.create_options = 0;
1113         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1114         io.smb2.in.security_flags = 0;
1115         io.smb2.in.fname = fname;
1116
1117         /* Create the readonly file. */
1118
1119         status = smb2_create(tree, tctx, &(io.smb2));
1120         CHECK_STATUS(status, NT_STATUS_OK);
1121         h1 = io.smb2.out.file.handle;
1122
1123         CHECK_VAL(io.smb2.out.oplock_level, 0);
1124         io.smb2.in.create_options = 0;
1125         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
1126         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
1127         smb2_util_close(tree, h1);
1128
1129         /* Now try and open for delete only - should succeed. */
1130         io.smb2.in.desired_access = SEC_STD_DELETE;
1131         io.smb2.in.file_attributes = 0;
1132         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1133                                 NTCREATEX_SHARE_ACCESS_WRITE |
1134                                 NTCREATEX_SHARE_ACCESS_DELETE;
1135         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1136         status = smb2_create(tree, tctx, &(io.smb2));
1137         CHECK_STATUS(status, NT_STATUS_OK);
1138
1139         smb2_util_unlink(tree, fname);
1140
1141         smb2_util_close(tree, h1);
1142         smb2_util_unlink(tree, fname);
1143         smb2_deltree(tree, DNAME);
1144
1145         return ret;
1146 }
1147
1148 /*
1149   test SMB2 open with a leading slash on the path.
1150   Trying to create a directory with a leading slash
1151   should give NT_STATUS_INVALID_PARAMETER error
1152 */
1153 static bool test_smb2_leading_slash(struct torture_context *tctx,
1154                                     struct smb2_tree *tree)
1155 {
1156         union smb_open io;
1157         const char *dnameslash = "\\"DNAME;
1158         NTSTATUS status;
1159         bool ret = true;
1160
1161         torture_comment(tctx,
1162                 "Trying to create a directory with leading slash on path\n");
1163         smb2_deltree(tree, dnameslash);
1164
1165         ZERO_STRUCT(io.smb2);
1166         io.generic.level = RAW_OPEN_SMB2;
1167         io.smb2.in.oplock_level = 0;
1168         io.smb2.in.desired_access = SEC_RIGHTS_DIR_ALL;
1169         io.smb2.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
1170         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1171         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1172                                 NTCREATEX_SHARE_ACCESS_WRITE |
1173                                 NTCREATEX_SHARE_ACCESS_DELETE;
1174         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1175         io.smb2.in.fname = dnameslash;
1176
1177         status = smb2_create(tree, tree, &(io.smb2));
1178         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
1179
1180         smb2_deltree(tree, dnameslash);
1181         return ret;
1182 }
1183
1184 /*
1185   test SMB2 open with an invalid impersonation level.
1186   Should give NT_STATUS_BAD_IMPERSONATION_LEVEL error
1187 */
1188 static bool test_smb2_impersonation_level(struct torture_context *tctx,
1189                                     struct smb2_tree *tree)
1190 {
1191         union smb_open io;
1192         const char *fname = DNAME "\\torture_invalid_impersonation_level.txt";
1193         NTSTATUS status;
1194         struct smb2_handle h;
1195         bool ret = true;
1196
1197         torture_comment(tctx,
1198                 "Testing SMB2 open with an invalid impersonation level.\n");
1199
1200         smb2_util_unlink(tree, fname);
1201         smb2_util_rmdir(tree, DNAME);
1202
1203         status = torture_smb2_testdir(tree, DNAME, &h);
1204         CHECK_STATUS(status, NT_STATUS_OK);
1205
1206         ZERO_STRUCT(io.smb2);
1207         io.generic.level = RAW_OPEN_SMB2;
1208         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
1209         io.smb2.in.alloc_size = 0;
1210         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1211         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1212                 NTCREATEX_SHARE_ACCESS_WRITE|
1213                 NTCREATEX_SHARE_ACCESS_DELETE;
1214         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
1215         io.smb2.in.create_options = 0;
1216         io.smb2.in.impersonation_level = 0x12345678;
1217         io.smb2.in.security_flags = 0;
1218         io.smb2.in.fname = fname;
1219         io.smb2.in.create_flags = 0;
1220
1221         status = smb2_create(tree, tree, &(io.smb2));
1222         CHECK_STATUS(status, NT_STATUS_BAD_IMPERSONATION_LEVEL);
1223
1224         smb2_util_close(tree, h);
1225         smb2_util_unlink(tree, fname);
1226         smb2_deltree(tree, DNAME);
1227         return ret;
1228 }
1229
1230 static bool test_create_acl_file(struct torture_context *tctx,
1231     struct smb2_tree *tree)
1232 {
1233         torture_comment(tctx, "Testing nttrans create with sec_desc on files\n");
1234
1235         return test_create_acl_ext(tctx, tree, false);
1236 }
1237
1238 static bool test_create_acl_dir(struct torture_context *tctx,
1239     struct smb2_tree *tree)
1240 {
1241         torture_comment(tctx, "Testing nttrans create with sec_desc on directories\n");
1242
1243         return test_create_acl_ext(tctx, tree, true);
1244 }
1245
1246 #define CHECK_ACCESS_FLAGS(_fh, flags) do { \
1247         union smb_fileinfo _q; \
1248         _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
1249         _q.access_information.in.file.handle = (_fh); \
1250         status = smb2_getinfo_file(tree, tctx, &_q); \
1251         CHECK_STATUS(status, NT_STATUS_OK); \
1252         if (_q.access_information.out.access_flags != (flags)) { \
1253                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
1254                        __location__, _q.access_information.out.access_flags, (flags)); \
1255                 ret = false; \
1256                 goto done; \
1257         } \
1258 } while (0)
1259
1260 /*
1261  * Test creating a file with a NULL DACL.
1262  */
1263 static bool test_create_null_dacl(struct torture_context *tctx,
1264     struct smb2_tree *tree)
1265 {
1266         NTSTATUS status;
1267         struct smb2_create io;
1268         const char *fname = "nulldacl.txt";
1269         bool ret = true;
1270         struct smb2_handle handle;
1271         union smb_fileinfo q;
1272         union smb_setfileinfo s;
1273         struct security_descriptor *sd = security_descriptor_initialise(tctx);
1274         struct security_acl dacl;
1275
1276         torture_comment(tctx, "TESTING SEC_DESC WITH A NULL DACL\n");
1277
1278         smb2_util_unlink(tree, fname);
1279
1280         ZERO_STRUCT(io);
1281         io.level = RAW_OPEN_SMB2;
1282         io.in.create_flags = 0;
1283         io.in.desired_access = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC
1284                 | SEC_STD_WRITE_OWNER;
1285         io.in.create_options = 0;
1286         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1287         io.in.share_access =
1288                 NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1289         io.in.alloc_size = 0;
1290         io.in.create_disposition = NTCREATEX_DISP_CREATE;
1291         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
1292         io.in.security_flags = 0;
1293         io.in.fname = fname;
1294         io.in.sec_desc = sd;
1295         /* XXX create_options ? */
1296         io.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
1297                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
1298                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
1299                                           0x00200000;
1300
1301         torture_comment(tctx, "creating a file with a empty sd\n");
1302         status = smb2_create(tree, tctx, &io);
1303         CHECK_STATUS(status, NT_STATUS_OK);
1304         handle = io.out.file.handle;
1305
1306         torture_comment(tctx, "get the original sd\n");
1307         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1308         q.query_secdesc.in.file.handle = handle;
1309         q.query_secdesc.in.secinfo_flags =
1310                 SECINFO_OWNER |
1311                 SECINFO_GROUP |
1312                 SECINFO_DACL;
1313         status = smb2_getinfo_file(tree, tctx, &q);
1314         CHECK_STATUS(status, NT_STATUS_OK);
1315
1316         /*
1317          * Testing the created DACL,
1318          * the server should add the inherited DACL
1319          * when SEC_DESC_DACL_PRESENT isn't specified
1320          */
1321         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1322                 ret = false;
1323                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1324         }
1325         if (q.query_secdesc.out.sd->dacl == NULL) {
1326                 ret = false;
1327                 torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
1328         }
1329
1330         torture_comment(tctx, "set NULL DACL\n");
1331         sd->type |= SEC_DESC_DACL_PRESENT;
1332
1333         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1334         s.set_secdesc.in.file.handle = handle;
1335         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1336         s.set_secdesc.in.sd = sd;
1337         status = smb2_setinfo_file(tree, &s);
1338         CHECK_STATUS(status, NT_STATUS_OK);
1339
1340         torture_comment(tctx, "get the sd\n");
1341         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1342         q.query_secdesc.in.file.handle = handle;
1343         q.query_secdesc.in.secinfo_flags =
1344                 SECINFO_OWNER |
1345                 SECINFO_GROUP |
1346                 SECINFO_DACL;
1347         status = smb2_getinfo_file(tree, tctx, &q);
1348         CHECK_STATUS(status, NT_STATUS_OK);
1349
1350         /* Testing the modified DACL */
1351         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1352                 ret = false;
1353                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1354         }
1355         if (q.query_secdesc.out.sd->dacl != NULL) {
1356                 ret = false;
1357                 torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
1358         }
1359
1360         io.in.create_disposition = NTCREATEX_DISP_OPEN;
1361
1362         torture_comment(tctx, "try open for read control\n");
1363         io.in.desired_access = SEC_STD_READ_CONTROL;
1364         status = smb2_create(tree, tctx, &io);
1365         CHECK_STATUS(status, NT_STATUS_OK);
1366         CHECK_ACCESS_FLAGS(io.out.file.handle,
1367                 SEC_STD_READ_CONTROL);
1368         smb2_util_close(tree, io.out.file.handle);
1369
1370         torture_comment(tctx, "try open for write\n");
1371         io.in.desired_access = SEC_FILE_WRITE_DATA;
1372         status = smb2_create(tree, tctx, &io);
1373         CHECK_STATUS(status, NT_STATUS_OK);
1374         CHECK_ACCESS_FLAGS(io.out.file.handle,
1375                 SEC_FILE_WRITE_DATA);
1376         smb2_util_close(tree, io.out.file.handle);
1377
1378         torture_comment(tctx, "try open for read\n");
1379         io.in.desired_access = SEC_FILE_READ_DATA;
1380         status = smb2_create(tree, tctx, &io);
1381         CHECK_STATUS(status, NT_STATUS_OK);
1382         CHECK_ACCESS_FLAGS(io.out.file.handle,
1383                 SEC_FILE_READ_DATA);
1384         smb2_util_close(tree, io.out.file.handle);
1385
1386         torture_comment(tctx, "try open for generic write\n");
1387         io.in.desired_access = SEC_GENERIC_WRITE;
1388         status = smb2_create(tree, tctx, &io);
1389         CHECK_STATUS(status, NT_STATUS_OK);
1390         CHECK_ACCESS_FLAGS(io.out.file.handle,
1391                 SEC_RIGHTS_FILE_WRITE);
1392         smb2_util_close(tree, io.out.file.handle);
1393
1394         torture_comment(tctx, "try open for generic read\n");
1395         io.in.desired_access = SEC_GENERIC_READ;
1396         status = smb2_create(tree, tctx, &io);
1397         CHECK_STATUS(status, NT_STATUS_OK);
1398         CHECK_ACCESS_FLAGS(io.out.file.handle,
1399                 SEC_RIGHTS_FILE_READ);
1400         smb2_util_close(tree, io.out.file.handle);
1401
1402         torture_comment(tctx, "set DACL with 0 aces\n");
1403         ZERO_STRUCT(dacl);
1404         dacl.revision = SECURITY_ACL_REVISION_NT4;
1405         dacl.num_aces = 0;
1406         sd->dacl = &dacl;
1407
1408         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1409         s.set_secdesc.in.file.handle = handle;
1410         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1411         s.set_secdesc.in.sd = sd;
1412         status = smb2_setinfo_file(tree, &s);
1413         CHECK_STATUS(status, NT_STATUS_OK);
1414
1415         torture_comment(tctx, "get the sd\n");
1416         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1417         q.query_secdesc.in.file.handle = handle;
1418         q.query_secdesc.in.secinfo_flags =
1419                 SECINFO_OWNER |
1420                 SECINFO_GROUP |
1421                 SECINFO_DACL;
1422         status = smb2_getinfo_file(tree, tctx, &q);
1423         CHECK_STATUS(status, NT_STATUS_OK);
1424
1425         /* Testing the modified DACL */
1426         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1427                 ret = false;
1428                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1429         }
1430         if (q.query_secdesc.out.sd->dacl == NULL) {
1431                 ret = false;
1432                 torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
1433         }
1434         if (q.query_secdesc.out.sd->dacl->num_aces != 0) {
1435                 torture_result(tctx, TORTURE_FAIL, "DACL has %u aces!\n",
1436                        q.query_secdesc.out.sd->dacl->num_aces);
1437                 ret = false;
1438                 goto done;
1439         }
1440
1441         torture_comment(tctx, "try open for read control\n");
1442         io.in.desired_access = SEC_STD_READ_CONTROL;
1443         status = smb2_create(tree, tctx, &io);
1444         CHECK_STATUS(status, NT_STATUS_OK);
1445         CHECK_ACCESS_FLAGS(io.out.file.handle,
1446                 SEC_STD_READ_CONTROL);
1447         smb2_util_close(tree, io.out.file.handle);
1448
1449         torture_comment(tctx, "try open for write => access_denied\n");
1450         io.in.desired_access = SEC_FILE_WRITE_DATA;
1451         status = smb2_create(tree, tctx, &io);
1452         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1453                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1454         } else {
1455                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1456         }
1457
1458         torture_comment(tctx, "try open for read => access_denied\n");
1459         io.in.desired_access = SEC_FILE_READ_DATA;
1460         status = smb2_create(tree, tctx, &io);
1461         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1462                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1463         } else {
1464                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1465         }
1466
1467         torture_comment(tctx, "try open for generic write => access_denied\n");
1468         io.in.desired_access = SEC_GENERIC_WRITE;
1469         status = smb2_create(tree, tctx, &io);
1470         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1471                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1472         } else {
1473                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1474         }
1475
1476         torture_comment(tctx, "try open for generic read => access_denied\n");
1477         io.in.desired_access = SEC_GENERIC_READ;
1478         status = smb2_create(tree, tctx, &io);
1479         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1480                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1481         } else {
1482                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1483         }
1484
1485         torture_comment(tctx, "set empty sd\n");
1486         sd->type &= ~SEC_DESC_DACL_PRESENT;
1487         sd->dacl = NULL;
1488
1489         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1490         s.set_secdesc.in.file.handle = handle;
1491         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1492         s.set_secdesc.in.sd = sd;
1493         status = smb2_setinfo_file(tree, &s);
1494         CHECK_STATUS(status, NT_STATUS_OK);
1495
1496         torture_comment(tctx, "get the sd\n");
1497         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1498         q.query_secdesc.in.file.handle = handle;
1499         q.query_secdesc.in.secinfo_flags =
1500                 SECINFO_OWNER |
1501                 SECINFO_GROUP |
1502                 SECINFO_DACL;
1503         status = smb2_getinfo_file(tree, tctx, &q);
1504         CHECK_STATUS(status, NT_STATUS_OK);
1505
1506         /* Testing the modified DACL */
1507         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1508                 ret = false;
1509                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1510         }
1511         if (q.query_secdesc.out.sd->dacl != NULL) {
1512                 ret = false;
1513                 torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
1514         }
1515 done:
1516         smb2_util_close(tree, handle);
1517         smb2_util_unlink(tree, fname);
1518         smb2_tdis(tree);
1519         smb2_logoff(tree->session);
1520         return ret;
1521 }
1522
1523 /*
1524   test SMB2 mkdir with OPEN_IF on the same name twice.
1525   Must use 2 connections to hit the race.
1526 */
1527
1528 static bool test_mkdir_dup(struct torture_context *tctx,
1529                                 struct smb2_tree *tree)
1530 {
1531         const char *fname = "mkdir_dup";
1532         NTSTATUS status;
1533         bool ret = true;
1534         union smb_open io;
1535         struct smb2_tree **trees;
1536         struct smb2_request **requests;
1537         union smb_open *ios;
1538         int i, num_files = 2;
1539         int num_ok = 0;
1540         int num_created = 0;
1541         int num_existed = 0;
1542
1543         torture_comment(tctx,
1544                 "Testing SMB2 Create Directory with multiple connections\n");
1545         trees = talloc_array(tctx, struct smb2_tree *, num_files);
1546         requests = talloc_array(tctx, struct smb2_request *, num_files);
1547         ios = talloc_array(tctx, union smb_open, num_files);
1548         if ((tctx->ev == NULL) || (trees == NULL) || (requests == NULL) ||
1549             (ios == NULL)) {
1550                 torture_fail(tctx, ("talloc failed\n"));
1551                 ret = false;
1552                 goto done;
1553         }
1554
1555         tree->session->transport->options.request_timeout = 60;
1556
1557         for (i=0; i<num_files; i++) {
1558                 if (!torture_smb2_connection(tctx, &(trees[i]))) {
1559                         torture_fail(tctx,
1560                                 talloc_asprintf(tctx,
1561                                         "Could not open %d'th connection\n", i));
1562                         ret = false;
1563                         goto done;
1564                 }
1565                 trees[i]->session->transport->options.request_timeout = 60;
1566         }
1567
1568         /* cleanup */
1569         smb2_util_unlink(tree, fname);
1570         smb2_util_rmdir(tree, fname);
1571
1572         /*
1573           base ntcreatex parms
1574         */
1575         ZERO_STRUCT(io.smb2);
1576         io.generic.level = RAW_OPEN_SMB2;
1577         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
1578         io.smb2.in.alloc_size = 0;
1579         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1580         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1581                 NTCREATEX_SHARE_ACCESS_WRITE|
1582                 NTCREATEX_SHARE_ACCESS_DELETE;
1583         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1584         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1585         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1586         io.smb2.in.security_flags = 0;
1587         io.smb2.in.fname = fname;
1588         io.smb2.in.create_flags = 0;
1589
1590         for (i=0; i<num_files; i++) {
1591                 ios[i] = io;
1592                 requests[i] = smb2_create_send(trees[i], &(ios[i].smb2));
1593                 if (requests[i] == NULL) {
1594                         torture_fail(tctx,
1595                                 talloc_asprintf(tctx,
1596                                 "could not send %d'th request\n", i));
1597                         ret = false;
1598                         goto done;
1599                 }
1600         }
1601
1602         torture_comment(tctx, "waiting for replies\n");
1603         while (1) {
1604                 bool unreplied = false;
1605                 for (i=0; i<num_files; i++) {
1606                         if (requests[i] == NULL) {
1607                                 continue;
1608                         }
1609                         if (requests[i]->state < SMB2_REQUEST_DONE) {
1610                                 unreplied = true;
1611                                 break;
1612                         }
1613                         status = smb2_create_recv(requests[i], tctx,
1614                                                   &(ios[i].smb2));
1615
1616                         if (NT_STATUS_IS_OK(status)) {
1617                                 num_ok += 1;
1618
1619                                 if (ios[i].smb2.out.create_action ==
1620                                                 NTCREATEX_ACTION_CREATED) {
1621                                         num_created++;
1622                                 }
1623                                 if (ios[i].smb2.out.create_action ==
1624                                                 NTCREATEX_ACTION_EXISTED) {
1625                                         num_existed++;
1626                                 }
1627                         } else {
1628                                 torture_fail(tctx,
1629                                         talloc_asprintf(tctx,
1630                                         "File %d returned status %s\n", i,
1631                                         nt_errstr(status)));
1632                         }
1633
1634
1635                         requests[i] = NULL;
1636                 }
1637                 if (!unreplied) {
1638                         break;
1639                 }
1640
1641                 if (tevent_loop_once(tctx->ev) != 0) {
1642                         torture_fail(tctx, "tevent_loop_once failed\n");
1643                         ret = false;
1644                         goto done;
1645                 }
1646         }
1647
1648         if (num_ok != 2) {
1649                 torture_fail(tctx,
1650                         talloc_asprintf(tctx,
1651                         "num_ok == %d\n", num_ok));
1652                 ret = false;
1653         }
1654         if (num_created != 1) {
1655                 torture_fail(tctx,
1656                         talloc_asprintf(tctx,
1657                         "num_created == %d\n", num_created));
1658                 ret = false;
1659         }
1660         if (num_existed != 1) {
1661                 torture_fail(tctx,
1662                         talloc_asprintf(tctx,
1663                         "num_existed == %d\n", num_existed));
1664                 ret = false;
1665         }
1666 done:
1667         smb2_deltree(tree, fname);
1668
1669         return ret;
1670 }
1671
1672 /*
1673   test directory creation with an initial allocation size > 0
1674 */
1675 static bool test_dir_alloc_size(struct torture_context *tctx,
1676                                 struct smb2_tree *tree)
1677 {
1678         bool ret = true;
1679         const char *dname = DNAME "\\torture_alloc_size.dir";
1680         NTSTATUS status;
1681         struct smb2_create c;
1682         struct smb2_handle h1 = {{0}}, h2;
1683
1684         torture_comment(tctx, "Checking initial allocation size on directories\n");
1685
1686         smb2_deltree(tree, dname);
1687
1688         status = torture_smb2_testdir(tree, DNAME, &h1);
1689         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
1690
1691         ZERO_STRUCT(c);
1692         c.in.create_disposition = NTCREATEX_DISP_CREATE;
1693         c.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1694         c.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1695         c.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1696         c.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1697         c.in.fname = dname;
1698         /*
1699          * An insanely large value so we can check the value is
1700          * ignored: Samba either returns 0 (current behaviour), or,
1701          * once vfswrap_get_alloc_size() is fixed to allow retrieving
1702          * the allocated size for directories, returns
1703          * smb_roundup(..., stat.st_size) which would be 1 MB by
1704          * default.
1705          *
1706          * Windows returns 0 for emtpy directories, once directories
1707          * have a few entries it starts replying with values > 0.
1708          */
1709         c.in.alloc_size = 1024*1024*1024;
1710
1711         status = smb2_create(tree, tctx, &c);
1712         h2 = c.out.file.handle;
1713         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1714                                         "dir create with initial alloc size failed");
1715
1716         smb2_util_close(tree, h2);
1717
1718         torture_comment(tctx, "Got directory alloc size: %ju\n", (uintmax_t)c.out.alloc_size);
1719
1720         /*
1721          * See above for the rational for this test
1722          */
1723         if (c.out.alloc_size > 1024*1024) {
1724                 torture_fail_goto(tctx, done, talloc_asprintf(tctx, "bad alloc size: %ju",
1725                                                               (uintmax_t)c.out.alloc_size));
1726         }
1727
1728 done:
1729         if (!smb2_util_handle_empty(h1)) {
1730                 smb2_util_close(tree, h1);
1731         }
1732         smb2_deltree(tree, DNAME);
1733         return ret;
1734 }
1735
1736 /*
1737    basic testing of SMB2 read
1738 */
1739 struct torture_suite *torture_smb2_create_init(TALLOC_CTX *ctx)
1740 {
1741         struct torture_suite *suite = torture_suite_create(ctx, "create");
1742
1743         torture_suite_add_1smb2_test(suite, "gentest", test_create_gentest);
1744         torture_suite_add_1smb2_test(suite, "blob", test_create_blob);
1745         torture_suite_add_1smb2_test(suite, "open", test_smb2_open);
1746         torture_suite_add_1smb2_test(suite, "brlocked", test_smb2_open_brlocked);
1747         torture_suite_add_1smb2_test(suite, "multi", test_smb2_open_multi);
1748         torture_suite_add_1smb2_test(suite, "delete", test_smb2_open_for_delete);
1749         torture_suite_add_1smb2_test(suite, "leading-slash", test_smb2_leading_slash);
1750         torture_suite_add_1smb2_test(suite, "impersonation", test_smb2_impersonation_level);
1751         torture_suite_add_1smb2_test(suite, "aclfile", test_create_acl_file);
1752         torture_suite_add_1smb2_test(suite, "acldir", test_create_acl_dir);
1753         torture_suite_add_1smb2_test(suite, "nulldacl", test_create_null_dacl);
1754         torture_suite_add_1smb2_test(suite, "mkdir-dup", test_mkdir_dup);
1755         torture_suite_add_1smb2_test(suite, "dir-alloc-size", test_dir_alloc_size);
1756
1757         suite->description = talloc_strdup(suite, "SMB2-CREATE tests");
1758
1759         return suite;
1760 }