2 Unix SMB/CIFS implementation.
4 test suite for SMB2 session setups
6 Copyright (C) Michael Adam 2012
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 "torture/torture.h"
26 #include "torture/smb2/proto.h"
27 #include "../libcli/smb/smbXcli_base.h"
28 #include "lib/cmdline/popt_common.h"
29 #include "auth/credentials/credentials.h"
30 #include "libcli/security/security.h"
31 #include "libcli/resolve/resolve.h"
32 #include "lib/param/param.h"
34 #define CHECK_VAL(v, correct) do { \
35 if ((v) != (correct)) { \
36 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
37 __location__, #v, (int)v, (int)correct); \
41 #define CHECK_STATUS(status, correct) do { \
42 if (!NT_STATUS_EQUAL(status, correct)) { \
43 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
44 nt_errstr(status), nt_errstr(correct)); \
49 #define CHECK_CREATED(__io, __created, __attribute) \
51 CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \
52 CHECK_VAL((__io)->out.alloc_size, 0); \
53 CHECK_VAL((__io)->out.size, 0); \
54 CHECK_VAL((__io)->out.file_attr, (__attribute)); \
55 CHECK_VAL((__io)->out.reserved2, 0); \
60 * basic test for doing a session reconnect
62 bool test_session_reconnect1(struct torture_context
*tctx
, struct smb2_tree
*tree
)
65 TALLOC_CTX
*mem_ctx
= talloc_new(tctx
);
67 struct smb2_handle _h1
;
68 struct smb2_handle
*h1
= NULL
;
69 struct smb2_handle _h2
;
70 struct smb2_handle
*h2
= NULL
;
71 struct smb2_create io1
, io2
;
72 uint64_t previous_session_id
;
74 struct smb2_tree
*tree2
;
75 union smb_fileinfo qfinfo
;
77 /* Add some random component to the file name. */
78 snprintf(fname
, 256, "session_reconnect_%s.dat",
79 generate_random_str(tctx
, 8));
81 smb2_util_unlink(tree
, fname
);
83 smb2_oplock_create_share(&io1
, fname
,
84 smb2_util_share_access(""),
85 smb2_util_oplock_level("b"));
87 status
= smb2_create(tree
, mem_ctx
, &io1
);
88 CHECK_STATUS(status
, NT_STATUS_OK
);
89 _h1
= io1
.out
.file
.handle
;
91 CHECK_CREATED(&io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
92 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
94 /* disconnect, reconnect and then do durable reopen */
95 previous_session_id
= smb2cli_session_current_id(tree
->session
->smbXcli
);
97 if (!torture_smb2_connection_ext(tctx
, previous_session_id
, &tree2
)) {
98 torture_warning(tctx
, "session reconnect failed\n");
103 /* try to access the file via the old handle */
106 qfinfo
.generic
.level
= RAW_FILEINFO_POSITION_INFORMATION
;
107 qfinfo
.generic
.in
.file
.handle
= _h1
;
108 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
109 CHECK_STATUS(status
, NT_STATUS_USER_SESSION_DELETED
);
112 smb2_oplock_create_share(&io2
, fname
,
113 smb2_util_share_access(""),
114 smb2_util_oplock_level("b"));
116 status
= smb2_create(tree2
, mem_ctx
, &io2
);
117 CHECK_STATUS(status
, NT_STATUS_OK
);
118 CHECK_CREATED(&io2
, EXISTED
, FILE_ATTRIBUTE_ARCHIVE
);
119 CHECK_VAL(io2
.out
.oplock_level
, smb2_util_oplock_level("b"));
120 _h2
= io2
.out
.file
.handle
;
125 smb2_util_close(tree
, *h1
);
128 smb2_util_close(tree2
, *h2
);
131 smb2_util_unlink(tree2
, fname
);
136 talloc_free(mem_ctx
);
142 * basic test for doing a session reconnect on one connection
144 bool test_session_reconnect2(struct torture_context
*tctx
, struct smb2_tree
*tree
)
147 TALLOC_CTX
*mem_ctx
= talloc_new(tctx
);
149 struct smb2_handle _h1
;
150 struct smb2_handle
*h1
= NULL
;
151 struct smb2_create io1
;
152 uint64_t previous_session_id
;
154 struct smb2_session
*session2
;
155 union smb_fileinfo qfinfo
;
157 /* Add some random component to the file name. */
158 snprintf(fname
, 256, "session_reconnect_%s.dat",
159 generate_random_str(tctx
, 8));
161 smb2_util_unlink(tree
, fname
);
163 smb2_oplock_create_share(&io1
, fname
,
164 smb2_util_share_access(""),
165 smb2_util_oplock_level("b"));
166 io1
.in
.create_options
|= NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
168 status
= smb2_create(tree
, mem_ctx
, &io1
);
169 CHECK_STATUS(status
, NT_STATUS_OK
);
170 _h1
= io1
.out
.file
.handle
;
172 CHECK_CREATED(&io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
173 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
175 /* disconnect, reconnect and then do durable reopen */
176 previous_session_id
= smb2cli_session_current_id(tree
->session
->smbXcli
);
178 torture_assert(tctx
, torture_smb2_session_setup(tctx
, tree
->session
->transport
,
179 previous_session_id
, tctx
, &session2
),
180 "session reconnect (on the same connection) failed");
182 /* try to access the file via the old handle */
185 qfinfo
.generic
.level
= RAW_FILEINFO_POSITION_INFORMATION
;
186 qfinfo
.generic
.in
.file
.handle
= _h1
;
187 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
188 CHECK_STATUS(status
, NT_STATUS_USER_SESSION_DELETED
);
193 smb2_util_close(tree
, *h1
);
197 talloc_free(session2
);
199 talloc_free(mem_ctx
);
204 bool test_session_reauth1(struct torture_context
*tctx
, struct smb2_tree
*tree
)
207 TALLOC_CTX
*mem_ctx
= talloc_new(tctx
);
209 struct smb2_handle _h1
;
210 struct smb2_handle
*h1
= NULL
;
211 struct smb2_create io1
;
213 union smb_fileinfo qfinfo
;
215 /* Add some random component to the file name. */
216 snprintf(fname
, 256, "session_reauth1_%s.dat",
217 generate_random_str(tctx
, 8));
219 smb2_util_unlink(tree
, fname
);
221 smb2_oplock_create_share(&io1
, fname
,
222 smb2_util_share_access(""),
223 smb2_util_oplock_level("b"));
225 status
= smb2_create(tree
, mem_ctx
, &io1
);
226 CHECK_STATUS(status
, NT_STATUS_OK
);
227 _h1
= io1
.out
.file
.handle
;
229 CHECK_CREATED(&io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
230 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
232 status
= smb2_session_setup_spnego(tree
->session
,
234 0 /* previous_session_id */);
235 CHECK_STATUS(status
, NT_STATUS_OK
);
237 /* try to access the file via the old handle */
240 qfinfo
.generic
.level
= RAW_FILEINFO_POSITION_INFORMATION
;
241 qfinfo
.generic
.in
.file
.handle
= _h1
;
242 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
243 CHECK_STATUS(status
, NT_STATUS_OK
);
245 status
= smb2_session_setup_spnego(tree
->session
,
247 0 /* previous_session_id */);
248 CHECK_STATUS(status
, NT_STATUS_OK
);
250 /* try to access the file via the old handle */
253 qfinfo
.generic
.level
= RAW_FILEINFO_POSITION_INFORMATION
;
254 qfinfo
.generic
.in
.file
.handle
= _h1
;
255 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
256 CHECK_STATUS(status
, NT_STATUS_OK
);
260 smb2_util_close(tree
, *h1
);
263 smb2_util_unlink(tree
, fname
);
267 talloc_free(mem_ctx
);
272 bool test_session_reauth2(struct torture_context
*tctx
, struct smb2_tree
*tree
)
275 TALLOC_CTX
*mem_ctx
= talloc_new(tctx
);
277 struct smb2_handle _h1
;
278 struct smb2_handle
*h1
= NULL
;
279 struct smb2_create io1
;
281 union smb_fileinfo qfinfo
;
282 struct cli_credentials
*anon_creds
= NULL
;
284 /* Add some random component to the file name. */
285 snprintf(fname
, 256, "session_reauth2_%s.dat",
286 generate_random_str(tctx
, 8));
288 smb2_util_unlink(tree
, fname
);
290 smb2_oplock_create_share(&io1
, fname
,
291 smb2_util_share_access(""),
292 smb2_util_oplock_level("b"));
294 status
= smb2_create(tree
, mem_ctx
, &io1
);
295 CHECK_STATUS(status
, NT_STATUS_OK
);
296 _h1
= io1
.out
.file
.handle
;
298 CHECK_CREATED(&io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
299 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
301 /* re-authenticate as anonymous */
303 anon_creds
= cli_credentials_init_anon(mem_ctx
);
304 torture_assert(tctx
, (anon_creds
!= NULL
), "talloc error");
306 status
= smb2_session_setup_spnego(tree
->session
,
308 0 /* previous_session_id */);
309 CHECK_STATUS(status
, NT_STATUS_OK
);
311 /* try to access the file via the old handle */
314 qfinfo
.generic
.level
= RAW_FILEINFO_POSITION_INFORMATION
;
315 qfinfo
.generic
.in
.file
.handle
= _h1
;
316 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
317 CHECK_STATUS(status
, NT_STATUS_OK
);
319 /* re-authenticate as original user again */
321 status
= smb2_session_setup_spnego(tree
->session
,
323 0 /* previous_session_id */);
324 CHECK_STATUS(status
, NT_STATUS_OK
);
326 /* try to access the file via the old handle */
329 qfinfo
.generic
.level
= RAW_FILEINFO_POSITION_INFORMATION
;
330 qfinfo
.generic
.in
.file
.handle
= _h1
;
331 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
332 CHECK_STATUS(status
, NT_STATUS_OK
);
336 smb2_util_close(tree
, *h1
);
339 smb2_util_unlink(tree
, fname
);
343 talloc_free(mem_ctx
);
349 * test getting security descriptor after reauth
351 bool test_session_reauth3(struct torture_context
*tctx
, struct smb2_tree
*tree
)
354 TALLOC_CTX
*mem_ctx
= talloc_new(tctx
);
356 struct smb2_handle _h1
;
357 struct smb2_handle
*h1
= NULL
;
358 struct smb2_create io1
;
360 union smb_fileinfo qfinfo
;
361 struct cli_credentials
*anon_creds
= NULL
;
362 uint32_t secinfo_flags
= SECINFO_OWNER
365 | SECINFO_PROTECTED_DACL
366 | SECINFO_UNPROTECTED_DACL
;
368 /* Add some random component to the file name. */
369 snprintf(fname
, 256, "session_reauth3_%s.dat",
370 generate_random_str(tctx
, 8));
372 smb2_util_unlink(tree
, fname
);
374 smb2_oplock_create_share(&io1
, fname
,
375 smb2_util_share_access(""),
376 smb2_util_oplock_level("b"));
378 status
= smb2_create(tree
, mem_ctx
, &io1
);
379 CHECK_STATUS(status
, NT_STATUS_OK
);
380 _h1
= io1
.out
.file
.handle
;
382 CHECK_CREATED(&io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
383 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
385 /* get the security descriptor */
389 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
390 qfinfo
.query_secdesc
.in
.file
.handle
= _h1
;
391 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
393 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
394 CHECK_STATUS(status
, NT_STATUS_OK
);
395 /* re-authenticate as anonymous */
397 anon_creds
= cli_credentials_init_anon(mem_ctx
);
398 torture_assert(tctx
, (anon_creds
!= NULL
), "talloc error");
400 status
= smb2_session_setup_spnego(tree
->session
,
402 0 /* previous_session_id */);
403 CHECK_STATUS(status
, NT_STATUS_OK
);
405 /* try to access the file via the old handle */
409 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
410 qfinfo
.query_secdesc
.in
.file
.handle
= _h1
;
411 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
413 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
414 CHECK_STATUS(status
, NT_STATUS_OK
);
416 /* re-authenticate as original user again */
418 status
= smb2_session_setup_spnego(tree
->session
,
420 0 /* previous_session_id */);
421 CHECK_STATUS(status
, NT_STATUS_OK
);
423 /* try to access the file via the old handle */
427 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
428 qfinfo
.query_secdesc
.in
.file
.handle
= _h1
;
429 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
431 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
432 CHECK_STATUS(status
, NT_STATUS_OK
);
436 smb2_util_close(tree
, *h1
);
439 smb2_util_unlink(tree
, fname
);
443 talloc_free(mem_ctx
);
449 * test setting security descriptor after reauth.
451 bool test_session_reauth4(struct torture_context
*tctx
, struct smb2_tree
*tree
)
454 TALLOC_CTX
*mem_ctx
= talloc_new(tctx
);
456 struct smb2_handle _h1
;
457 struct smb2_handle
*h1
= NULL
;
458 struct smb2_create io1
;
460 union smb_fileinfo qfinfo
;
461 union smb_setfileinfo sfinfo
;
462 struct cli_credentials
*anon_creds
= NULL
;
463 uint32_t secinfo_flags
= SECINFO_OWNER
466 | SECINFO_PROTECTED_DACL
467 | SECINFO_UNPROTECTED_DACL
;
468 struct security_descriptor
*sd1
;
469 struct security_ace ace
;
470 struct dom_sid
*extra_sid
;
472 /* Add some random component to the file name. */
473 snprintf(fname
, 256, "session_reauth4_%s.dat",
474 generate_random_str(tctx
, 8));
476 smb2_util_unlink(tree
, fname
);
478 smb2_oplock_create_share(&io1
, fname
,
479 smb2_util_share_access(""),
480 smb2_util_oplock_level("b"));
482 status
= smb2_create(tree
, mem_ctx
, &io1
);
483 CHECK_STATUS(status
, NT_STATUS_OK
);
484 _h1
= io1
.out
.file
.handle
;
486 CHECK_CREATED(&io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
487 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
489 /* get the security descriptor */
493 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
494 qfinfo
.query_secdesc
.in
.file
.handle
= _h1
;
495 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
497 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
498 CHECK_STATUS(status
, NT_STATUS_OK
);
500 sd1
= qfinfo
.query_secdesc
.out
.sd
;
502 /* re-authenticate as anonymous */
504 anon_creds
= cli_credentials_init_anon(mem_ctx
);
505 torture_assert(tctx
, (anon_creds
!= NULL
), "talloc error");
507 status
= smb2_session_setup_spnego(tree
->session
,
509 0 /* previous_session_id */);
510 CHECK_STATUS(status
, NT_STATUS_OK
);
512 /* give full access on the file to anonymous */
514 extra_sid
= dom_sid_parse_talloc(tctx
, SID_NT_ANONYMOUS
);
517 ace
.type
= SEC_ACE_TYPE_ACCESS_ALLOWED
;
519 ace
.access_mask
= SEC_STD_ALL
| SEC_FILE_ALL
;
520 ace
.trustee
= *extra_sid
;
522 status
= security_descriptor_dacl_add(sd1
, &ace
);
523 CHECK_STATUS(status
, NT_STATUS_OK
);
526 sfinfo
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
527 sfinfo
.set_secdesc
.in
.file
.handle
= _h1
;
528 sfinfo
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
529 sfinfo
.set_secdesc
.in
.sd
= sd1
;
531 status
= smb2_setinfo_file(tree
, &sfinfo
);
532 CHECK_STATUS(status
, NT_STATUS_OK
);
534 /* re-authenticate as original user again */
536 status
= smb2_session_setup_spnego(tree
->session
,
538 0 /* previous_session_id */);
539 CHECK_STATUS(status
, NT_STATUS_OK
);
541 /* re-get the security descriptor */
545 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
546 qfinfo
.query_secdesc
.in
.file
.handle
= _h1
;
547 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
549 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
550 CHECK_STATUS(status
, NT_STATUS_OK
);
556 smb2_util_close(tree
, *h1
);
559 smb2_util_unlink(tree
, fname
);
563 talloc_free(mem_ctx
);
569 * test renaming after reauth.
570 * compare security descriptors before and after rename/reauth
572 bool test_session_reauth5(struct torture_context
*tctx
, struct smb2_tree
*tree
)
575 TALLOC_CTX
*mem_ctx
= talloc_new(tctx
);
579 struct smb2_handle _dh1
;
580 struct smb2_handle
*dh1
= NULL
;
581 struct smb2_handle _h1
;
582 struct smb2_handle
*h1
= NULL
;
583 struct smb2_create io1
;
586 union smb_fileinfo qfinfo
;
587 union smb_setfileinfo sfinfo
;
588 struct cli_credentials
*anon_creds
= NULL
;
589 uint32_t secinfo_flags
= SECINFO_OWNER
592 | SECINFO_PROTECTED_DACL
593 | SECINFO_UNPROTECTED_DACL
;
594 struct security_descriptor
*f_sd1
, *f_sd2
;
595 struct security_descriptor
*d_sd1
= NULL
;
596 struct security_ace ace
;
597 struct dom_sid
*extra_sid
;
599 /* Add some random component to the file name. */
600 snprintf(dname
, 256, "session_reauth5_%s.d",
601 generate_random_str(tctx
, 8));
602 snprintf(fname
, 256, "%s\\file.dat", dname
);
604 ok
= smb2_util_setup_dir(tctx
, tree
, dname
);
607 status
= torture_smb2_testdir(tree
, dname
, &_dh1
);
608 CHECK_STATUS(status
, NT_STATUS_OK
);
611 smb2_oplock_create_share(&io1
, fname
,
612 smb2_util_share_access(""),
613 smb2_util_oplock_level("b"));
615 status
= smb2_create(tree
, mem_ctx
, &io1
);
616 CHECK_STATUS(status
, NT_STATUS_OK
);
617 _h1
= io1
.out
.file
.handle
;
619 CHECK_CREATED(&io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
620 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
622 /* get the security descriptor */
626 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
627 qfinfo
.query_secdesc
.in
.file
.handle
= _h1
;
628 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
630 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
631 CHECK_STATUS(status
, NT_STATUS_OK
);
633 f_sd1
= qfinfo
.query_secdesc
.out
.sd
;
635 /* re-authenticate as anonymous */
637 anon_creds
= cli_credentials_init_anon(mem_ctx
);
638 torture_assert(tctx
, (anon_creds
!= NULL
), "talloc error");
640 status
= smb2_session_setup_spnego(tree
->session
,
642 0 /* previous_session_id */);
643 CHECK_STATUS(status
, NT_STATUS_OK
);
645 /* try to rename the file: fails */
647 snprintf(fname2
, 256, "%s\\file2.dat", dname
);
649 smb2_util_unlink(tree
, fname2
);
652 sfinfo
.rename_information
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
653 sfinfo
.rename_information
.in
.file
.handle
= _h1
;
654 sfinfo
.rename_information
.in
.overwrite
= true;
655 sfinfo
.rename_information
.in
.new_name
= fname2
;
657 status
= smb2_setinfo_file(tree
, &sfinfo
);
658 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
660 /* re-authenticate as original user again */
662 status
= smb2_session_setup_spnego(tree
->session
,
664 0 /* previous_session_id */);
665 CHECK_STATUS(status
, NT_STATUS_OK
);
667 /* give full access on the file to anonymous */
669 extra_sid
= dom_sid_parse_talloc(tctx
, SID_NT_ANONYMOUS
);
672 ace
.type
= SEC_ACE_TYPE_ACCESS_ALLOWED
;
674 ace
.access_mask
= SEC_RIGHTS_FILE_ALL
;
675 ace
.trustee
= *extra_sid
;
677 status
= security_descriptor_dacl_add(f_sd1
, &ace
);
678 CHECK_STATUS(status
, NT_STATUS_OK
);
681 sfinfo
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
682 sfinfo
.set_secdesc
.in
.file
.handle
= _h1
;
683 sfinfo
.set_secdesc
.in
.secinfo_flags
= secinfo_flags
;
684 sfinfo
.set_secdesc
.in
.sd
= f_sd1
;
686 status
= smb2_setinfo_file(tree
, &sfinfo
);
687 CHECK_STATUS(status
, NT_STATUS_OK
);
689 /* re-get the security descriptor */
693 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
694 qfinfo
.query_secdesc
.in
.file
.handle
= _h1
;
695 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
697 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
698 CHECK_STATUS(status
, NT_STATUS_OK
);
700 /* re-authenticate as anonymous - again */
702 anon_creds
= cli_credentials_init_anon(mem_ctx
);
703 torture_assert(tctx
, (anon_creds
!= NULL
), "talloc error");
705 status
= smb2_session_setup_spnego(tree
->session
,
707 0 /* previous_session_id */);
708 CHECK_STATUS(status
, NT_STATUS_OK
);
710 /* try to rename the file: fails */
713 sfinfo
.rename_information
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
714 sfinfo
.rename_information
.in
.file
.handle
= _h1
;
715 sfinfo
.rename_information
.in
.overwrite
= true;
716 sfinfo
.rename_information
.in
.new_name
= fname2
;
718 status
= smb2_setinfo_file(tree
, &sfinfo
);
719 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
721 /* give full access on the parent dir to anonymous */
725 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
726 qfinfo
.query_secdesc
.in
.file
.handle
= _dh1
;
727 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
729 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
730 CHECK_STATUS(status
, NT_STATUS_OK
);
732 d_sd1
= qfinfo
.query_secdesc
.out
.sd
;
735 ace
.type
= SEC_ACE_TYPE_ACCESS_ALLOWED
;
737 ace
.access_mask
= SEC_RIGHTS_FILE_ALL
;
738 ace
.trustee
= *extra_sid
;
740 status
= security_descriptor_dacl_add(d_sd1
, &ace
);
741 CHECK_STATUS(status
, NT_STATUS_OK
);
744 sfinfo
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
745 sfinfo
.set_secdesc
.in
.file
.handle
= _dh1
;
746 sfinfo
.set_secdesc
.in
.secinfo_flags
= secinfo_flags
;
747 sfinfo
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
748 sfinfo
.set_secdesc
.in
.sd
= d_sd1
;
750 status
= smb2_setinfo_file(tree
, &sfinfo
);
751 CHECK_STATUS(status
, NT_STATUS_OK
);
755 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
756 qfinfo
.query_secdesc
.in
.file
.handle
= _dh1
;
757 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
759 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
760 CHECK_STATUS(status
, NT_STATUS_OK
);
762 smb2_util_close(tree
, _dh1
);
765 /* try to rename the file: still fails */
768 sfinfo
.rename_information
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
769 sfinfo
.rename_information
.in
.file
.handle
= _h1
;
770 sfinfo
.rename_information
.in
.overwrite
= true;
771 sfinfo
.rename_information
.in
.new_name
= fname2
;
773 status
= smb2_setinfo_file(tree
, &sfinfo
);
774 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
776 /* re-authenticate as original user - again */
778 status
= smb2_session_setup_spnego(tree
->session
,
780 0 /* previous_session_id */);
781 CHECK_STATUS(status
, NT_STATUS_OK
);
783 /* rename the file - for verification that it works */
786 sfinfo
.rename_information
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
787 sfinfo
.rename_information
.in
.file
.handle
= _h1
;
788 sfinfo
.rename_information
.in
.overwrite
= true;
789 sfinfo
.rename_information
.in
.new_name
= fname2
;
791 status
= smb2_setinfo_file(tree
, &sfinfo
);
792 CHECK_STATUS(status
, NT_STATUS_OK
);
794 /* closs the file, check it is gone and reopen under the new name */
796 smb2_util_close(tree
, _h1
);
800 smb2_generic_create_share(&io1
,
801 NULL
/* lease */, false /* dir */,
804 smb2_util_share_access(""),
805 smb2_util_oplock_level("b"),
806 0 /* leasekey */, 0 /* leasestate */);
808 status
= smb2_create(tree
, mem_ctx
, &io1
);
809 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
813 smb2_generic_create_share(&io1
,
814 NULL
/* lease */, false /* dir */,
817 smb2_util_share_access(""),
818 smb2_util_oplock_level("b"),
819 0 /* leasekey */, 0 /* leasestate */);
821 status
= smb2_create(tree
, mem_ctx
, &io1
);
822 CHECK_STATUS(status
, NT_STATUS_OK
);
823 _h1
= io1
.out
.file
.handle
;
825 CHECK_CREATED(&io1
, EXISTED
, FILE_ATTRIBUTE_ARCHIVE
);
826 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
828 /* try to access the file via the old handle */
832 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
833 qfinfo
.query_secdesc
.in
.file
.handle
= _h1
;
834 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
836 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
837 CHECK_STATUS(status
, NT_STATUS_OK
);
839 f_sd2
= qfinfo
.query_secdesc
.out
.sd
;
843 smb2_util_close(tree
, *dh1
);
846 smb2_util_close(tree
, *h1
);
849 smb2_deltree(tree
, dname
);
853 talloc_free(mem_ctx
);
858 static bool test_session_expire1(struct torture_context
*tctx
)
862 struct smbcli_options options
;
863 const char *host
= torture_setting_string(tctx
, "host", NULL
);
864 const char *share
= torture_setting_string(tctx
, "share", NULL
);
865 struct cli_credentials
*credentials
= cmdline_credentials
;
866 struct smb2_tree
*tree
;
867 enum credentials_use_kerberos use_kerberos
;
869 struct smb2_handle _h1
;
870 struct smb2_handle
*h1
= NULL
;
871 struct smb2_create io1
;
872 union smb_fileinfo qfinfo
;
875 use_kerberos
= cli_credentials_get_kerberos_state(credentials
);
876 if (use_kerberos
!= CRED_MUST_USE_KERBEROS
) {
877 torture_warning(tctx
, "smb2.session.expire1 requires -k yes!");
878 torture_skip(tctx
, "smb2.session.expire1 requires -k yes!");
881 torture_assert_int_equal(tctx
, use_kerberos
, CRED_MUST_USE_KERBEROS
,
882 "please use -k yes");
884 lpcfg_set_option(tctx
->lp_ctx
, "gensec_gssapi:requested_life_time=4");
886 lpcfg_smbcli_options(tctx
->lp_ctx
, &options
);
888 status
= smb2_connect(tctx
,
890 lpcfg_smb_ports(tctx
->lp_ctx
),
892 lpcfg_resolve_context(tctx
->lp_ctx
),
897 lpcfg_socket_options(tctx
->lp_ctx
),
898 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
)
900 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
901 "smb2_connect failed");
903 /* Add some random component to the file name. */
904 snprintf(fname
, 256, "session_expire1_%s.dat",
905 generate_random_str(tctx
, 8));
907 smb2_util_unlink(tree
, fname
);
909 smb2_oplock_create_share(&io1
, fname
,
910 smb2_util_share_access(""),
911 smb2_util_oplock_level("b"));
912 io1
.in
.create_options
|= NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
914 status
= smb2_create(tree
, tctx
, &io1
);
915 CHECK_STATUS(status
, NT_STATUS_OK
);
916 _h1
= io1
.out
.file
.handle
;
918 CHECK_CREATED(&io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
919 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
921 /* get the security descriptor */
925 qfinfo
.access_information
.level
= RAW_FILEINFO_ACCESS_INFORMATION
;
926 qfinfo
.access_information
.in
.file
.handle
= _h1
;
928 for (i
=0; i
< 2; i
++) {
929 torture_comment(tctx
, "query info => OK\n");
931 ZERO_STRUCT(qfinfo
.access_information
.out
);
932 status
= smb2_getinfo_file(tree
, tctx
, &qfinfo
);
933 CHECK_STATUS(status
, NT_STATUS_OK
);
935 torture_comment(tctx
, "sleep 5 seconds\n");
938 torture_comment(tctx
, "query info => EXPIRED\n");
939 ZERO_STRUCT(qfinfo
.access_information
.out
);
940 status
= smb2_getinfo_file(tree
, tctx
, &qfinfo
);
941 CHECK_STATUS(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
);
944 * the krb5 library may not handle expired creds
945 * well, lets start with an empty ccache.
947 cli_credentials_invalidate_ccache(credentials
, CRED_SPECIFIED
);
949 torture_comment(tctx
, "reauth => OK\n");
950 status
= smb2_session_setup_spnego(tree
->session
,
952 0 /* previous_session_id */);
953 CHECK_STATUS(status
, NT_STATUS_OK
);
956 ZERO_STRUCT(qfinfo
.access_information
.out
);
957 status
= smb2_getinfo_file(tree
, tctx
, &qfinfo
);
958 CHECK_STATUS(status
, NT_STATUS_OK
);
963 smb2_util_close(tree
, *h1
);
967 lpcfg_set_option(tctx
->lp_ctx
, "gensec_gssapi:requested_life_time=0");
971 struct torture_suite
*torture_smb2_session_init(void)
973 struct torture_suite
*suite
=
974 torture_suite_create(talloc_autofree_context(), "session");
976 torture_suite_add_1smb2_test(suite
, "reconnect1", test_session_reconnect1
);
977 torture_suite_add_1smb2_test(suite
, "reconnect2", test_session_reconnect2
);
978 torture_suite_add_1smb2_test(suite
, "reauth1", test_session_reauth1
);
979 torture_suite_add_1smb2_test(suite
, "reauth2", test_session_reauth2
);
980 torture_suite_add_1smb2_test(suite
, "reauth3", test_session_reauth3
);
981 torture_suite_add_1smb2_test(suite
, "reauth4", test_session_reauth4
);
982 torture_suite_add_1smb2_test(suite
, "reauth5", test_session_reauth5
);
983 torture_suite_add_simple_test(suite
, "expire1", test_session_expire1
);
985 suite
->description
= talloc_strdup(suite
, "SMB2-SESSION tests");