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
[] = {
37 { "", BASEDIRHOLD
"\\N" },
38 { "R", BASEDIRHOLD
"\\R" },
39 { "W", BASEDIRHOLD
"\\W" },
40 { "D", BASEDIRHOLD
"\\D" },
41 { "RW", BASEDIRHOLD
"\\RW" },
42 { "RD", BASEDIRHOLD
"\\RD" },
43 { "WD", BASEDIRHOLD
"\\WD" },
44 { "RWD", BASEDIRHOLD
"\\RWD" },
47 static void signal_handler(struct tevent_context
*ev
,
48 struct tevent_signal
*se
,
54 struct torture_context
*tctx
= private_data
;
56 torture_comment(tctx
, "Received signal %d\n", signum
);
60 * Used for manual testing of sharemodes - especially interaction with
61 * other filesystems (such as NFS and local access). The scenario is
62 * that this test holds files open and then concurrent access to the same
63 * files outside of Samba can be tested.
65 bool torture_smb2_hold_sharemode(struct torture_context
*tctx
)
67 struct tevent_context
*ev
= tctx
->ev
;
68 struct smb2_tree
*tree
= NULL
;
69 struct smb2_handle dir_handle
;
70 struct tevent_signal
*s
;
75 if (!torture_smb2_connection(tctx
, &tree
)) {
76 torture_comment(tctx
, "Initializing smb2 connection failed.\n");
80 s
= tevent_add_signal(ev
, tctx
, SIGINT
, 0, signal_handler
, tctx
);
81 torture_assert_not_null_goto(tctx
, s
, ret
, done
,
82 "Error registering signal handler.");
84 torture_comment(tctx
, "Setting up open files with sharemodes in %s\n",
87 status
= torture_smb2_testdir(tree
, BASEDIRHOLD
, &dir_handle
);
88 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
89 "Error creating directory.");
91 for (i
= 0; i
< ARRAY_SIZE(hold_sharemode_table
); i
++) {
92 struct hold_sharemode_info
*info
= &hold_sharemode_table
[i
];
93 struct smb2_create create
= { };
95 create
.in
.desired_access
= SEC_RIGHTS_FILE_ALL
;
96 create
.in
.alloc_size
= 0;
97 create
.in
.file_attributes
= FILE_ATTRIBUTE_NORMAL
;
98 create
.in
.share_access
=
99 smb2_util_share_access(info
->sharemode
);
100 create
.in
.create_disposition
= NTCREATEX_DISP_OPEN_IF
;
101 create
.in
.create_options
= 0;
102 create
.in
.impersonation_level
= SMB2_IMPERSONATION_ANONYMOUS
;
103 create
.in
.security_flags
= 0;
104 create
.in
.fname
= info
->filename
;
105 create
.in
.create_flags
= NTCREATEX_FLAGS_EXTENDED
;
106 create
.in
.oplock_level
= SMB2_OPLOCK_LEVEL_NONE
;
108 torture_comment(tctx
, "opening %s\n", info
->filename
);
110 status
= smb2_create(tree
, tctx
, &create
);
112 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
113 "CREATE file failed\n");
115 info
->handle
= create
.out
.file
.handle
;
118 torture_comment(tctx
, "Waiting for SIGINT (ctrl-c)\n");
119 tevent_loop_wait(ev
);
121 torture_comment(tctx
, "Closing and deleting files\n");
123 for (i
= 0; i
< ARRAY_SIZE(hold_sharemode_table
); i
++) {
124 struct hold_sharemode_info
*info
= &hold_sharemode_table
[i
];
126 union smb_setfileinfo sfinfo
= { };
128 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
129 sfinfo
.generic
.level
= RAW_SFILEINFO_DISPOSITION_INFORMATION
;
130 sfinfo
.generic
.in
.file
.handle
= info
->handle
;
131 status
= smb2_setinfo_file(tree
, &sfinfo
);
132 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
135 status
= smb2_util_close(tree
, info
->handle
);
136 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
137 torture_comment(tctx
, "File %s not found, could have "
138 "been deleted outside of SMB\n",
142 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
147 smb2_deltree(tree
, BASEDIRHOLD
);
152 * Used for manual testing of sharemodes, especially interaction with
153 * file systems that can enforce sharemodes. The scenario here is that
154 * a file is already open outside of Samba with a sharemode and this
155 * can be used to test accessing the same file from Samba.
157 bool torture_smb2_check_sharemode(struct torture_context
*tctx
)
159 const char *sharemode_string
, *access_string
, *filename
, *operation
;
160 uint32_t sharemode
, access
;
161 struct smb2_tree
*tree
;
162 struct smb2_create create
= { };
166 sharemode_string
= torture_setting_string(tctx
, "sharemode", "RWD");
167 sharemode
= smb2_util_share_access(sharemode_string
);
169 access_string
= torture_setting_string(tctx
, "access", "0xf01ff");
170 access
= strtoul(access_string
, NULL
, 0);
172 filename
= torture_setting_string(tctx
, "filename", "testfile");
173 operation
= torture_setting_string(tctx
, "operation", "WD");
175 if (!torture_smb2_connection(tctx
, &tree
)) {
176 torture_comment(tctx
, "Initializing smb2 connection failed.\n");
180 create
.in
.desired_access
= access
;
181 create
.in
.alloc_size
= 0;
182 create
.in
.file_attributes
= FILE_ATTRIBUTE_NORMAL
;
183 create
.in
.share_access
= sharemode
;
184 create
.in
.create_disposition
= NTCREATEX_DISP_OPEN_IF
;
185 create
.in
.create_options
= 0;
186 create
.in
.impersonation_level
= SMB2_IMPERSONATION_ANONYMOUS
;
187 create
.in
.security_flags
= 0;
188 create
.in
.fname
= filename
;
189 create
.in
.create_flags
= NTCREATEX_FLAGS_EXTENDED
;
190 create
.in
.oplock_level
= SMB2_OPLOCK_LEVEL_NONE
;
192 status
= smb2_create(tree
, tctx
, &create
);
193 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
196 if (strchr(operation
, 'R')) {
197 struct smb2_read read
= { 0 };
199 read
.in
.file
.handle
= create
.out
.file
.handle
;
203 status
= smb2_read(tree
, tctx
, &read
);
204 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
208 if (strchr(operation
, 'W')) {
210 status
= smb2_util_write(tree
, create
.out
.file
.handle
,
211 &buf
, 0, sizeof(buf
));
212 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
216 if (strchr(operation
, 'D')) {
217 union smb_setfileinfo sfinfo
= { };
219 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
220 sfinfo
.generic
.level
= RAW_SFILEINFO_DISPOSITION_INFORMATION
;
221 sfinfo
.generic
.in
.file
.handle
= create
.out
.file
.handle
;
223 status
= smb2_setinfo_file(tree
, &sfinfo
);
224 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
227 status
= smb2_util_close(tree
, create
.out
.file
.handle
);
228 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
236 struct sharemode_info
{
237 const char *sharemode
;
238 uint32_t access_mask
;
240 } sharemode_table
[] = {
243 * Basic tests, check each permission bit against every
244 * possible sharemode combination.
247 { "R", SEC_FILE_READ_DATA
, true, },
248 { "R", SEC_FILE_WRITE_DATA
, false, },
249 { "R", SEC_FILE_APPEND_DATA
, false, },
250 { "R", SEC_FILE_READ_EA
, true, },
251 { "R", SEC_FILE_WRITE_EA
, true, },
252 { "R", SEC_FILE_EXECUTE
, true, },
253 { "R", SEC_FILE_READ_ATTRIBUTE
, true, },
254 { "R", SEC_FILE_WRITE_ATTRIBUTE
, true, },
255 { "R", SEC_STD_DELETE
, false, },
256 { "R", SEC_STD_READ_CONTROL
, true, },
257 { "R", SEC_STD_WRITE_DAC
, true, },
258 { "R", SEC_STD_WRITE_OWNER
, true, },
259 { "R", SEC_STD_SYNCHRONIZE
, true, },
261 { "W", SEC_FILE_READ_DATA
, false },
262 { "W", SEC_FILE_WRITE_DATA
, true, },
263 { "W", SEC_FILE_APPEND_DATA
, true, },
264 { "W", SEC_FILE_READ_EA
, true, },
265 { "W", SEC_FILE_WRITE_EA
, true, },
266 { "W", SEC_FILE_EXECUTE
, false, },
267 { "W", SEC_FILE_READ_ATTRIBUTE
, true, },
268 { "W", SEC_FILE_WRITE_ATTRIBUTE
, true, },
269 { "W", SEC_STD_DELETE
, false, },
270 { "W", SEC_STD_READ_CONTROL
, true, },
271 { "W", SEC_STD_WRITE_DAC
, true, },
272 { "W", SEC_STD_WRITE_OWNER
, true, },
273 { "W", SEC_STD_SYNCHRONIZE
, true, },
275 { "D", SEC_FILE_READ_DATA
, false },
276 { "D", SEC_FILE_WRITE_DATA
, false },
277 { "D", SEC_FILE_APPEND_DATA
, false },
278 { "D", SEC_FILE_READ_EA
, true, },
279 { "D", SEC_FILE_WRITE_EA
, true, },
280 { "D", SEC_FILE_EXECUTE
, false, },
281 { "D", SEC_FILE_READ_ATTRIBUTE
, true, },
282 { "D", SEC_FILE_WRITE_ATTRIBUTE
, true, },
283 { "D", SEC_STD_DELETE
, true, },
284 { "D", SEC_STD_READ_CONTROL
, true, },
285 { "D", SEC_STD_WRITE_DAC
, true, },
286 { "D", SEC_STD_WRITE_OWNER
, true, },
287 { "D", SEC_STD_SYNCHRONIZE
, true, },
289 { "RW", SEC_FILE_READ_DATA
, true, },
290 { "RW", SEC_FILE_WRITE_DATA
, true, },
291 { "RW", SEC_FILE_APPEND_DATA
, true, },
292 { "RW", SEC_FILE_READ_EA
, true, },
293 { "RW", SEC_FILE_WRITE_EA
, true, },
294 { "RW", SEC_FILE_EXECUTE
, true, },
295 { "RW", SEC_FILE_READ_ATTRIBUTE
, true, },
296 { "RW", SEC_FILE_WRITE_ATTRIBUTE
, true, },
297 { "RW", SEC_STD_DELETE
, false, },
298 { "RW", SEC_STD_READ_CONTROL
, true, },
299 { "RW", SEC_STD_WRITE_DAC
, true, },
300 { "RW", SEC_STD_WRITE_OWNER
, true, },
301 { "RW", SEC_STD_SYNCHRONIZE
, true, },
303 { "RD", SEC_FILE_READ_DATA
, true, },
304 { "RD", SEC_FILE_WRITE_DATA
, false, },
305 { "RD", SEC_FILE_APPEND_DATA
, false, },
306 { "RD", SEC_FILE_READ_EA
, true, },
307 { "RD", SEC_FILE_WRITE_EA
, true, },
308 { "RD", SEC_FILE_EXECUTE
, true, },
309 { "RD", SEC_FILE_READ_ATTRIBUTE
, true, },
310 { "RD", SEC_FILE_WRITE_ATTRIBUTE
, true, },
311 { "RD", SEC_STD_DELETE
, true, },
312 { "RD", SEC_STD_READ_CONTROL
, true, },
313 { "RD", SEC_STD_WRITE_DAC
, true, },
314 { "RD", SEC_STD_WRITE_OWNER
, true, },
315 { "RD", SEC_STD_SYNCHRONIZE
, true, },
317 { "WD", SEC_FILE_READ_DATA
, false },
318 { "WD", SEC_FILE_WRITE_DATA
, true, },
319 { "WD", SEC_FILE_APPEND_DATA
, true, },
320 { "WD", SEC_FILE_READ_EA
, true },
321 { "WD", SEC_FILE_WRITE_EA
, true, },
322 { "WD", SEC_FILE_EXECUTE
, false },
323 { "WD", SEC_FILE_READ_ATTRIBUTE
, true, },
324 { "WD", SEC_FILE_WRITE_ATTRIBUTE
, true, },
325 { "WD", SEC_STD_DELETE
, true, },
326 { "WD", SEC_STD_READ_CONTROL
, true, },
327 { "WD", SEC_STD_WRITE_DAC
, true, },
328 { "WD", SEC_STD_WRITE_OWNER
, true, },
329 { "WD", SEC_STD_SYNCHRONIZE
, true, },
331 { "RWD", SEC_FILE_READ_DATA
, true },
332 { "RWD", SEC_FILE_WRITE_DATA
, true, },
333 { "RWD", SEC_FILE_APPEND_DATA
, true, },
334 { "RWD", SEC_FILE_READ_EA
, true },
335 { "RWD", SEC_FILE_WRITE_EA
, true, },
336 { "RWD", SEC_FILE_EXECUTE
, true, },
337 { "RWD", SEC_FILE_READ_ATTRIBUTE
, true, },
338 { "RWD", SEC_FILE_WRITE_ATTRIBUTE
, true, },
339 { "RWD", SEC_STD_DELETE
, true, },
340 { "RWD", SEC_STD_READ_CONTROL
, true, },
341 { "RWD", SEC_STD_WRITE_DAC
, true, },
342 { "RWD", SEC_STD_WRITE_OWNER
, true, },
343 { "RWD", SEC_STD_SYNCHRONIZE
, true, },
346 * Some more interesting cases. Always request READ or WRITE
347 * access, as that will trigger the opening of a file
348 * description in Samba. This especially useful for file
349 * systems that enforce share modes on open file descriptors.
352 { "R", SEC_FILE_READ_DATA
, true, },
353 { "R", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_DATA
, false, },
354 { "R", SEC_FILE_READ_DATA
|SEC_FILE_APPEND_DATA
, false, },
355 { "R", SEC_FILE_READ_DATA
|SEC_FILE_READ_EA
, true, },
356 { "R", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_EA
, true, },
357 { "R", SEC_FILE_READ_DATA
|SEC_FILE_EXECUTE
, true, },
358 { "R", SEC_FILE_READ_DATA
|SEC_FILE_READ_ATTRIBUTE
, true, },
359 { "R", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_ATTRIBUTE
, true, },
360 { "R", SEC_FILE_READ_DATA
|SEC_STD_DELETE
, false, },
361 { "R", SEC_FILE_READ_DATA
|SEC_STD_READ_CONTROL
, true, },
362 { "R", SEC_FILE_READ_DATA
|SEC_STD_WRITE_DAC
, true, },
363 { "R", SEC_FILE_READ_DATA
|SEC_STD_WRITE_OWNER
, true, },
364 { "R", SEC_FILE_READ_DATA
|SEC_STD_SYNCHRONIZE
, true, },
366 { "W", SEC_FILE_WRITE_DATA
|SEC_FILE_READ_DATA
, false, },
367 { "W", SEC_FILE_WRITE_DATA
, true, },
368 { "W", SEC_FILE_WRITE_DATA
|SEC_FILE_APPEND_DATA
, true, },
369 { "W", SEC_FILE_WRITE_DATA
|SEC_FILE_READ_EA
, true, },
370 { "W", SEC_FILE_WRITE_DATA
|SEC_FILE_WRITE_EA
, true, },
371 { "W", SEC_FILE_WRITE_DATA
|SEC_FILE_EXECUTE
, false, },
372 { "W", SEC_FILE_WRITE_DATA
|SEC_FILE_READ_ATTRIBUTE
, true, },
373 { "W", SEC_FILE_WRITE_DATA
|SEC_FILE_WRITE_ATTRIBUTE
, true, },
374 { "W", SEC_FILE_WRITE_DATA
|SEC_STD_DELETE
, false, },
375 { "W", SEC_FILE_WRITE_DATA
|SEC_STD_READ_CONTROL
, true, },
376 { "W", SEC_FILE_WRITE_DATA
|SEC_STD_WRITE_DAC
, true, },
377 { "W", SEC_FILE_WRITE_DATA
|SEC_STD_WRITE_OWNER
, true, },
378 { "W", SEC_FILE_WRITE_DATA
|SEC_STD_SYNCHRONIZE
, true, },
380 { "RW", SEC_FILE_READ_DATA
, true, },
381 { "RW", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_DATA
, true, },
382 { "RW", SEC_FILE_READ_DATA
|SEC_FILE_APPEND_DATA
, true, },
383 { "RW", SEC_FILE_READ_DATA
|SEC_FILE_READ_EA
, true, },
384 { "RW", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_EA
, true, },
385 { "RW", SEC_FILE_READ_DATA
|SEC_FILE_EXECUTE
, true, },
386 { "RW", SEC_FILE_READ_DATA
|SEC_FILE_READ_ATTRIBUTE
, true, },
387 { "RW", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_ATTRIBUTE
, true, },
388 { "RW", SEC_FILE_READ_DATA
|SEC_STD_DELETE
, false, },
389 { "RW", SEC_FILE_READ_DATA
|SEC_STD_READ_CONTROL
, true, },
390 { "RW", SEC_FILE_READ_DATA
|SEC_STD_WRITE_DAC
, true, },
391 { "RW", SEC_FILE_READ_DATA
|SEC_STD_WRITE_OWNER
, true, },
392 { "RW", SEC_FILE_READ_DATA
|SEC_STD_SYNCHRONIZE
, true, },
394 { "RD", SEC_FILE_READ_DATA
, true, },
395 { "RD", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_DATA
, false, },
396 { "RD", SEC_FILE_READ_DATA
|SEC_FILE_APPEND_DATA
, false, },
397 { "RD", SEC_FILE_READ_DATA
|SEC_FILE_READ_EA
, true },
398 { "RD", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_EA
, true, },
399 { "RD", SEC_FILE_READ_DATA
|SEC_FILE_EXECUTE
, true, },
400 { "RD", SEC_FILE_READ_DATA
|SEC_FILE_READ_ATTRIBUTE
, true, },
401 { "RD", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_ATTRIBUTE
, true, },
402 { "RD", SEC_FILE_READ_DATA
|SEC_STD_DELETE
, true, },
403 { "RD", SEC_FILE_READ_DATA
|SEC_STD_READ_CONTROL
, true, },
404 { "RD", SEC_FILE_READ_DATA
|SEC_STD_WRITE_DAC
, true, },
405 { "RD", SEC_FILE_READ_DATA
|SEC_STD_WRITE_OWNER
, true, },
406 { "RD", SEC_FILE_READ_DATA
|SEC_STD_SYNCHRONIZE
, true, },
408 { "WD", SEC_FILE_WRITE_DATA
|SEC_FILE_READ_DATA
, false },
409 { "WD", SEC_FILE_WRITE_DATA
, true, },
410 { "WD", SEC_FILE_WRITE_DATA
|SEC_FILE_APPEND_DATA
, true, },
411 { "WD", SEC_FILE_WRITE_DATA
|SEC_FILE_READ_EA
, true },
412 { "WD", SEC_FILE_WRITE_DATA
|SEC_FILE_WRITE_EA
, true, },
413 { "WD", SEC_FILE_WRITE_DATA
|SEC_FILE_EXECUTE
, false },
414 { "WD", SEC_FILE_WRITE_DATA
|SEC_FILE_READ_ATTRIBUTE
, true, },
415 { "WD", SEC_FILE_WRITE_DATA
|SEC_FILE_WRITE_ATTRIBUTE
, true, },
416 { "WD", SEC_FILE_WRITE_DATA
|SEC_STD_DELETE
, true, },
417 { "WD", SEC_FILE_WRITE_DATA
|SEC_STD_READ_CONTROL
, true, },
418 { "WD", SEC_FILE_WRITE_DATA
|SEC_STD_WRITE_DAC
, true, },
419 { "WD", SEC_FILE_WRITE_DATA
|SEC_STD_WRITE_OWNER
, true, },
420 { "WD", SEC_FILE_WRITE_DATA
|SEC_STD_SYNCHRONIZE
, true, },
422 { "RWD", SEC_FILE_READ_DATA
, true },
423 { "RWD", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_DATA
, true, },
424 { "RWD", SEC_FILE_READ_DATA
|SEC_FILE_APPEND_DATA
, true, },
425 { "RWD", SEC_FILE_READ_DATA
|SEC_FILE_READ_EA
, true, },
426 { "RWD", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_EA
, true, },
427 { "RWD", SEC_FILE_READ_DATA
|SEC_FILE_EXECUTE
, true, },
428 { "RWD", SEC_FILE_READ_DATA
|SEC_FILE_READ_ATTRIBUTE
, true, },
429 { "RWD", SEC_FILE_READ_DATA
|SEC_FILE_WRITE_ATTRIBUTE
, true, },
430 { "RWD", SEC_FILE_READ_DATA
|SEC_STD_DELETE
, true, },
431 { "RWD", SEC_FILE_READ_DATA
|SEC_STD_READ_CONTROL
, true, },
432 { "RWD", SEC_FILE_READ_DATA
|SEC_STD_WRITE_DAC
, true, },
433 { "RWD", SEC_FILE_READ_DATA
|SEC_STD_WRITE_OWNER
, true, },
434 { "RWD", SEC_FILE_READ_DATA
|SEC_STD_SYNCHRONIZE
, true, },
438 * Test conflicting sharemodes through SMB2: First open takes a
439 * sharemode, second open with potentially conflicting access.
441 static bool test_smb2_sharemode_access(struct torture_context
*tctx
,
442 struct smb2_tree
*tree
)
444 const char *fname
= "test_sharemode";
449 for (i
= 0; i
< ARRAY_SIZE(sharemode_table
); i
++) {
450 struct sharemode_info
*info
= &sharemode_table
[i
];
451 struct smb2_create create1
= { }, create2
= { };
452 NTSTATUS expected_status
;
454 torture_comment(tctx
, "index %3d, sharemode %3s, "
455 "access mask 0x%06x\n",
456 i
, info
->sharemode
, info
->access_mask
);
458 create1
.in
.desired_access
= SEC_RIGHTS_FILE_ALL
;
459 create1
.in
.alloc_size
= 0;
460 create1
.in
.file_attributes
= FILE_ATTRIBUTE_NORMAL
;
461 create1
.in
.share_access
=
462 smb2_util_share_access(info
->sharemode
);
463 create1
.in
.create_disposition
= NTCREATEX_DISP_OPEN_IF
;
464 create1
.in
.create_options
= 0;
465 create1
.in
.impersonation_level
= SMB2_IMPERSONATION_ANONYMOUS
;
466 create1
.in
.fname
= fname
;
467 create1
.in
.security_flags
= 0;
468 create1
.in
.create_flags
= NTCREATEX_FLAGS_EXTENDED
;
469 create1
.in
.oplock_level
= SMB2_OPLOCK_LEVEL_NONE
;
471 status
= smb2_create(tree
, tctx
, &create1
);
473 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
474 "CREATE file failed\n");
476 create2
.in
.desired_access
= info
->access_mask
;
477 create2
.in
.alloc_size
= 0;
478 create2
.in
.file_attributes
= FILE_ATTRIBUTE_NORMAL
;
479 create2
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
480 NTCREATEX_SHARE_ACCESS_WRITE
|
481 NTCREATEX_SHARE_ACCESS_DELETE
;
482 create2
.in
.create_disposition
= NTCREATEX_DISP_OPEN
;
483 create2
.in
.create_options
= 0;
484 create2
.in
.impersonation_level
= SMB2_IMPERSONATION_ANONYMOUS
;
485 create2
.in
.fname
= fname
;
486 create2
.in
.security_flags
= 0;
487 create2
.in
.create_flags
= NTCREATEX_FLAGS_EXTENDED
;
488 create2
.in
.oplock_level
= SMB2_OPLOCK_LEVEL_NONE
;
490 status
= smb2_create(tree
, tctx
, &create2
);
491 expected_status
= info
->expect_ok
?
492 NT_STATUS_OK
: NT_STATUS_SHARING_VIOLATION
;
493 torture_assert_ntstatus_equal_goto(tctx
, status
,
494 expected_status
, ret
,
495 done
, "Unexpected status on "
498 status
= smb2_util_close(tree
, create1
.out
.file
.handle
);
499 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
503 if (info
->expect_ok
) {
504 status
= smb2_util_close(tree
, create2
.out
.file
.handle
);
505 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
512 smb2_util_unlink(tree
, fname
);
517 * Test conflicting sharemodes through SMB2: First open file with
518 * different access masks, second open requests potentially conflict
521 static bool test_smb2_access_sharemode(struct torture_context
*tctx
,
522 struct smb2_tree
*tree
)
524 const char *fname
= "test_sharemode";
529 for (i
= 0; i
< ARRAY_SIZE(sharemode_table
); i
++) {
530 struct sharemode_info
*info
= &sharemode_table
[i
];
531 struct smb2_create create1
= { }, create2
= { };
532 NTSTATUS expected_status
;
534 torture_comment(tctx
, "index %3d, access mask 0x%06x, "
536 i
, info
->access_mask
, info
->sharemode
);
538 create1
.in
.desired_access
= info
->access_mask
;
539 create1
.in
.alloc_size
= 0;
540 create1
.in
.file_attributes
= FILE_ATTRIBUTE_NORMAL
;
541 create1
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
542 NTCREATEX_SHARE_ACCESS_WRITE
|
543 NTCREATEX_SHARE_ACCESS_DELETE
;
544 create1
.in
.create_disposition
= NTCREATEX_DISP_OPEN_IF
;
545 create1
.in
.create_options
= 0;
546 create1
.in
.impersonation_level
= SMB2_IMPERSONATION_ANONYMOUS
;
547 create1
.in
.fname
= fname
;
548 create1
.in
.security_flags
= 0;
549 create1
.in
.create_flags
= NTCREATEX_FLAGS_EXTENDED
;
550 create1
.in
.oplock_level
= SMB2_OPLOCK_LEVEL_NONE
;
552 status
= smb2_create(tree
, tctx
, &create1
);
554 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
555 "CREATE file failed\n");
557 create2
.in
.desired_access
= SEC_RIGHTS_FILE_ALL
;
558 create2
.in
.alloc_size
= 0;
559 create2
.in
.file_attributes
= FILE_ATTRIBUTE_NORMAL
;
560 create2
.in
.share_access
=
561 smb2_util_share_access(info
->sharemode
);
562 create2
.in
.create_disposition
= NTCREATEX_DISP_OPEN
;
563 create2
.in
.create_options
= 0;
564 create2
.in
.impersonation_level
= SMB2_IMPERSONATION_ANONYMOUS
;
565 create2
.in
.fname
= fname
;
566 create2
.in
.security_flags
= 0;
567 create2
.in
.create_flags
= NTCREATEX_FLAGS_EXTENDED
;
568 create2
.in
.oplock_level
= SMB2_OPLOCK_LEVEL_NONE
;
570 status
= smb2_create(tree
, tctx
, &create2
);
572 expected_status
= info
->expect_ok
?
573 NT_STATUS_OK
: NT_STATUS_SHARING_VIOLATION
;
574 torture_assert_ntstatus_equal_goto(tctx
, status
,
575 expected_status
, ret
,
576 done
, "Unexpected status on "
579 status
= smb2_util_close(tree
, create1
.out
.file
.handle
);
580 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
584 if (info
->expect_ok
) {
585 status
= smb2_util_close(tree
, create2
.out
.file
.handle
);
586 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
593 smb2_util_unlink(tree
, fname
);
597 struct torture_suite
*torture_smb2_sharemode_init(TALLOC_CTX
*ctx
)
599 struct torture_suite
*suite
= torture_suite_create(ctx
, "sharemode");
601 torture_suite_add_1smb2_test(suite
, "sharemode-access",
602 test_smb2_sharemode_access
);
603 torture_suite_add_1smb2_test(suite
, "access-sharemode",
604 test_smb2_access_sharemode
);
606 suite
->description
= talloc_strdup(suite
, "SMB2-SHAREMODE tests");