2 Unix SMB/CIFS implementation.
4 test suite for SMB2 sharemodes
6 Copyright (C) Christof Schmitt 2017
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/>.
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25 #include "libcli/security/security.h"
26 #include "torture/torture.h"
27 #include "torture/smb2/proto.h"
30 #define BASEDIRHOLD "sharemode_hold_test"
32 struct hold_sharemode_info {
33 const char *sharemode;
35 struct smb2_handle handle;
36 } hold_sharemode_table[] = {
39 .filename = BASEDIRHOLD "\\N",
43 .filename = BASEDIRHOLD "\\R",
47 .filename = BASEDIRHOLD "\\W",
51 .filename = BASEDIRHOLD "\\D",
55 .filename = BASEDIRHOLD "\\RW",
59 .filename = BASEDIRHOLD "\\RD",
63 .filename = BASEDIRHOLD "\\WD",
67 .filename = BASEDIRHOLD "\\RWD",
71 static void signal_handler(struct tevent_context *ev,
72 struct tevent_signal *se,
78 struct torture_context *tctx = private_data;
80 torture_comment(tctx, "Received signal %d\n", signum);
84 * Used for manual testing of sharemodes - especially interaction with
85 * other filesystems (such as NFS and local access). The scenario is
86 * that this test holds files open and then concurrent access to the same
87 * files outside of Samba can be tested.
89 bool torture_smb2_hold_sharemode(struct torture_context *tctx)
91 struct tevent_context *ev = tctx->ev;
92 struct smb2_tree *tree = NULL;
93 struct smb2_handle dir_handle;
94 struct tevent_signal *s;
99 if (!torture_smb2_connection(tctx, &tree)) {
100 torture_comment(tctx, "Initializing smb2 connection failed.\n");
104 s = tevent_add_signal(ev, tctx, SIGINT, 0, signal_handler, tctx);
105 torture_assert_not_null_goto(tctx, s, ret, done,
106 "Error registering signal handler.");
108 torture_comment(tctx, "Setting up open files with sharemodes in %s\n",
111 status = torture_smb2_testdir(tree, BASEDIRHOLD, &dir_handle);
112 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
113 "Error creating directory.");
115 for (i = 0; i < ARRAY_SIZE(hold_sharemode_table); i++) {
116 struct hold_sharemode_info *info = &hold_sharemode_table[i];
117 struct smb2_create create = { };
119 create.in.desired_access = SEC_RIGHTS_FILE_ALL;
120 create.in.alloc_size = 0;
121 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
122 create.in.share_access =
123 smb2_util_share_access(info->sharemode);
124 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
125 create.in.create_options = 0;
126 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
127 create.in.security_flags = 0;
128 create.in.fname = info->filename;
129 create.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
130 create.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
132 torture_comment(tctx, "opening %s\n", info->filename);
134 status = smb2_create(tree, tctx, &create);
136 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
137 "CREATE file failed\n");
139 info->handle = create.out.file.handle;
142 torture_comment(tctx, "Waiting for SIGINT (ctrl-c)\n");
143 tevent_loop_wait(ev);
145 torture_comment(tctx, "Closing and deleting files\n");
147 for (i = 0; i < ARRAY_SIZE(hold_sharemode_table); i++) {
148 struct hold_sharemode_info *info = &hold_sharemode_table[i];
150 union smb_setfileinfo sfinfo = { };
152 sfinfo.disposition_info.in.delete_on_close = 1;
153 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
154 sfinfo.generic.in.file.handle = info->handle;
155 status = smb2_setinfo_file(tree, &sfinfo);
156 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
159 status = smb2_util_close(tree, info->handle);
160 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
161 torture_comment(tctx, "File %s not found, could have "
162 "been deleted outside of SMB\n",
166 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
171 smb2_deltree(tree, BASEDIRHOLD);
176 * Used for manual testing of sharemodes, especially interaction with
177 * file systems that can enforce sharemodes. The scenario here is that
178 * a file is already open outside of Samba with a sharemode and this
179 * can be used to test accessing the same file from Samba.
181 bool torture_smb2_check_sharemode(struct torture_context *tctx)
183 const char *sharemode_string, *access_string, *filename, *operation;
184 uint32_t sharemode, access;
185 struct smb2_tree *tree;
186 struct smb2_create create = { };
191 sharemode_string = torture_setting_string(tctx, "sharemode", "RWD");
192 sharemode = smb2_util_share_access(sharemode_string);
194 access_string = torture_setting_string(tctx, "access", "0xf01ff");
195 access = strtoul_err(access_string, NULL, 0, &error);
197 torture_comment(tctx, "Initializing access failed.\n");
201 filename = torture_setting_string(tctx, "filename", "testfile");
202 operation = torture_setting_string(tctx, "operation", "WD");
204 if (!torture_smb2_connection(tctx, &tree)) {
205 torture_comment(tctx, "Initializing smb2 connection failed.\n");
209 create.in.desired_access = access;
210 create.in.alloc_size = 0;
211 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
212 create.in.share_access = sharemode;
213 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
214 create.in.create_options = 0;
215 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
216 create.in.security_flags = 0;
217 create.in.fname = filename;
218 create.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
219 create.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
221 status = smb2_create(tree, tctx, &create);
222 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
225 if (strchr(operation, 'R')) {
226 struct smb2_read read = { 0 };
228 read.in.file.handle = create.out.file.handle;
232 status = smb2_read(tree, tctx, &read);
233 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
237 if (strchr(operation, 'W')) {
239 status = smb2_util_write(tree, create.out.file.handle,
240 &buf, 0, sizeof(buf));
241 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
245 if (strchr(operation, 'D')) {
246 union smb_setfileinfo sfinfo = { };
248 sfinfo.disposition_info.in.delete_on_close = 1;
249 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
250 sfinfo.generic.in.file.handle = create.out.file.handle;
252 status = smb2_setinfo_file(tree, &sfinfo);
253 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
256 status = smb2_util_close(tree, create.out.file.handle);
257 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
265 struct sharemode_info {
266 const char *sharemode;
267 uint32_t access_mask;
269 } sharemode_table[] = {
272 * Basic tests, check each permission bit against every
273 * possible sharemode combination.
276 { "R", SEC_FILE_READ_DATA, true, },
277 { "R", SEC_FILE_WRITE_DATA, false, },
278 { "R", SEC_FILE_APPEND_DATA, false, },
279 { "R", SEC_FILE_READ_EA, true, },
280 { "R", SEC_FILE_WRITE_EA, true, },
281 { "R", SEC_FILE_EXECUTE, true, },
282 { "R", SEC_FILE_READ_ATTRIBUTE, true, },
283 { "R", SEC_FILE_WRITE_ATTRIBUTE, true, },
284 { "R", SEC_STD_DELETE, false, },
285 { "R", SEC_STD_READ_CONTROL, true, },
286 { "R", SEC_STD_WRITE_DAC, true, },
287 { "R", SEC_STD_WRITE_OWNER, true, },
288 { "R", SEC_STD_SYNCHRONIZE, true, },
290 { "W", SEC_FILE_READ_DATA, false },
291 { "W", SEC_FILE_WRITE_DATA, true, },
292 { "W", SEC_FILE_APPEND_DATA, true, },
293 { "W", SEC_FILE_READ_EA, true, },
294 { "W", SEC_FILE_WRITE_EA, true, },
295 { "W", SEC_FILE_EXECUTE, false, },
296 { "W", SEC_FILE_READ_ATTRIBUTE, true, },
297 { "W", SEC_FILE_WRITE_ATTRIBUTE, true, },
298 { "W", SEC_STD_DELETE, false, },
299 { "W", SEC_STD_READ_CONTROL, true, },
300 { "W", SEC_STD_WRITE_DAC, true, },
301 { "W", SEC_STD_WRITE_OWNER, true, },
302 { "W", SEC_STD_SYNCHRONIZE, true, },
304 { "D", SEC_FILE_READ_DATA, false },
305 { "D", SEC_FILE_WRITE_DATA, false },
306 { "D", SEC_FILE_APPEND_DATA, false },
307 { "D", SEC_FILE_READ_EA, true, },
308 { "D", SEC_FILE_WRITE_EA, true, },
309 { "D", SEC_FILE_EXECUTE, false, },
310 { "D", SEC_FILE_READ_ATTRIBUTE, true, },
311 { "D", SEC_FILE_WRITE_ATTRIBUTE, true, },
312 { "D", SEC_STD_DELETE, true, },
313 { "D", SEC_STD_READ_CONTROL, true, },
314 { "D", SEC_STD_WRITE_DAC, true, },
315 { "D", SEC_STD_WRITE_OWNER, true, },
316 { "D", SEC_STD_SYNCHRONIZE, true, },
318 { "RW", SEC_FILE_READ_DATA, true, },
319 { "RW", SEC_FILE_WRITE_DATA, true, },
320 { "RW", SEC_FILE_APPEND_DATA, true, },
321 { "RW", SEC_FILE_READ_EA, true, },
322 { "RW", SEC_FILE_WRITE_EA, true, },
323 { "RW", SEC_FILE_EXECUTE, true, },
324 { "RW", SEC_FILE_READ_ATTRIBUTE, true, },
325 { "RW", SEC_FILE_WRITE_ATTRIBUTE, true, },
326 { "RW", SEC_STD_DELETE, false, },
327 { "RW", SEC_STD_READ_CONTROL, true, },
328 { "RW", SEC_STD_WRITE_DAC, true, },
329 { "RW", SEC_STD_WRITE_OWNER, true, },
330 { "RW", SEC_STD_SYNCHRONIZE, true, },
332 { "RD", SEC_FILE_READ_DATA, true, },
333 { "RD", SEC_FILE_WRITE_DATA, false, },
334 { "RD", SEC_FILE_APPEND_DATA, false, },
335 { "RD", SEC_FILE_READ_EA, true, },
336 { "RD", SEC_FILE_WRITE_EA, true, },
337 { "RD", SEC_FILE_EXECUTE, true, },
338 { "RD", SEC_FILE_READ_ATTRIBUTE, true, },
339 { "RD", SEC_FILE_WRITE_ATTRIBUTE, true, },
340 { "RD", SEC_STD_DELETE, true, },
341 { "RD", SEC_STD_READ_CONTROL, true, },
342 { "RD", SEC_STD_WRITE_DAC, true, },
343 { "RD", SEC_STD_WRITE_OWNER, true, },
344 { "RD", SEC_STD_SYNCHRONIZE, true, },
346 { "WD", SEC_FILE_READ_DATA, false },
347 { "WD", SEC_FILE_WRITE_DATA, true, },
348 { "WD", SEC_FILE_APPEND_DATA, true, },
349 { "WD", SEC_FILE_READ_EA, true },
350 { "WD", SEC_FILE_WRITE_EA, true, },
351 { "WD", SEC_FILE_EXECUTE, false },
352 { "WD", SEC_FILE_READ_ATTRIBUTE, true, },
353 { "WD", SEC_FILE_WRITE_ATTRIBUTE, true, },
354 { "WD", SEC_STD_DELETE, true, },
355 { "WD", SEC_STD_READ_CONTROL, true, },
356 { "WD", SEC_STD_WRITE_DAC, true, },
357 { "WD", SEC_STD_WRITE_OWNER, true, },
358 { "WD", SEC_STD_SYNCHRONIZE, true, },
360 { "RWD", SEC_FILE_READ_DATA, true },
361 { "RWD", SEC_FILE_WRITE_DATA, true, },
362 { "RWD", SEC_FILE_APPEND_DATA, true, },
363 { "RWD", SEC_FILE_READ_EA, true },
364 { "RWD", SEC_FILE_WRITE_EA, true, },
365 { "RWD", SEC_FILE_EXECUTE, true, },
366 { "RWD", SEC_FILE_READ_ATTRIBUTE, true, },
367 { "RWD", SEC_FILE_WRITE_ATTRIBUTE, true, },
368 { "RWD", SEC_STD_DELETE, true, },
369 { "RWD", SEC_STD_READ_CONTROL, true, },
370 { "RWD", SEC_STD_WRITE_DAC, true, },
371 { "RWD", SEC_STD_WRITE_OWNER, true, },
372 { "RWD", SEC_STD_SYNCHRONIZE, true, },
375 * Some more interesting cases. Always request READ or WRITE
376 * access, as that will trigger the opening of a file
377 * description in Samba. This especially useful for file
378 * systems that enforce share modes on open file descriptors.
381 { "R", SEC_FILE_READ_DATA, true, },
382 { "R", SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA, false, },
383 { "R", SEC_FILE_READ_DATA|SEC_FILE_APPEND_DATA, false, },
384 { "R", SEC_FILE_READ_DATA|SEC_FILE_READ_EA, true, },
385 { "R", SEC_FILE_READ_DATA|SEC_FILE_WRITE_EA, true, },
386 { "R", SEC_FILE_READ_DATA|SEC_FILE_EXECUTE, true, },
387 { "R", SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE, true, },
388 { "R", SEC_FILE_READ_DATA|SEC_FILE_WRITE_ATTRIBUTE, true, },
389 { "R", SEC_FILE_READ_DATA|SEC_STD_DELETE, false, },
390 { "R", SEC_FILE_READ_DATA|SEC_STD_READ_CONTROL, true, },
391 { "R", SEC_FILE_READ_DATA|SEC_STD_WRITE_DAC, true, },
392 { "R", SEC_FILE_READ_DATA|SEC_STD_WRITE_OWNER, true, },
393 { "R", SEC_FILE_READ_DATA|SEC_STD_SYNCHRONIZE, true, },
395 { "W", SEC_FILE_WRITE_DATA|SEC_FILE_READ_DATA, false, },
396 { "W", SEC_FILE_WRITE_DATA, true, },
397 { "W", SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA, true, },
398 { "W", SEC_FILE_WRITE_DATA|SEC_FILE_READ_EA, true, },
399 { "W", SEC_FILE_WRITE_DATA|SEC_FILE_WRITE_EA, true, },
400 { "W", SEC_FILE_WRITE_DATA|SEC_FILE_EXECUTE, false, },
401 { "W", SEC_FILE_WRITE_DATA|SEC_FILE_READ_ATTRIBUTE, true, },
402 { "W", SEC_FILE_WRITE_DATA|SEC_FILE_WRITE_ATTRIBUTE, true, },
403 { "W", SEC_FILE_WRITE_DATA|SEC_STD_DELETE, false, },
404 { "W", SEC_FILE_WRITE_DATA|SEC_STD_READ_CONTROL, true, },
405 { "W", SEC_FILE_WRITE_DATA|SEC_STD_WRITE_DAC, true, },
406 { "W", SEC_FILE_WRITE_DATA|SEC_STD_WRITE_OWNER, true, },
407 { "W", SEC_FILE_WRITE_DATA|SEC_STD_SYNCHRONIZE, true, },
409 { "RW", SEC_FILE_READ_DATA, true, },
410 { "RW", SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA, true, },
411 { "RW", SEC_FILE_READ_DATA|SEC_FILE_APPEND_DATA, true, },
412 { "RW", SEC_FILE_READ_DATA|SEC_FILE_READ_EA, true, },
413 { "RW", SEC_FILE_READ_DATA|SEC_FILE_WRITE_EA, true, },
414 { "RW", SEC_FILE_READ_DATA|SEC_FILE_EXECUTE, true, },
415 { "RW", SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE, true, },
416 { "RW", SEC_FILE_READ_DATA|SEC_FILE_WRITE_ATTRIBUTE, true, },
417 { "RW", SEC_FILE_READ_DATA|SEC_STD_DELETE, false, },
418 { "RW", SEC_FILE_READ_DATA|SEC_STD_READ_CONTROL, true, },
419 { "RW", SEC_FILE_READ_DATA|SEC_STD_WRITE_DAC, true, },
420 { "RW", SEC_FILE_READ_DATA|SEC_STD_WRITE_OWNER, true, },
421 { "RW", SEC_FILE_READ_DATA|SEC_STD_SYNCHRONIZE, true, },
423 { "RD", SEC_FILE_READ_DATA, true, },
424 { "RD", SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA, false, },
425 { "RD", SEC_FILE_READ_DATA|SEC_FILE_APPEND_DATA, false, },
426 { "RD", SEC_FILE_READ_DATA|SEC_FILE_READ_EA, true },
427 { "RD", SEC_FILE_READ_DATA|SEC_FILE_WRITE_EA, true, },
428 { "RD", SEC_FILE_READ_DATA|SEC_FILE_EXECUTE, true, },
429 { "RD", SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE, true, },
430 { "RD", SEC_FILE_READ_DATA|SEC_FILE_WRITE_ATTRIBUTE, true, },
431 { "RD", SEC_FILE_READ_DATA|SEC_STD_DELETE, true, },
432 { "RD", SEC_FILE_READ_DATA|SEC_STD_READ_CONTROL, true, },
433 { "RD", SEC_FILE_READ_DATA|SEC_STD_WRITE_DAC, true, },
434 { "RD", SEC_FILE_READ_DATA|SEC_STD_WRITE_OWNER, true, },
435 { "RD", SEC_FILE_READ_DATA|SEC_STD_SYNCHRONIZE, true, },
437 { "WD", SEC_FILE_WRITE_DATA|SEC_FILE_READ_DATA, false },
438 { "WD", SEC_FILE_WRITE_DATA, true, },
439 { "WD", SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA, true, },
440 { "WD", SEC_FILE_WRITE_DATA|SEC_FILE_READ_EA, true },
441 { "WD", SEC_FILE_WRITE_DATA|SEC_FILE_WRITE_EA, true, },
442 { "WD", SEC_FILE_WRITE_DATA|SEC_FILE_EXECUTE, false },
443 { "WD", SEC_FILE_WRITE_DATA|SEC_FILE_READ_ATTRIBUTE, true, },
444 { "WD", SEC_FILE_WRITE_DATA|SEC_FILE_WRITE_ATTRIBUTE, true, },
445 { "WD", SEC_FILE_WRITE_DATA|SEC_STD_DELETE, true, },
446 { "WD", SEC_FILE_WRITE_DATA|SEC_STD_READ_CONTROL, true, },
447 { "WD", SEC_FILE_WRITE_DATA|SEC_STD_WRITE_DAC, true, },
448 { "WD", SEC_FILE_WRITE_DATA|SEC_STD_WRITE_OWNER, true, },
449 { "WD", SEC_FILE_WRITE_DATA|SEC_STD_SYNCHRONIZE, true, },
451 { "RWD", SEC_FILE_READ_DATA, true },
452 { "RWD", SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA, true, },
453 { "RWD", SEC_FILE_READ_DATA|SEC_FILE_APPEND_DATA, true, },
454 { "RWD", SEC_FILE_READ_DATA|SEC_FILE_READ_EA, true, },
455 { "RWD", SEC_FILE_READ_DATA|SEC_FILE_WRITE_EA, true, },
456 { "RWD", SEC_FILE_READ_DATA|SEC_FILE_EXECUTE, true, },
457 { "RWD", SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE, true, },
458 { "RWD", SEC_FILE_READ_DATA|SEC_FILE_WRITE_ATTRIBUTE, true, },
459 { "RWD", SEC_FILE_READ_DATA|SEC_STD_DELETE, true, },
460 { "RWD", SEC_FILE_READ_DATA|SEC_STD_READ_CONTROL, true, },
461 { "RWD", SEC_FILE_READ_DATA|SEC_STD_WRITE_DAC, true, },
462 { "RWD", SEC_FILE_READ_DATA|SEC_STD_WRITE_OWNER, true, },
463 { "RWD", SEC_FILE_READ_DATA|SEC_STD_SYNCHRONIZE, true, },
467 * Test conflicting sharemodes through SMB2: First open takes a
468 * sharemode, second open with potentially conflicting access.
470 static bool test_smb2_sharemode_access(struct torture_context *tctx,
471 struct smb2_tree *tree)
473 const char *fname = "test_sharemode";
478 for (i = 0; i < ARRAY_SIZE(sharemode_table); i++) {
479 struct sharemode_info *info = &sharemode_table[i];
480 struct smb2_create create1 = { }, create2 = { };
481 NTSTATUS expected_status;
483 torture_comment(tctx, "index %3d, sharemode %3s, "
484 "access mask 0x%06x\n",
485 i, info->sharemode, info->access_mask);
487 create1.in.desired_access = SEC_RIGHTS_FILE_ALL;
488 create1.in.alloc_size = 0;
489 create1.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
490 create1.in.share_access =
491 smb2_util_share_access(info->sharemode);
492 create1.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
493 create1.in.create_options = 0;
494 create1.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
495 create1.in.fname = fname;
496 create1.in.security_flags = 0;
497 create1.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
498 create1.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
500 status = smb2_create(tree, tctx, &create1);
502 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
503 "CREATE file failed\n");
505 create2.in.desired_access = info->access_mask;
506 create2.in.alloc_size = 0;
507 create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
508 create2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
509 NTCREATEX_SHARE_ACCESS_WRITE |
510 NTCREATEX_SHARE_ACCESS_DELETE;
511 create2.in.create_disposition = NTCREATEX_DISP_OPEN;
512 create2.in.create_options = 0;
513 create2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
514 create2.in.fname = fname;
515 create2.in.security_flags = 0;
516 create2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
517 create2.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
519 status = smb2_create(tree, tctx, &create2);
520 expected_status = info->expect_ok ?
521 NT_STATUS_OK : NT_STATUS_SHARING_VIOLATION;
522 torture_assert_ntstatus_equal_goto(tctx, status,
523 expected_status, ret,
524 done, "Unexpected status on "
527 status = smb2_util_close(tree, create1.out.file.handle);
528 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
532 if (info->expect_ok) {
533 status = smb2_util_close(tree, create2.out.file.handle);
534 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
541 smb2_util_unlink(tree, fname);
546 * Test conflicting sharemodes through SMB2: First open file with
547 * different access masks, second open requests potentially conflict
550 static bool test_smb2_access_sharemode(struct torture_context *tctx,
551 struct smb2_tree *tree)
553 const char *fname = "test_sharemode";
558 for (i = 0; i < ARRAY_SIZE(sharemode_table); i++) {
559 struct sharemode_info *info = &sharemode_table[i];
560 struct smb2_create create1 = { }, create2 = { };
561 NTSTATUS expected_status;
563 torture_comment(tctx, "index %3d, access mask 0x%06x, "
565 i, info->access_mask, info->sharemode);
567 create1.in.desired_access = info->access_mask;
568 create1.in.alloc_size = 0;
569 create1.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
570 create1.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
571 NTCREATEX_SHARE_ACCESS_WRITE |
572 NTCREATEX_SHARE_ACCESS_DELETE;
573 create1.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
574 create1.in.create_options = 0;
575 create1.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
576 create1.in.fname = fname;
577 create1.in.security_flags = 0;
578 create1.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
579 create1.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
581 status = smb2_create(tree, tctx, &create1);
583 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
584 "CREATE file failed\n");
586 create2.in.desired_access = SEC_RIGHTS_FILE_ALL;
587 create2.in.alloc_size = 0;
588 create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
589 create2.in.share_access =
590 smb2_util_share_access(info->sharemode);
591 create2.in.create_disposition = NTCREATEX_DISP_OPEN;
592 create2.in.create_options = 0;
593 create2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
594 create2.in.fname = fname;
595 create2.in.security_flags = 0;
596 create2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
597 create2.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
599 status = smb2_create(tree, tctx, &create2);
601 expected_status = info->expect_ok ?
602 NT_STATUS_OK : NT_STATUS_SHARING_VIOLATION;
603 torture_assert_ntstatus_equal_goto(tctx, status,
604 expected_status, ret,
605 done, "Unexpected status on "
608 status = smb2_util_close(tree, create1.out.file.handle);
609 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
613 if (info->expect_ok) {
614 status = smb2_util_close(tree, create2.out.file.handle);
615 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
622 smb2_util_unlink(tree, fname);
626 struct torture_suite *torture_smb2_sharemode_init(TALLOC_CTX *ctx)
628 struct torture_suite *suite = torture_suite_create(ctx, "sharemode");
630 torture_suite_add_1smb2_test(suite, "sharemode-access",
631 test_smb2_sharemode_access);
632 torture_suite_add_1smb2_test(suite, "access-sharemode",
633 test_smb2_access_sharemode);
635 suite->description = talloc_strdup(suite, "SMB2-SHAREMODE tests");