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
);
578 struct smb2_handle _h1
;
579 struct smb2_handle
*h1
= NULL
;
580 struct smb2_create io1
;
582 union smb_fileinfo qfinfo
;
583 union smb_setfileinfo sfinfo
;
584 struct cli_credentials
*anon_creds
= NULL
;
585 uint32_t secinfo_flags
= SECINFO_OWNER
588 | SECINFO_PROTECTED_DACL
589 | SECINFO_UNPROTECTED_DACL
;
590 struct security_descriptor
*sd1
, *sd2
;
591 struct security_ace ace
;
592 struct dom_sid
*extra_sid
;
594 /* Add some random component to the file name. */
595 snprintf(fname
, 256, "session_reauth5_%s.dat",
596 generate_random_str(tctx
, 8));
598 smb2_util_unlink(tree
, fname
);
600 smb2_oplock_create_share(&io1
, fname
,
601 smb2_util_share_access(""),
602 smb2_util_oplock_level("b"));
604 status
= smb2_create(tree
, mem_ctx
, &io1
);
605 CHECK_STATUS(status
, NT_STATUS_OK
);
606 _h1
= io1
.out
.file
.handle
;
608 CHECK_CREATED(&io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
609 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
611 /* get the security descriptor */
615 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
616 qfinfo
.query_secdesc
.in
.file
.handle
= _h1
;
617 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
619 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
620 CHECK_STATUS(status
, NT_STATUS_OK
);
622 sd1
= qfinfo
.query_secdesc
.out
.sd
;
624 /* re-authenticate as anonymous */
626 anon_creds
= cli_credentials_init_anon(mem_ctx
);
627 torture_assert(tctx
, (anon_creds
!= NULL
), "talloc error");
629 status
= smb2_session_setup_spnego(tree
->session
,
631 0 /* previous_session_id */);
632 CHECK_STATUS(status
, NT_STATUS_OK
);
634 /* try to rename the file: fails */
636 snprintf(fname2
, 256, "session_reauth5.2_%s.dat",
637 generate_random_str(tctx
, 8));
639 smb2_util_unlink(tree
, fname2
);
642 sfinfo
.rename_information
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
643 sfinfo
.rename_information
.in
.file
.handle
= _h1
;
644 sfinfo
.rename_information
.in
.overwrite
= true;
645 sfinfo
.rename_information
.in
.new_name
= fname2
;
647 status
= smb2_setinfo_file(tree
, &sfinfo
);
648 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
650 /* re-authenticate as original user again */
652 status
= smb2_session_setup_spnego(tree
->session
,
654 0 /* previous_session_id */);
655 CHECK_STATUS(status
, NT_STATUS_OK
);
657 /* give full access on the file to anonymous */
659 extra_sid
= dom_sid_parse_talloc(tctx
, SID_NT_ANONYMOUS
);
662 ace
.type
= SEC_ACE_TYPE_ACCESS_ALLOWED
;
664 ace
.access_mask
= SEC_STD_ALL
| SEC_FILE_ALL
;
665 ace
.trustee
= *extra_sid
;
667 status
= security_descriptor_dacl_add(sd1
, &ace
);
668 CHECK_STATUS(status
, NT_STATUS_OK
);
671 sfinfo
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
672 sfinfo
.set_secdesc
.in
.file
.handle
= _h1
;
673 sfinfo
.set_secdesc
.in
.secinfo_flags
= secinfo_flags
;
674 sfinfo
.set_secdesc
.in
.sd
= sd1
;
676 status
= smb2_setinfo_file(tree
, &sfinfo
);
677 CHECK_STATUS(status
, NT_STATUS_OK
);
679 /* re-get the security descriptor */
683 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
684 qfinfo
.query_secdesc
.in
.file
.handle
= _h1
;
685 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
687 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
688 CHECK_STATUS(status
, NT_STATUS_OK
);
690 /* re-authenticate as anonymous - again */
692 anon_creds
= cli_credentials_init_anon(mem_ctx
);
693 torture_assert(tctx
, (anon_creds
!= NULL
), "talloc error");
695 status
= smb2_session_setup_spnego(tree
->session
,
697 0 /* previous_session_id */);
698 CHECK_STATUS(status
, NT_STATUS_OK
);
700 /* try to rename the file: fails */
702 snprintf(fname2
, 256, "session_reauth3.2_%s.dat",
703 generate_random_str(tctx
, 8));
705 smb2_util_unlink(tree
, fname2
);
708 sfinfo
.rename_information
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
709 sfinfo
.rename_information
.in
.file
.handle
= _h1
;
710 sfinfo
.rename_information
.in
.overwrite
= true;
711 sfinfo
.rename_information
.in
.new_name
= fname2
;
713 status
= smb2_setinfo_file(tree
, &sfinfo
);
714 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
716 /* re-authenticate as original user - again */
718 status
= smb2_session_setup_spnego(tree
->session
,
720 0 /* previous_session_id */);
721 CHECK_STATUS(status
, NT_STATUS_OK
);
723 /* rename the file - for verification that it works */
726 sfinfo
.rename_information
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
727 sfinfo
.rename_information
.in
.file
.handle
= _h1
;
728 sfinfo
.rename_information
.in
.overwrite
= true;
729 sfinfo
.rename_information
.in
.new_name
= fname2
;
731 status
= smb2_setinfo_file(tree
, &sfinfo
);
732 CHECK_STATUS(status
, NT_STATUS_OK
);
734 /* closs the file, check it is gone and reopen under the new name */
736 smb2_util_close(tree
, _h1
);
740 smb2_generic_create_share(&io1
,
741 NULL
/* lease */, false /* dir */,
744 smb2_util_share_access(""),
745 smb2_util_oplock_level("b"),
746 0 /* leasekey */, 0 /* leasestate */);
748 status
= smb2_create(tree
, mem_ctx
, &io1
);
749 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
753 smb2_generic_create_share(&io1
,
754 NULL
/* lease */, false /* dir */,
757 smb2_util_share_access(""),
758 smb2_util_oplock_level("b"),
759 0 /* leasekey */, 0 /* leasestate */);
761 status
= smb2_create(tree
, mem_ctx
, &io1
);
762 CHECK_STATUS(status
, NT_STATUS_OK
);
763 _h1
= io1
.out
.file
.handle
;
765 CHECK_CREATED(&io1
, EXISTED
, FILE_ATTRIBUTE_ARCHIVE
);
766 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
768 /* try to access the file via the old handle */
772 qfinfo
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
773 qfinfo
.query_secdesc
.in
.file
.handle
= _h1
;
774 qfinfo
.query_secdesc
.in
.secinfo_flags
= secinfo_flags
;
776 status
= smb2_getinfo_file(tree
, mem_ctx
, &qfinfo
);
777 CHECK_STATUS(status
, NT_STATUS_OK
);
779 sd2
= qfinfo
.query_secdesc
.out
.sd
;
783 smb2_util_close(tree
, *h1
);
786 smb2_util_unlink(tree
, fname
);
790 talloc_free(mem_ctx
);
795 static bool test_session_expire1(struct torture_context
*tctx
)
799 struct smbcli_options options
;
800 const char *host
= torture_setting_string(tctx
, "host", NULL
);
801 const char *share
= torture_setting_string(tctx
, "share", NULL
);
802 struct cli_credentials
*credentials
= cmdline_credentials
;
803 struct smb2_tree
*tree
;
804 enum credentials_use_kerberos use_kerberos
;
806 struct smb2_handle _h1
;
807 struct smb2_handle
*h1
= NULL
;
808 struct smb2_create io1
;
809 union smb_fileinfo qfinfo
;
812 use_kerberos
= cli_credentials_get_kerberos_state(credentials
);
813 if (use_kerberos
!= CRED_MUST_USE_KERBEROS
) {
814 torture_warning(tctx
, "smb2.session.expire1 requires -k yes!");
815 torture_skip(tctx
, "smb2.session.expire1 requires -k yes!");
818 torture_assert_int_equal(tctx
, use_kerberos
, CRED_MUST_USE_KERBEROS
,
819 "please use -k yes");
821 lpcfg_set_option(tctx
->lp_ctx
, "gensec_gssapi:requested_life_time=4");
823 lpcfg_smbcli_options(tctx
->lp_ctx
, &options
);
825 status
= smb2_connect(tctx
,
827 lpcfg_smb_ports(tctx
->lp_ctx
),
829 lpcfg_resolve_context(tctx
->lp_ctx
),
834 lpcfg_socket_options(tctx
->lp_ctx
),
835 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
)
837 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
838 "smb2_connect failed");
840 /* Add some random component to the file name. */
841 snprintf(fname
, 256, "session_expire1_%s.dat",
842 generate_random_str(tctx
, 8));
844 smb2_util_unlink(tree
, fname
);
846 smb2_oplock_create_share(&io1
, fname
,
847 smb2_util_share_access(""),
848 smb2_util_oplock_level("b"));
849 io1
.in
.create_options
|= NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
851 status
= smb2_create(tree
, tctx
, &io1
);
852 CHECK_STATUS(status
, NT_STATUS_OK
);
853 _h1
= io1
.out
.file
.handle
;
855 CHECK_CREATED(&io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
856 CHECK_VAL(io1
.out
.oplock_level
, smb2_util_oplock_level("b"));
858 /* get the security descriptor */
862 qfinfo
.access_information
.level
= RAW_FILEINFO_ACCESS_INFORMATION
;
863 qfinfo
.access_information
.in
.file
.handle
= _h1
;
865 for (i
=0; i
< 2; i
++) {
866 torture_comment(tctx
, "query info => OK\n");
868 ZERO_STRUCT(qfinfo
.access_information
.out
);
869 status
= smb2_getinfo_file(tree
, tctx
, &qfinfo
);
870 CHECK_STATUS(status
, NT_STATUS_OK
);
872 torture_comment(tctx
, "sleep 5 seconds\n");
875 torture_comment(tctx
, "query info => EXPIRED\n");
876 ZERO_STRUCT(qfinfo
.access_information
.out
);
877 status
= smb2_getinfo_file(tree
, tctx
, &qfinfo
);
878 CHECK_STATUS(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
);
881 * the krb5 library may not handle expired creds
882 * well, lets start with an empty ccache.
884 cli_credentials_invalidate_ccache(credentials
, CRED_SPECIFIED
);
886 torture_comment(tctx
, "reauth => OK\n");
887 status
= smb2_session_setup_spnego(tree
->session
,
889 0 /* previous_session_id */);
890 CHECK_STATUS(status
, NT_STATUS_OK
);
893 ZERO_STRUCT(qfinfo
.access_information
.out
);
894 status
= smb2_getinfo_file(tree
, tctx
, &qfinfo
);
895 CHECK_STATUS(status
, NT_STATUS_OK
);
900 smb2_util_close(tree
, *h1
);
904 lpcfg_set_option(tctx
->lp_ctx
, "gensec_gssapi:requested_life_time=0");
908 struct torture_suite
*torture_smb2_session_init(void)
910 struct torture_suite
*suite
=
911 torture_suite_create(talloc_autofree_context(), "session");
913 torture_suite_add_1smb2_test(suite
, "reconnect1", test_session_reconnect1
);
914 torture_suite_add_1smb2_test(suite
, "reconnect2", test_session_reconnect2
);
915 torture_suite_add_1smb2_test(suite
, "reauth1", test_session_reauth1
);
916 torture_suite_add_1smb2_test(suite
, "reauth2", test_session_reauth2
);
917 torture_suite_add_1smb2_test(suite
, "reauth3", test_session_reauth3
);
918 torture_suite_add_1smb2_test(suite
, "reauth4", test_session_reauth4
);
919 torture_suite_add_1smb2_test(suite
, "reauth5", test_session_reauth5
);
920 torture_suite_add_simple_test(suite
, "expire1", test_session_expire1
);
922 suite
->description
= talloc_strdup(suite
, "SMB2-SESSION tests");