build(waf): Fail "configure --with-cluster-support" if ctdb support is not available.
[Samba/gebeck_regimport.git] / source4 / torture / smb2 / create.c
blobe36a0789f2248fb59e584cc95169e6dd8778b10b
1 /*
2 Unix SMB/CIFS implementation.
4 SMB2 create test suite
6 Copyright (C) Andrew Tridgell 2008
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.
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.
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/>.
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"
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"
37 #define FNAME "test_create.dat"
38 #define DNAME "smb2_open"
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)
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)
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)
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 (t != t2) { \
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)
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)
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)
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)
130 test some interesting combinations found by gentest
132 static bool test_create_gentest(struct torture_context *tctx, struct smb2_tree *tree)
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;
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;
152 status = smb2_create(tree, tctx, &io);
153 CHECK_STATUS(status, NT_STATUS_OK);
155 status = smb2_util_close(tree, io.out.file.handle);
156 CHECK_STATUS(status, NT_STATUS_OK);
158 io.in.create_options = 0xF0000000;
159 status = smb2_create(tree, tctx, &io);
160 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
162 io.in.create_options = 0;
164 io.in.file_attributes = FILE_ATTRIBUTE_DEVICE;
165 status = smb2_create(tree, tctx, &io);
166 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
168 io.in.file_attributes = FILE_ATTRIBUTE_VOLUME;
169 status = smb2_create(tree, tctx, &io);
170 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
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);
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);
182 io.in.desired_access = 0x04000000;
183 status = smb2_create(tree, tctx, &io);
184 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
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;
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;
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));
220 io.in.create_options = 0;
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);
228 io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
229 io.in.file_attributes = 0;
230 access_mask = 0;
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);
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);
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;
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;
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;
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;
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));
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);
298 smb2_deltree(tree, FNAME);
301 * Standalone servers doesn't support encryption
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);
316 smb2_deltree(tree, FNAME);
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);
330 status = smb2_util_close(tree, io.out.file.handle);
331 CHECK_STATUS(status, NT_STATUS_OK);
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);
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);
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);
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);
361 smb2_deltree(tree, FNAME);
363 return true;
368 try the various request blobs
370 static bool test_create_blob(struct torture_context *tctx, struct smb2_tree *tree)
372 struct smb2_create io;
373 NTSTATUS status;
375 smb2_deltree(tree, FNAME);
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;
391 status = smb2_create(tree, tctx, &io);
392 CHECK_STATUS(status, NT_STATUS_OK);
394 status = smb2_util_close(tree, io.out.file.handle);
395 CHECK_STATUS(status, NT_STATUS_OK);
397 torture_comment(tctx, "Testing alloc size\n");
398 io.in.alloc_size = 4096;
399 status = smb2_create(tree, tctx, &io);
400 CHECK_STATUS(status, NT_STATUS_OK);
401 CHECK_EQUAL(io.out.alloc_size, io.in.alloc_size);
403 status = smb2_util_close(tree, io.out.file.handle);
404 CHECK_STATUS(status, NT_STATUS_OK);
406 torture_comment(tctx, "Testing durable open\n");
407 io.in.durable_open = true;
408 status = smb2_create(tree, tctx, &io);
409 CHECK_STATUS(status, NT_STATUS_OK);
411 status = smb2_util_close(tree, io.out.file.handle);
412 CHECK_STATUS(status, NT_STATUS_OK);
414 torture_comment(tctx, "Testing query maximal access\n");
415 io.in.query_maximal_access = true;
416 status = smb2_create(tree, tctx, &io);
417 CHECK_STATUS(status, NT_STATUS_OK);
418 CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);
420 status = smb2_util_close(tree, io.out.file.handle);
421 CHECK_STATUS(status, NT_STATUS_OK);
423 torture_comment(tctx, "Testing timewarp\n");
424 io.in.timewarp = 10000;
425 status = smb2_create(tree, tctx, &io);
426 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
427 io.in.timewarp = 0;
429 torture_comment(tctx, "Testing query_on_disk\n");
430 io.in.query_on_disk_id = true;
431 status = smb2_create(tree, tctx, &io);
432 CHECK_STATUS(status, NT_STATUS_OK);
434 status = smb2_util_close(tree, io.out.file.handle);
435 CHECK_STATUS(status, NT_STATUS_OK);
437 torture_comment(tctx, "Testing unknown tag\n");
438 status = smb2_create_blob_add(tctx, &io.in.blobs,
439 "FooO", data_blob(NULL, 0));
440 CHECK_STATUS(status, NT_STATUS_OK);
442 status = smb2_create(tree, tctx, &io);
443 CHECK_STATUS(status, NT_STATUS_OK);
445 status = smb2_util_close(tree, io.out.file.handle);
446 CHECK_STATUS(status, NT_STATUS_OK);
448 torture_comment(tctx, "Testing bad tag length 0\n");
449 ZERO_STRUCT(io.in.blobs);
450 status = smb2_create_blob_add(tctx, &io.in.blobs,
451 "x", data_blob(NULL, 0));
452 CHECK_STATUS(status, NT_STATUS_OK);
453 status = smb2_create(tree, tctx, &io);
454 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
456 torture_comment(tctx, "Testing bad tag length 1\n");
457 ZERO_STRUCT(io.in.blobs);
458 status = smb2_create_blob_add(tctx, &io.in.blobs,
459 "x", data_blob(NULL, 0));
460 CHECK_STATUS(status, NT_STATUS_OK);
461 status = smb2_create(tree, tctx, &io);
462 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
464 torture_comment(tctx, "Testing bad tag length 2\n");
465 ZERO_STRUCT(io.in.blobs);
466 status = smb2_create_blob_add(tctx, &io.in.blobs,
467 "xx", data_blob(NULL, 0));
468 CHECK_STATUS(status, NT_STATUS_OK);
469 status = smb2_create(tree, tctx, &io);
470 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
472 torture_comment(tctx, "Testing bad tag length 3\n");
473 ZERO_STRUCT(io.in.blobs);
474 status = smb2_create_blob_add(tctx, &io.in.blobs,
475 "xxx", data_blob(NULL, 0));
476 CHECK_STATUS(status, NT_STATUS_OK);
477 status = smb2_create(tree, tctx, &io);
478 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
480 torture_comment(tctx, "Testing tag length 4\n");
481 ZERO_STRUCT(io.in.blobs);
482 status = smb2_create_blob_add(tctx, &io.in.blobs,
483 "xxxx", data_blob(NULL, 0));
484 CHECK_STATUS(status, NT_STATUS_OK);
485 status = smb2_create(tree, tctx, &io);
486 CHECK_STATUS(status, NT_STATUS_OK);
488 torture_comment(tctx, "Testing tag length 5\n");
489 ZERO_STRUCT(io.in.blobs);
490 status = smb2_create_blob_add(tctx, &io.in.blobs,
491 "xxxxx", data_blob(NULL, 0));
492 CHECK_STATUS(status, NT_STATUS_OK);
493 status = smb2_create(tree, tctx, &io);
494 CHECK_STATUS(status, NT_STATUS_OK);
496 torture_comment(tctx, "Testing tag length 6\n");
497 ZERO_STRUCT(io.in.blobs);
498 status = smb2_create_blob_add(tctx, &io.in.blobs,
499 "xxxxxx", data_blob(NULL, 0));
500 CHECK_STATUS(status, NT_STATUS_OK);
501 status = smb2_create(tree, tctx, &io);
502 CHECK_STATUS(status, NT_STATUS_OK);
504 torture_comment(tctx, "Testing tag length 7\n");
505 ZERO_STRUCT(io.in.blobs);
506 status = smb2_create_blob_add(tctx, &io.in.blobs,
507 "xxxxxxx", data_blob(NULL, 0));
508 CHECK_STATUS(status, NT_STATUS_OK);
509 status = smb2_create(tree, tctx, &io);
510 CHECK_STATUS(status, NT_STATUS_OK);
512 torture_comment(tctx, "Testing tag length 8\n");
513 ZERO_STRUCT(io.in.blobs);
514 status = smb2_create_blob_add(tctx, &io.in.blobs,
515 "xxxxxxxx", data_blob(NULL, 0));
516 CHECK_STATUS(status, NT_STATUS_OK);
517 status = smb2_create(tree, tctx, &io);
518 CHECK_STATUS(status, NT_STATUS_OK);
520 torture_comment(tctx, "Testing tag length 16\n");
521 ZERO_STRUCT(io.in.blobs);
522 status = smb2_create_blob_add(tctx, &io.in.blobs,
523 "xxxxxxxxxxxxxxxx", data_blob(NULL, 0));
524 CHECK_STATUS(status, NT_STATUS_OK);
525 status = smb2_create(tree, tctx, &io);
526 CHECK_STATUS(status, NT_STATUS_OK);
528 torture_comment(tctx, "Testing tag length 17\n");
529 ZERO_STRUCT(io.in.blobs);
530 status = smb2_create_blob_add(tctx, &io.in.blobs,
531 "xxxxxxxxxxxxxxxxx", data_blob(NULL, 0));
532 CHECK_STATUS(status, NT_STATUS_OK);
533 status = smb2_create(tree, tctx, &io);
534 CHECK_STATUS(status, NT_STATUS_OK);
536 torture_comment(tctx, "Testing tag length 34\n");
537 ZERO_STRUCT(io.in.blobs);
538 status = smb2_create_blob_add(tctx, &io.in.blobs,
539 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
540 data_blob(NULL, 0));
541 CHECK_STATUS(status, NT_STATUS_OK);
542 status = smb2_create(tree, tctx, &io);
543 CHECK_STATUS(status, NT_STATUS_OK);
545 smb2_deltree(tree, FNAME);
547 return true;
550 #define FAIL_UNLESS(__cond) \
551 do { \
552 if (__cond) {} else { \
553 torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n", \
554 __location__, #__cond); \
555 ret = false; goto done; \
557 } while(0)
560 try creating with acls
562 static bool test_create_acl_ext(struct torture_context *tctx, struct smb2_tree *tree, bool test_dir)
564 bool ret = true;
565 struct smb2_create io;
566 NTSTATUS status;
567 struct security_ace ace;
568 struct security_descriptor *sd;
569 struct dom_sid *test_sid;
570 union smb_fileinfo q = {};
571 uint32_t attrib =
572 FILE_ATTRIBUTE_HIDDEN |
573 FILE_ATTRIBUTE_SYSTEM |
574 (test_dir ? FILE_ATTRIBUTE_DIRECTORY : 0);
575 NTSTATUS (*delete_func)(struct smb2_tree *, const char *) =
576 test_dir ? smb2_util_rmdir : smb2_util_unlink;
578 smb2_deltree(tree, FNAME);
580 ZERO_STRUCT(io);
581 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
582 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
583 io.in.create_disposition = NTCREATEX_DISP_CREATE;
584 io.in.share_access =
585 NTCREATEX_SHARE_ACCESS_DELETE |
586 NTCREATEX_SHARE_ACCESS_READ |
587 NTCREATEX_SHARE_ACCESS_WRITE;
588 io.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT | 0x00200000 |
589 (test_dir ? NTCREATEX_OPTIONS_DIRECTORY :
590 (NTCREATEX_OPTIONS_NON_DIRECTORY_FILE));
592 io.in.fname = FNAME;
594 torture_comment(tctx, "basic create\n");
596 status = smb2_create(tree, tctx, &io);
597 CHECK_STATUS(status, NT_STATUS_OK);
599 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
600 q.query_secdesc.in.file.handle = io.out.file.handle;
601 q.query_secdesc.in.secinfo_flags =
602 SECINFO_OWNER |
603 SECINFO_GROUP |
604 SECINFO_DACL;
605 status = smb2_getinfo_file(tree, tctx, &q);
606 CHECK_STATUS(status, NT_STATUS_OK);
607 sd = q.query_secdesc.out.sd;
609 status = smb2_util_close(tree, io.out.file.handle);
610 CHECK_STATUS(status, NT_STATUS_OK);
611 status = delete_func(tree, FNAME);
612 CHECK_STATUS(status, NT_STATUS_OK);
614 torture_comment(tctx, "adding a new ACE\n");
615 test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
617 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
618 ace.flags = 0;
619 ace.access_mask = SEC_STD_ALL;
620 ace.trustee = *test_sid;
622 status = security_descriptor_dacl_add(sd, &ace);
623 CHECK_STATUS(status, NT_STATUS_OK);
625 torture_comment(tctx, "creating a file with an initial ACL\n");
627 io.in.sec_desc = sd;
628 status = smb2_create(tree, tctx, &io);
629 CHECK_STATUS(status, NT_STATUS_OK);
631 FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
633 status = smb2_util_close(tree, io.out.file.handle);
634 CHECK_STATUS(status, NT_STATUS_OK);
635 status = delete_func(tree, FNAME);
636 CHECK_STATUS(status, NT_STATUS_OK);
638 torture_comment(tctx, "creating with attributes\n");
640 io.in.sec_desc = NULL;
641 io.in.file_attributes = attrib;
642 status = smb2_create(tree, tctx, &io);
643 CHECK_STATUS(status, NT_STATUS_OK);
645 FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
647 status = smb2_util_close(tree, io.out.file.handle);
648 CHECK_STATUS(status, NT_STATUS_OK);
649 status = delete_func(tree, FNAME);
650 CHECK_STATUS(status, NT_STATUS_OK);
652 torture_comment(tctx, "creating with attributes and ACL\n");
654 io.in.sec_desc = sd;
655 io.in.file_attributes = attrib;
656 status = smb2_create(tree, tctx, &io);
657 CHECK_STATUS(status, NT_STATUS_OK);
659 FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
660 FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
662 status = smb2_util_close(tree, io.out.file.handle);
663 CHECK_STATUS(status, NT_STATUS_OK);
664 status = delete_func(tree, FNAME);
665 CHECK_STATUS(status, NT_STATUS_OK);
667 torture_comment(tctx, "creating with attributes, ACL and owner\n");
668 sd = security_descriptor_dacl_create(tctx,
669 0, SID_WORLD, SID_BUILTIN_USERS,
670 SID_WORLD,
671 SEC_ACE_TYPE_ACCESS_ALLOWED,
672 SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
674 NULL);
676 io.in.sec_desc = sd;
677 io.in.file_attributes = attrib;
678 status = smb2_create(tree, tctx, &io);
679 CHECK_STATUS(status, NT_STATUS_OK);
681 FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
682 FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
684 done:
685 status = smb2_util_close(tree, io.out.file.handle);
686 CHECK_STATUS(status, NT_STATUS_OK);
687 status = delete_func(tree, FNAME);
688 CHECK_STATUS(status, NT_STATUS_OK);
690 return ret;
694 test SMB2 open
696 static bool test_smb2_open(struct torture_context *tctx,
697 struct smb2_tree *tree)
699 union smb_open io;
700 union smb_fileinfo finfo;
701 const char *fname = DNAME "\\torture_ntcreatex.txt";
702 const char *dname = DNAME "\\torture_ntcreatex.dir";
703 NTSTATUS status;
704 struct smb2_handle h, h1;
705 bool ret = true;
706 int i;
707 struct {
708 uint32_t create_disp;
709 bool with_file;
710 NTSTATUS correct_status;
711 } open_funcs[] = {
712 { NTCREATEX_DISP_SUPERSEDE, true, NT_STATUS_OK },
713 { NTCREATEX_DISP_SUPERSEDE, false, NT_STATUS_OK },
714 { NTCREATEX_DISP_OPEN, true, NT_STATUS_OK },
715 { NTCREATEX_DISP_OPEN, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
716 { NTCREATEX_DISP_CREATE, true, NT_STATUS_OBJECT_NAME_COLLISION },
717 { NTCREATEX_DISP_CREATE, false, NT_STATUS_OK },
718 { NTCREATEX_DISP_OPEN_IF, true, NT_STATUS_OK },
719 { NTCREATEX_DISP_OPEN_IF, false, NT_STATUS_OK },
720 { NTCREATEX_DISP_OVERWRITE, true, NT_STATUS_OK },
721 { NTCREATEX_DISP_OVERWRITE, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
722 { NTCREATEX_DISP_OVERWRITE_IF, true, NT_STATUS_OK },
723 { NTCREATEX_DISP_OVERWRITE_IF, false, NT_STATUS_OK },
724 { 6, true, NT_STATUS_INVALID_PARAMETER },
725 { 6, false, NT_STATUS_INVALID_PARAMETER },
728 torture_comment(tctx, "Checking SMB2 Open\n");
730 smb2_util_unlink(tree, fname);
731 smb2_util_rmdir(tree, dname);
733 status = torture_smb2_testdir(tree, DNAME, &h);
734 CHECK_STATUS(status, NT_STATUS_OK);
736 ZERO_STRUCT(io.smb2);
737 /* reasonable default parameters */
738 io.generic.level = RAW_OPEN_SMB2;
739 io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
740 io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
741 io.smb2.in.alloc_size = 1024*1024;
742 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
743 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
744 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
745 io.smb2.in.create_options = 0;
746 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
747 io.smb2.in.security_flags = 0;
748 io.smb2.in.fname = fname;
750 /* test the create disposition */
751 for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
752 if (open_funcs[i].with_file) {
753 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
754 status= smb2_create(tree, tctx, &(io.smb2));
755 if (!NT_STATUS_IS_OK(status)) {
756 torture_comment(tctx,
757 "Failed to create file %s status %s %d\n",
758 fname, nt_errstr(status), i);
760 ret = false;
761 goto done;
763 smb2_util_close(tree, io.smb2.out.file.handle);
765 io.smb2.in.create_disposition = open_funcs[i].create_disp;
766 status = smb2_create(tree, tctx, &(io.smb2));
767 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
768 torture_comment(tctx,
769 "(%s) incorrect status %s should be %s (i=%d "
770 "with_file=%d open_disp=%d)\n",
771 __location__, nt_errstr(status),
772 nt_errstr(open_funcs[i].correct_status),
773 i, (int)open_funcs[i].with_file,
774 (int)open_funcs[i].create_disp);
776 ret = false;
777 goto done;
779 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
780 smb2_util_close(tree, io.smb2.out.file.handle);
781 smb2_util_unlink(tree, fname);
785 /* basic field testing */
786 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
788 status = smb2_create(tree, tctx, &(io.smb2));
789 CHECK_STATUS(status, NT_STATUS_OK);
790 h1 = io.smb2.out.file.handle;
792 CHECK_VAL(io.smb2.out.oplock_level, 0);
793 CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
794 CHECK_NTTIME(io.smb2.out.create_time, create_time);
795 CHECK_NTTIME(io.smb2.out.access_time, access_time);
796 CHECK_NTTIME(io.smb2.out.write_time, write_time);
797 CHECK_NTTIME(io.smb2.out.change_time, change_time);
798 CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
799 CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
800 CHECK_ALL_INFO(io.smb2.out.size, size);
802 /* check fields when the file already existed */
803 smb2_util_close(tree, h1);
804 smb2_util_unlink(tree, fname);
806 status = smb2_create_complex_file(tree, fname, &h1);
807 CHECK_STATUS(status, NT_STATUS_OK);
809 smb2_util_close(tree, h1);
811 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
812 status = smb2_create(tree, tctx, &(io.smb2));
813 CHECK_STATUS(status, NT_STATUS_OK);
814 h1 = io.smb2.out.file.handle;
816 CHECK_VAL(io.smb2.out.oplock_level, 0);
817 CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_EXISTED);
818 CHECK_NTTIME(io.smb2.out.create_time, create_time);
819 CHECK_NTTIME(io.smb2.out.access_time, access_time);
820 CHECK_NTTIME(io.smb2.out.write_time, write_time);
821 CHECK_NTTIME(io.smb2.out.change_time, change_time);
822 CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
823 CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
824 CHECK_ALL_INFO(io.smb2.out.size, size);
825 smb2_util_close(tree, h1);
826 smb2_util_unlink(tree, fname);
828 /* create a directory */
829 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
830 io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
831 io.smb2.in.alloc_size = 0;
832 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
833 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
834 io.smb2.in.create_options = 0;
835 io.smb2.in.fname = dname;
836 fname = dname;
838 smb2_util_rmdir(tree, fname);
839 smb2_util_unlink(tree, fname);
841 io.smb2.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
842 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
843 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
844 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
845 NTCREATEX_SHARE_ACCESS_WRITE;
846 status = smb2_create(tree, tctx, &(io.smb2));
847 CHECK_STATUS(status, NT_STATUS_OK);
848 h1 = io.smb2.out.file.handle;
850 CHECK_VAL(io.smb2.out.oplock_level, 0);
851 CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
852 CHECK_NTTIME(io.smb2.out.create_time, create_time);
853 CHECK_NTTIME(io.smb2.out.access_time, access_time);
854 CHECK_NTTIME(io.smb2.out.write_time, write_time);
855 CHECK_NTTIME(io.smb2.out.change_time, change_time);
856 CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
857 CHECK_VAL(io.smb2.out.file_attr & ~FILE_ATTRIBUTE_NONINDEXED,
858 FILE_ATTRIBUTE_DIRECTORY);
859 CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
860 CHECK_ALL_INFO(io.smb2.out.size, size);
861 CHECK_VAL(io.smb2.out.size, 0);
862 CHECK_VAL(io.smb2.out.alloc_size, 0);
863 smb2_util_unlink(tree, fname);
865 done:
866 smb2_util_close(tree, h1);
867 smb2_util_unlink(tree, fname);
868 smb2_deltree(tree, DNAME);
869 return ret;
873 test with an already opened and byte range locked file
876 static bool test_smb2_open_brlocked(struct torture_context *tctx,
877 struct smb2_tree *tree)
879 union smb_open io, io1;
880 union smb_lock io2;
881 struct smb2_lock_element lock[1];
882 const char *fname = DNAME "\\torture_ntcreatex.txt";
883 NTSTATUS status;
884 bool ret = true;
885 struct smb2_handle h;
886 char b = 42;
888 torture_comment(tctx,
889 "Testing SMB2 open with a byte range locked file\n");
891 smb2_util_unlink(tree, fname);
893 status = torture_smb2_testdir(tree, DNAME, &h);
894 CHECK_STATUS(status, NT_STATUS_OK);
896 ZERO_STRUCT(io.smb2);
897 io.generic.level = RAW_OPEN_SMB2;
898 io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
899 io.smb2.in.desired_access = 0x2019f;
900 io.smb2.in.alloc_size = 0;
901 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
902 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
903 NTCREATEX_SHARE_ACCESS_WRITE;
904 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
905 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
906 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
907 io.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
908 io.smb2.in.fname = fname;
910 status = smb2_create(tree, tctx, &(io.smb2));
911 CHECK_STATUS(status, NT_STATUS_OK);
913 status = smb2_util_write(tree, io.smb2.out.file.handle, &b, 0, 1);
914 CHECK_STATUS(status, NT_STATUS_OK);
916 ZERO_STRUCT(io2.smb2);
917 io2.smb2.level = RAW_LOCK_SMB2;
918 io2.smb2.in.file.handle = io.smb2.out.file.handle;
919 io2.smb2.in.lock_count = 1;
921 ZERO_STRUCT(lock);
922 lock[0].offset = 0;
923 lock[0].length = 1;
924 lock[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
925 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
926 io2.smb2.in.locks = &lock[0];
927 status = smb2_lock(tree, &(io2.smb2));
928 CHECK_STATUS(status, NT_STATUS_OK);
930 ZERO_STRUCT(io1.smb2);
931 io1.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
932 io1.smb2.in.desired_access = 0x20196;
933 io1.smb2.in.alloc_size = 0;
934 io1.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
935 io1.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
936 NTCREATEX_SHARE_ACCESS_WRITE;
937 io1.smb2.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
938 io1.smb2.in.create_options = 0;
939 io1.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
940 io1.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
941 io1.smb2.in.fname = fname;
943 status = smb2_create(tree, tctx, &(io1.smb2));
944 CHECK_STATUS(status, NT_STATUS_OK);
946 smb2_util_close(tree, io.smb2.out.file.handle);
947 smb2_util_close(tree, io1.smb2.out.file.handle);
948 smb2_util_unlink(tree, fname);
949 smb2_deltree(tree, DNAME);
951 return ret;
954 /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
956 static bool test_smb2_open_multi(struct torture_context *tctx,
957 struct smb2_tree *tree)
959 const char *fname = "test_oplock.dat";
960 NTSTATUS status;
961 bool ret = true;
962 union smb_open io;
963 struct smb2_tree **trees;
964 struct smb2_request **requests;
965 union smb_open *ios;
966 int i, num_files = 3;
967 int num_ok = 0;
968 int num_collision = 0;
970 torture_comment(tctx,
971 "Testing SMB2 Open with multiple connections\n");
972 trees = talloc_array(tctx, struct smb2_tree *, num_files);
973 requests = talloc_array(tctx, struct smb2_request *, num_files);
974 ios = talloc_array(tctx, union smb_open, num_files);
975 if ((tctx->ev == NULL) || (trees == NULL) || (requests == NULL) ||
976 (ios == NULL)) {
977 torture_comment(tctx, ("talloc failed\n"));
978 ret = false;
979 goto done;
982 tree->session->transport->options.request_timeout = 60;
984 for (i=0; i<num_files; i++) {
985 if (!torture_smb2_connection(tctx, &(trees[i]))) {
986 torture_comment(tctx,
987 "Could not open %d'th connection\n", i);
988 ret = false;
989 goto done;
991 trees[i]->session->transport->options.request_timeout = 60;
994 /* cleanup */
995 smb2_util_unlink(tree, fname);
998 base ntcreatex parms
1000 ZERO_STRUCT(io.smb2);
1001 io.generic.level = RAW_OPEN_SMB2;
1002 io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
1003 io.smb2.in.alloc_size = 0;
1004 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1005 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1006 NTCREATEX_SHARE_ACCESS_WRITE|
1007 NTCREATEX_SHARE_ACCESS_DELETE;
1008 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
1009 io.smb2.in.create_options = 0;
1010 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1011 io.smb2.in.security_flags = 0;
1012 io.smb2.in.fname = fname;
1013 io.smb2.in.create_flags = 0;
1015 for (i=0; i<num_files; i++) {
1016 ios[i] = io;
1017 requests[i] = smb2_create_send(trees[i], &(ios[i].smb2));
1018 if (requests[i] == NULL) {
1019 torture_comment(tctx,
1020 "could not send %d'th request\n", i);
1021 ret = false;
1022 goto done;
1026 torture_comment(tctx, "waiting for replies\n");
1027 while (1) {
1028 bool unreplied = false;
1029 for (i=0; i<num_files; i++) {
1030 if (requests[i] == NULL) {
1031 continue;
1033 if (requests[i]->state < SMB2_REQUEST_DONE) {
1034 unreplied = true;
1035 break;
1037 status = smb2_create_recv(requests[i], tctx,
1038 &(ios[i].smb2));
1040 torture_comment(tctx,
1041 "File %d returned status %s\n", i,
1042 nt_errstr(status));
1044 if (NT_STATUS_IS_OK(status)) {
1045 num_ok += 1;
1048 if (NT_STATUS_EQUAL(status,
1049 NT_STATUS_OBJECT_NAME_COLLISION)) {
1050 num_collision += 1;
1053 requests[i] = NULL;
1055 if (!unreplied) {
1056 break;
1059 if (tevent_loop_once(tctx->ev) != 0) {
1060 torture_comment(tctx, "tevent_loop_once failed\n");
1061 ret = false;
1062 goto done;
1066 if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
1067 ret = false;
1069 done:
1070 smb2_deltree(tree, fname);
1072 return ret;
1076 test opening for delete on a read-only attribute file.
1079 static bool test_smb2_open_for_delete(struct torture_context *tctx,
1080 struct smb2_tree *tree)
1082 union smb_open io;
1083 union smb_fileinfo finfo;
1084 const char *fname = DNAME "\\torture_open_for_delete.txt";
1085 NTSTATUS status;
1086 struct smb2_handle h, h1;
1087 bool ret = true;
1089 torture_comment(tctx,
1090 "Checking SMB2_OPEN for delete on a readonly file.\n");
1091 smb2_util_unlink(tree, fname);
1092 smb2_deltree(tree, fname);
1094 status = torture_smb2_testdir(tree, DNAME, &h);
1095 CHECK_STATUS(status, NT_STATUS_OK);
1097 /* reasonable default parameters */
1098 ZERO_STRUCT(io.smb2);
1099 io.generic.level = RAW_OPEN_SMB2;
1100 io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
1101 io.smb2.in.alloc_size = 0;
1102 io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
1103 io.smb2.in.file_attributes = FILE_ATTRIBUTE_READONLY;
1104 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1105 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
1106 io.smb2.in.create_options = 0;
1107 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
1108 io.smb2.in.security_flags = 0;
1109 io.smb2.in.fname = fname;
1111 /* Create the readonly file. */
1113 status = smb2_create(tree, tctx, &(io.smb2));
1114 CHECK_STATUS(status, NT_STATUS_OK);
1115 h1 = io.smb2.out.file.handle;
1117 CHECK_VAL(io.smb2.out.oplock_level, 0);
1118 io.smb2.in.create_options = 0;
1119 CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
1120 CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
1121 smb2_util_close(tree, h1);
1123 /* Now try and open for delete only - should succeed. */
1124 io.smb2.in.desired_access = SEC_STD_DELETE;
1125 io.smb2.in.file_attributes = 0;
1126 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1127 NTCREATEX_SHARE_ACCESS_WRITE |
1128 NTCREATEX_SHARE_ACCESS_DELETE;
1129 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1130 status = smb2_create(tree, tctx, &(io.smb2));
1131 CHECK_STATUS(status, NT_STATUS_OK);
1133 smb2_util_unlink(tree, fname);
1135 smb2_util_close(tree, h1);
1136 smb2_util_unlink(tree, fname);
1137 smb2_deltree(tree, DNAME);
1139 return ret;
1143 test SMB2 open with a leading slash on the path.
1144 Trying to create a directory with a leading slash
1145 should give NT_STATUS_INVALID_PARAMETER error
1147 static bool test_smb2_leading_slash(struct torture_context *tctx,
1148 struct smb2_tree *tree)
1150 union smb_open io;
1151 const char *dnameslash = "\\"DNAME;
1152 NTSTATUS status;
1153 bool ret = true;
1155 torture_comment(tctx,
1156 "Trying to create a directory with leading slash on path\n");
1157 smb2_deltree(tree, dnameslash);
1159 ZERO_STRUCT(io.smb2);
1160 io.generic.level = RAW_OPEN_SMB2;
1161 io.smb2.in.oplock_level = 0;
1162 io.smb2.in.desired_access = SEC_RIGHTS_DIR_ALL;
1163 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1164 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1165 io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1166 NTCREATEX_SHARE_ACCESS_WRITE |
1167 NTCREATEX_SHARE_ACCESS_DELETE;
1168 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1169 io.smb2.in.fname = dnameslash;
1171 status = smb2_create(tree, tree, &(io.smb2));
1172 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
1174 smb2_deltree(tree, dnameslash);
1175 return ret;
1179 static bool test_create_acl_file(struct torture_context *tctx,
1180 struct smb2_tree *tree)
1182 torture_comment(tctx, "Testing nttrans create with sec_desc on files\n");
1184 return test_create_acl_ext(tctx, tree, false);
1187 static bool test_create_acl_dir(struct torture_context *tctx,
1188 struct smb2_tree *tree)
1190 torture_comment(tctx, "Testing nttrans create with sec_desc on directories\n");
1192 return test_create_acl_ext(tctx, tree, true);
1195 #define CHECK_ACCESS_FLAGS(_fh, flags) do { \
1196 union smb_fileinfo _q; \
1197 _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
1198 _q.access_information.in.file.handle = (_fh); \
1199 status = smb2_getinfo_file(tree, tctx, &_q); \
1200 CHECK_STATUS(status, NT_STATUS_OK); \
1201 if (_q.access_information.out.access_flags != (flags)) { \
1202 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
1203 __location__, _q.access_information.out.access_flags, (flags)); \
1204 ret = false; \
1205 goto done; \
1207 } while (0)
1210 * Test creating a file with a NULL DACL.
1212 static bool test_create_null_dacl(struct torture_context *tctx,
1213 struct smb2_tree *tree)
1215 NTSTATUS status;
1216 struct smb2_create io;
1217 const char *fname = "nulldacl.txt";
1218 bool ret = true;
1219 struct smb2_handle handle;
1220 union smb_fileinfo q;
1221 union smb_setfileinfo s;
1222 struct security_descriptor *sd = security_descriptor_initialise(tctx);
1223 struct security_acl dacl;
1225 torture_comment(tctx, "TESTING SEC_DESC WITH A NULL DACL\n");
1227 smb2_util_unlink(tree, fname);
1229 ZERO_STRUCT(io);
1230 io.level = RAW_OPEN_SMB2;
1231 io.in.create_flags = 0;
1232 io.in.desired_access = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC
1233 | SEC_STD_WRITE_OWNER;
1234 io.in.create_options = 0;
1235 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1236 io.in.share_access =
1237 NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1238 io.in.alloc_size = 0;
1239 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1240 io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
1241 io.in.security_flags = 0;
1242 io.in.fname = fname;
1243 io.in.sec_desc = sd;
1244 /* XXX create_options ? */
1245 io.in.create_options = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
1246 NTCREATEX_OPTIONS_ASYNC_ALERT |
1247 NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
1248 0x00200000;
1250 torture_comment(tctx, "creating a file with a empty sd\n");
1251 status = smb2_create(tree, tctx, &io);
1252 CHECK_STATUS(status, NT_STATUS_OK);
1253 handle = io.out.file.handle;
1255 torture_comment(tctx, "get the original sd\n");
1256 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1257 q.query_secdesc.in.file.handle = handle;
1258 q.query_secdesc.in.secinfo_flags =
1259 SECINFO_OWNER |
1260 SECINFO_GROUP |
1261 SECINFO_DACL;
1262 status = smb2_getinfo_file(tree, tctx, &q);
1263 CHECK_STATUS(status, NT_STATUS_OK);
1266 * Testing the created DACL,
1267 * the server should add the inherited DACL
1268 * when SEC_DESC_DACL_PRESENT isn't specified
1270 if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1271 ret = false;
1272 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1274 if (q.query_secdesc.out.sd->dacl == NULL) {
1275 ret = false;
1276 torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
1279 torture_comment(tctx, "set NULL DACL\n");
1280 sd->type |= SEC_DESC_DACL_PRESENT;
1282 s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1283 s.set_secdesc.in.file.handle = handle;
1284 s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1285 s.set_secdesc.in.sd = sd;
1286 status = smb2_setinfo_file(tree, &s);
1287 CHECK_STATUS(status, NT_STATUS_OK);
1289 torture_comment(tctx, "get the sd\n");
1290 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1291 q.query_secdesc.in.file.handle = handle;
1292 q.query_secdesc.in.secinfo_flags =
1293 SECINFO_OWNER |
1294 SECINFO_GROUP |
1295 SECINFO_DACL;
1296 status = smb2_getinfo_file(tree, tctx, &q);
1297 CHECK_STATUS(status, NT_STATUS_OK);
1299 /* Testing the modified DACL */
1300 if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1301 ret = false;
1302 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1304 if (q.query_secdesc.out.sd->dacl != NULL) {
1305 ret = false;
1306 torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
1309 io.in.create_disposition = NTCREATEX_DISP_OPEN;
1311 torture_comment(tctx, "try open for read control\n");
1312 io.in.desired_access = SEC_STD_READ_CONTROL;
1313 status = smb2_create(tree, tctx, &io);
1314 CHECK_STATUS(status, NT_STATUS_OK);
1315 CHECK_ACCESS_FLAGS(io.out.file.handle,
1316 SEC_STD_READ_CONTROL);
1317 smb2_util_close(tree, io.out.file.handle);
1319 torture_comment(tctx, "try open for write\n");
1320 io.in.desired_access = SEC_FILE_WRITE_DATA;
1321 status = smb2_create(tree, tctx, &io);
1322 CHECK_STATUS(status, NT_STATUS_OK);
1323 CHECK_ACCESS_FLAGS(io.out.file.handle,
1324 SEC_FILE_WRITE_DATA);
1325 smb2_util_close(tree, io.out.file.handle);
1327 torture_comment(tctx, "try open for read\n");
1328 io.in.desired_access = SEC_FILE_READ_DATA;
1329 status = smb2_create(tree, tctx, &io);
1330 CHECK_STATUS(status, NT_STATUS_OK);
1331 CHECK_ACCESS_FLAGS(io.out.file.handle,
1332 SEC_FILE_READ_DATA);
1333 smb2_util_close(tree, io.out.file.handle);
1335 torture_comment(tctx, "try open for generic write\n");
1336 io.in.desired_access = SEC_GENERIC_WRITE;
1337 status = smb2_create(tree, tctx, &io);
1338 CHECK_STATUS(status, NT_STATUS_OK);
1339 CHECK_ACCESS_FLAGS(io.out.file.handle,
1340 SEC_RIGHTS_FILE_WRITE);
1341 smb2_util_close(tree, io.out.file.handle);
1343 torture_comment(tctx, "try open for generic read\n");
1344 io.in.desired_access = SEC_GENERIC_READ;
1345 status = smb2_create(tree, tctx, &io);
1346 CHECK_STATUS(status, NT_STATUS_OK);
1347 CHECK_ACCESS_FLAGS(io.out.file.handle,
1348 SEC_RIGHTS_FILE_READ);
1349 smb2_util_close(tree, io.out.file.handle);
1351 torture_comment(tctx, "set DACL with 0 aces\n");
1352 ZERO_STRUCT(dacl);
1353 dacl.revision = SECURITY_ACL_REVISION_NT4;
1354 dacl.num_aces = 0;
1355 sd->dacl = &dacl;
1357 s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1358 s.set_secdesc.in.file.handle = handle;
1359 s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1360 s.set_secdesc.in.sd = sd;
1361 status = smb2_setinfo_file(tree, &s);
1362 CHECK_STATUS(status, NT_STATUS_OK);
1364 torture_comment(tctx, "get the sd\n");
1365 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1366 q.query_secdesc.in.file.handle = handle;
1367 q.query_secdesc.in.secinfo_flags =
1368 SECINFO_OWNER |
1369 SECINFO_GROUP |
1370 SECINFO_DACL;
1371 status = smb2_getinfo_file(tree, tctx, &q);
1372 CHECK_STATUS(status, NT_STATUS_OK);
1374 /* Testing the modified DACL */
1375 if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1376 ret = false;
1377 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1379 if (q.query_secdesc.out.sd->dacl == NULL) {
1380 ret = false;
1381 torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
1383 if (q.query_secdesc.out.sd->dacl->num_aces != 0) {
1384 torture_result(tctx, TORTURE_FAIL, "DACL has %u aces!\n",
1385 q.query_secdesc.out.sd->dacl->num_aces);
1386 ret = false;
1387 goto done;
1390 torture_comment(tctx, "try open for read control\n");
1391 io.in.desired_access = SEC_STD_READ_CONTROL;
1392 status = smb2_create(tree, tctx, &io);
1393 CHECK_STATUS(status, NT_STATUS_OK);
1394 CHECK_ACCESS_FLAGS(io.out.file.handle,
1395 SEC_STD_READ_CONTROL);
1396 smb2_util_close(tree, io.out.file.handle);
1398 torture_comment(tctx, "try open for write => access_denied\n");
1399 io.in.desired_access = SEC_FILE_WRITE_DATA;
1400 status = smb2_create(tree, tctx, &io);
1401 if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1402 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1403 } else {
1404 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1407 torture_comment(tctx, "try open for read => access_denied\n");
1408 io.in.desired_access = SEC_FILE_READ_DATA;
1409 status = smb2_create(tree, tctx, &io);
1410 if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1411 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1412 } else {
1413 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1416 torture_comment(tctx, "try open for generic write => access_denied\n");
1417 io.in.desired_access = SEC_GENERIC_WRITE;
1418 status = smb2_create(tree, tctx, &io);
1419 if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1420 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1421 } else {
1422 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1425 torture_comment(tctx, "try open for generic read => access_denied\n");
1426 io.in.desired_access = SEC_GENERIC_READ;
1427 status = smb2_create(tree, tctx, &io);
1428 if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1429 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1430 } else {
1431 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1434 torture_comment(tctx, "set empty sd\n");
1435 sd->type &= ~SEC_DESC_DACL_PRESENT;
1436 sd->dacl = NULL;
1438 s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1439 s.set_secdesc.in.file.handle = handle;
1440 s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1441 s.set_secdesc.in.sd = sd;
1442 status = smb2_setinfo_file(tree, &s);
1443 CHECK_STATUS(status, NT_STATUS_OK);
1445 torture_comment(tctx, "get the sd\n");
1446 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1447 q.query_secdesc.in.file.handle = handle;
1448 q.query_secdesc.in.secinfo_flags =
1449 SECINFO_OWNER |
1450 SECINFO_GROUP |
1451 SECINFO_DACL;
1452 status = smb2_getinfo_file(tree, tctx, &q);
1453 CHECK_STATUS(status, NT_STATUS_OK);
1455 /* Testing the modified DACL */
1456 if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
1457 ret = false;
1458 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
1460 if (q.query_secdesc.out.sd->dacl != NULL) {
1461 ret = false;
1462 torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
1464 done:
1465 smb2_util_close(tree, handle);
1466 smb2_util_unlink(tree, fname);
1467 smb2_tdis(tree);
1468 smb2_logoff(tree->session);
1469 return ret;
1473 basic testing of SMB2 read
1475 struct torture_suite *torture_smb2_create_init(void)
1477 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "create");
1479 torture_suite_add_1smb2_test(suite, "gentest", test_create_gentest);
1480 torture_suite_add_1smb2_test(suite, "blob", test_create_blob);
1481 torture_suite_add_1smb2_test(suite, "open", test_smb2_open);
1482 torture_suite_add_1smb2_test(suite, "brlocked", test_smb2_open_brlocked);
1483 torture_suite_add_1smb2_test(suite, "multi", test_smb2_open_multi);
1484 torture_suite_add_1smb2_test(suite, "delete", test_smb2_open_for_delete);
1485 torture_suite_add_1smb2_test(suite, "leading-slash", test_smb2_leading_slash);
1486 torture_suite_add_1smb2_test(suite, "aclfile", test_create_acl_file);
1487 torture_suite_add_1smb2_test(suite, "acldir", test_create_acl_dir);
1488 torture_suite_add_1smb2_test(suite, "nulldacl", test_create_null_dacl);
1490 suite->description = talloc_strdup(suite, "SMB2-CREATE tests");
1492 return suite;