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 "auth/credentials/credentials_krb5.h"
31 #include "libcli/security/security.h"
32 #include "libcli/resolve/resolve.h"
33 #include "lib/param/param.h"
34 #include "lib/util/tevent_ntstatus.h"
36 #define CHECK_CREATED(tctx, __io, __created, __attribute) \
38 torture_assert_int_equal(tctx, (__io)->out.create_action, \
39 NTCREATEX_ACTION_ ## __created, \
40 "out.create_action incorrect"); \
41 torture_assert_int_equal(tctx, (__io)->out.alloc_size, 0, \
42 "out.alloc_size incorrect"); \
43 torture_assert_int_equal(tctx, (__io)->out.size, 0, \
44 "out.size incorrect"); \
45 torture_assert_int_equal(tctx, (__io)->out.file_attr, \
47 "out.file_attr incorrect"); \
48 torture_assert_int_equal(tctx, (__io)->out.reserved2, 0, \
49 "out.reserverd2 incorrect"); \
53 * basic test for doing a session reconnect
55 bool test_session_reconnect1(struct torture_context *tctx, struct smb2_tree *tree)
58 TALLOC_CTX *mem_ctx = talloc_new(tctx);
60 struct smb2_handle _h1;
61 struct smb2_handle *h1 = NULL;
62 struct smb2_handle _h2;
63 struct smb2_handle *h2 = NULL;
64 struct smb2_create io1, io2;
65 uint64_t previous_session_id;
67 struct smb2_tree *tree2 = NULL;
68 union smb_fileinfo qfinfo;
70 /* Add some random component to the file name. */
71 snprintf(fname, sizeof(fname), "session_reconnect_%s.dat",
72 generate_random_str(tctx, 8));
74 smb2_util_unlink(tree, fname);
76 smb2_oplock_create_share(&io1, fname,
77 smb2_util_share_access(""),
78 smb2_util_oplock_level("b"));
80 status = smb2_create(tree, mem_ctx, &io1);
81 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
82 "smb2_create failed");
83 _h1 = io1.out.file.handle;
85 CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
86 torture_assert_int_equal(tctx, io1.out.oplock_level,
87 smb2_util_oplock_level("b"),
88 "oplock_level incorrect");
90 /* disconnect, reconnect and then do durable reopen */
91 previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
93 torture_assert_goto(tctx, torture_smb2_connection_ext(tctx, previous_session_id,
94 &tree->session->transport->options, &tree2),
96 "session reconnect failed\n");
98 /* try to access the file via the old handle */
101 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
102 qfinfo.generic.in.file.handle = _h1;
103 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
104 torture_assert_ntstatus_equal_goto(tctx, status,
105 NT_STATUS_USER_SESSION_DELETED,
106 ret, done, "smb2_getinfo_file "
107 "returned unexpected status");
110 smb2_oplock_create_share(&io2, fname,
111 smb2_util_share_access(""),
112 smb2_util_oplock_level("b"));
114 status = smb2_create(tree2, mem_ctx, &io2);
115 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
116 "smb2_create failed");
118 CHECK_CREATED(tctx, &io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
119 torture_assert_int_equal(tctx, io1.out.oplock_level,
120 smb2_util_oplock_level("b"),
121 "oplock_level incorrect");
122 _h2 = io2.out.file.handle;
127 smb2_util_close(tree, *h1);
130 smb2_util_close(tree2, *h2);
134 smb2_util_unlink(tree2, fname);
136 smb2_util_unlink(tree, fname);
141 talloc_free(mem_ctx);
147 * basic test for doing a session reconnect on one connection
149 bool test_session_reconnect2(struct torture_context *tctx, struct smb2_tree *tree)
152 TALLOC_CTX *mem_ctx = talloc_new(tctx);
154 struct smb2_handle _h1;
155 struct smb2_handle *h1 = NULL;
156 struct smb2_create io1;
157 uint64_t previous_session_id;
159 struct smb2_session *session2 = NULL;
160 union smb_fileinfo qfinfo;
162 /* Add some random component to the file name. */
163 snprintf(fname, sizeof(fname), "session_reconnect_%s.dat",
164 generate_random_str(tctx, 8));
166 smb2_util_unlink(tree, fname);
168 smb2_oplock_create_share(&io1, fname,
169 smb2_util_share_access(""),
170 smb2_util_oplock_level("b"));
171 io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
173 status = smb2_create(tree, mem_ctx, &io1);
174 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
175 "smb2_create failed");
176 _h1 = io1.out.file.handle;
178 CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
179 torture_assert_int_equal(tctx, io1.out.oplock_level,
180 smb2_util_oplock_level("b"),
181 "oplock_level incorrect");
183 /* disconnect, reconnect and then do durable reopen */
184 previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
186 torture_assert(tctx, torture_smb2_session_setup(tctx, tree->session->transport,
187 previous_session_id, tctx, &session2),
188 "session reconnect (on the same connection) failed");
190 /* try to access the file via the old handle */
193 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
194 qfinfo.generic.in.file.handle = _h1;
195 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
196 torture_assert_ntstatus_equal_goto(tctx, status,
197 NT_STATUS_USER_SESSION_DELETED,
198 ret, done, "smb2_getinfo_file "
199 "returned unexpected status");
204 smb2_util_close(tree, *h1);
208 talloc_free(session2);
210 talloc_free(mem_ctx);
215 bool test_session_reauth1(struct torture_context *tctx, struct smb2_tree *tree)
218 TALLOC_CTX *mem_ctx = talloc_new(tctx);
220 struct smb2_handle _h1;
221 struct smb2_handle *h1 = NULL;
222 struct smb2_create io1;
224 union smb_fileinfo qfinfo;
226 /* Add some random component to the file name. */
227 snprintf(fname, sizeof(fname), "session_reauth1_%s.dat",
228 generate_random_str(tctx, 8));
230 smb2_util_unlink(tree, fname);
232 smb2_oplock_create_share(&io1, fname,
233 smb2_util_share_access(""),
234 smb2_util_oplock_level("b"));
236 status = smb2_create(tree, mem_ctx, &io1);
237 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
238 "smb2_create failed");
239 _h1 = io1.out.file.handle;
241 CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
242 torture_assert_int_equal(tctx, io1.out.oplock_level,
243 smb2_util_oplock_level("b"),
244 "oplock_level incorrect");
246 status = smb2_session_setup_spnego(tree->session,
247 popt_get_cmdline_credentials(),
248 0 /* previous_session_id */);
249 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
250 "smb2_session_setup_spnego failed");
252 /* try to access the file via the old handle */
255 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
256 qfinfo.generic.in.file.handle = _h1;
257 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
258 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
259 "smb2_getinfo_file failed");
261 status = smb2_session_setup_spnego(tree->session,
262 popt_get_cmdline_credentials(),
263 0 /* previous_session_id */);
264 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
265 "smb2_session_setup_spnego failed");
267 /* try to access the file via the old handle */
270 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
271 qfinfo.generic.in.file.handle = _h1;
272 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
273 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
274 "smb2_getinfo_file failed");
278 smb2_util_close(tree, *h1);
281 smb2_util_unlink(tree, fname);
285 talloc_free(mem_ctx);
290 bool test_session_reauth2(struct torture_context *tctx, struct smb2_tree *tree)
293 TALLOC_CTX *mem_ctx = talloc_new(tctx);
295 struct smb2_handle _h1;
296 struct smb2_handle *h1 = NULL;
297 struct smb2_create io1;
299 union smb_fileinfo qfinfo;
300 struct cli_credentials *anon_creds = NULL;
302 /* Add some random component to the file name. */
303 snprintf(fname, sizeof(fname), "session_reauth2_%s.dat",
304 generate_random_str(tctx, 8));
306 smb2_util_unlink(tree, fname);
308 smb2_oplock_create_share(&io1, fname,
309 smb2_util_share_access(""),
310 smb2_util_oplock_level("b"));
312 status = smb2_create(tree, mem_ctx, &io1);
313 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
314 "smb2_create failed");
315 _h1 = io1.out.file.handle;
317 CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
318 torture_assert_int_equal(tctx, io1.out.oplock_level,
319 smb2_util_oplock_level("b"),
320 "oplock_level incorrect");
322 /* re-authenticate as anonymous */
324 anon_creds = cli_credentials_init_anon(mem_ctx);
325 torture_assert(tctx, (anon_creds != NULL), "talloc error");
327 status = smb2_session_setup_spnego(tree->session,
329 0 /* previous_session_id */);
330 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
331 "smb2_session_setup_spnego failed");
333 /* try to access the file via the old handle */
336 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
337 qfinfo.generic.in.file.handle = _h1;
338 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
339 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
340 "smb2_getinfo_file failed");
342 /* re-authenticate as original user again */
344 status = smb2_session_setup_spnego(tree->session,
345 popt_get_cmdline_credentials(),
346 0 /* previous_session_id */);
347 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
348 "smb2_session_setup_spnego failed");
350 /* try to access the file via the old handle */
353 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
354 qfinfo.generic.in.file.handle = _h1;
355 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
356 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
357 "smb2_getinfo_file failed");
361 smb2_util_close(tree, *h1);
364 smb2_util_unlink(tree, fname);
368 talloc_free(mem_ctx);
374 * test getting security descriptor after reauth
376 bool test_session_reauth3(struct torture_context *tctx, struct smb2_tree *tree)
379 TALLOC_CTX *mem_ctx = talloc_new(tctx);
381 struct smb2_handle _h1;
382 struct smb2_handle *h1 = NULL;
383 struct smb2_create io1;
385 union smb_fileinfo qfinfo;
386 struct cli_credentials *anon_creds = NULL;
387 uint32_t secinfo_flags = SECINFO_OWNER
390 | SECINFO_PROTECTED_DACL
391 | SECINFO_UNPROTECTED_DACL;
393 /* Add some random component to the file name. */
394 snprintf(fname, sizeof(fname), "session_reauth3_%s.dat",
395 generate_random_str(tctx, 8));
397 smb2_util_unlink(tree, fname);
399 smb2_oplock_create_share(&io1, fname,
400 smb2_util_share_access(""),
401 smb2_util_oplock_level("b"));
403 status = smb2_create(tree, mem_ctx, &io1);
404 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
405 "smb2_create failed");
406 _h1 = io1.out.file.handle;
408 CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
409 torture_assert_int_equal(tctx, io1.out.oplock_level,
410 smb2_util_oplock_level("b"),
411 "oplock_level incorrect");
413 /* get the security descriptor */
417 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
418 qfinfo.query_secdesc.in.file.handle = _h1;
419 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
421 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
422 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
423 "smb2_getinfo_file failed");
425 /* re-authenticate as anonymous */
427 anon_creds = cli_credentials_init_anon(mem_ctx);
428 torture_assert(tctx, (anon_creds != NULL), "talloc error");
430 status = smb2_session_setup_spnego(tree->session,
432 0 /* previous_session_id */);
433 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
434 "smb2_session_setup_spnego failed");
436 /* try to access the file via the old handle */
440 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
441 qfinfo.query_secdesc.in.file.handle = _h1;
442 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
444 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
445 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
446 "smb2_getinfo_file failed");
448 /* re-authenticate as original user again */
450 status = smb2_session_setup_spnego(tree->session,
451 popt_get_cmdline_credentials(),
452 0 /* previous_session_id */);
453 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
454 "smb2_session_setup_spnego failed");
456 /* try to access the file via the old handle */
460 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
461 qfinfo.query_secdesc.in.file.handle = _h1;
462 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
464 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
465 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
466 "smb2_getinfo_file failed");
470 smb2_util_close(tree, *h1);
473 smb2_util_unlink(tree, fname);
477 talloc_free(mem_ctx);
483 * test setting security descriptor after reauth.
485 bool test_session_reauth4(struct torture_context *tctx, struct smb2_tree *tree)
488 TALLOC_CTX *mem_ctx = talloc_new(tctx);
490 struct smb2_handle _h1;
491 struct smb2_handle *h1 = NULL;
492 struct smb2_create io1;
494 union smb_fileinfo qfinfo;
495 union smb_setfileinfo sfinfo;
496 struct cli_credentials *anon_creds = NULL;
497 uint32_t secinfo_flags = SECINFO_OWNER
500 | SECINFO_PROTECTED_DACL
501 | SECINFO_UNPROTECTED_DACL;
502 struct security_descriptor *sd1;
503 struct security_ace ace;
504 struct dom_sid *extra_sid;
506 /* Add some random component to the file name. */
507 snprintf(fname, sizeof(fname), "session_reauth4_%s.dat",
508 generate_random_str(tctx, 8));
510 smb2_util_unlink(tree, fname);
512 smb2_oplock_create_share(&io1, fname,
513 smb2_util_share_access(""),
514 smb2_util_oplock_level("b"));
516 status = smb2_create(tree, mem_ctx, &io1);
517 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
518 "smb2_create failed");
519 _h1 = io1.out.file.handle;
521 CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
522 torture_assert_int_equal(tctx, io1.out.oplock_level,
523 smb2_util_oplock_level("b"),
524 "oplock_level incorrect");
526 /* get the security descriptor */
530 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
531 qfinfo.query_secdesc.in.file.handle = _h1;
532 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
534 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
535 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
536 "smb2_getinfo_file failed");
538 sd1 = qfinfo.query_secdesc.out.sd;
540 /* re-authenticate as anonymous */
542 anon_creds = cli_credentials_init_anon(mem_ctx);
543 torture_assert(tctx, (anon_creds != NULL), "talloc error");
545 status = smb2_session_setup_spnego(tree->session,
547 0 /* previous_session_id */);
548 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
549 "smb2_session_setup_spnego failed");
551 /* give full access on the file to anonymous */
553 extra_sid = dom_sid_parse_talloc(tctx, SID_NT_ANONYMOUS);
556 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
558 ace.access_mask = SEC_STD_ALL | SEC_FILE_ALL;
559 ace.trustee = *extra_sid;
561 status = security_descriptor_dacl_add(sd1, &ace);
562 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
563 "security_descriptor_dacl_add failed");
566 sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
567 sfinfo.set_secdesc.in.file.handle = _h1;
568 sfinfo.set_secdesc.in.secinfo_flags = SECINFO_DACL;
569 sfinfo.set_secdesc.in.sd = sd1;
571 status = smb2_setinfo_file(tree, &sfinfo);
572 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
573 "smb2_setinfo_file failed");
575 /* re-authenticate as original user again */
577 status = smb2_session_setup_spnego(tree->session,
578 popt_get_cmdline_credentials(),
579 0 /* previous_session_id */);
580 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
581 "smb2_session_setup_spnego failed");
583 /* re-get the security descriptor */
587 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
588 qfinfo.query_secdesc.in.file.handle = _h1;
589 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
591 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
592 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
593 "smb2_getinfo_file failed");
599 smb2_util_close(tree, *h1);
602 smb2_util_unlink(tree, fname);
606 talloc_free(mem_ctx);
612 * test renaming after reauth.
613 * compare security descriptors before and after rename/reauth
615 bool test_session_reauth5(struct torture_context *tctx, struct smb2_tree *tree)
618 TALLOC_CTX *mem_ctx = talloc_new(tctx);
622 struct smb2_handle _dh1;
623 struct smb2_handle *dh1 = NULL;
624 struct smb2_handle _h1;
625 struct smb2_handle *h1 = NULL;
626 struct smb2_create io1;
629 union smb_fileinfo qfinfo;
630 union smb_setfileinfo sfinfo;
631 struct cli_credentials *anon_creds = NULL;
632 uint32_t secinfo_flags = SECINFO_OWNER
635 | SECINFO_PROTECTED_DACL
636 | SECINFO_UNPROTECTED_DACL;
637 struct security_descriptor *f_sd1;
638 struct security_descriptor *d_sd1 = NULL;
639 struct security_ace ace;
640 struct dom_sid *extra_sid;
642 /* Add some random component to the file name. */
643 snprintf(dname, sizeof(dname), "session_reauth5_%s.d",
644 generate_random_str(tctx, 8));
645 snprintf(fname, sizeof(fname), "%s\\file.dat", dname);
647 ok = smb2_util_setup_dir(tctx, tree, dname);
648 torture_assert(tctx, ok, "smb2_util_setup_dir not ok");
650 status = torture_smb2_testdir(tree, dname, &_dh1);
651 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
652 "torture_smb2_testdir failed");
655 smb2_oplock_create_share(&io1, fname,
656 smb2_util_share_access(""),
657 smb2_util_oplock_level("b"));
659 status = smb2_create(tree, mem_ctx, &io1);
660 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
661 "smb2_create failed");
662 _h1 = io1.out.file.handle;
664 CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
665 torture_assert_int_equal(tctx, io1.out.oplock_level,
666 smb2_util_oplock_level("b"),
667 "oplock_level incorrect");
669 /* get the security descriptor */
673 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
674 qfinfo.query_secdesc.in.file.handle = _h1;
675 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
677 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
678 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
679 "smb2_getinfo_file failed");
681 f_sd1 = qfinfo.query_secdesc.out.sd;
683 /* re-authenticate as anonymous */
685 anon_creds = cli_credentials_init_anon(mem_ctx);
686 torture_assert(tctx, (anon_creds != NULL), "talloc error");
688 status = smb2_session_setup_spnego(tree->session,
690 0 /* previous_session_id */);
691 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
692 "smb2_session_setup_spnego failed");
694 /* try to rename the file: fails */
696 snprintf(fname2, sizeof(fname2), "%s\\file2.dat", dname);
698 status = smb2_util_unlink(tree, fname2);
699 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
700 "smb2_util_unlink failed");
704 sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
705 sfinfo.rename_information.in.file.handle = _h1;
706 sfinfo.rename_information.in.overwrite = true;
707 sfinfo.rename_information.in.new_name = fname2;
709 status = smb2_setinfo_file(tree, &sfinfo);
710 torture_assert_ntstatus_equal_goto(tctx, status,
711 NT_STATUS_ACCESS_DENIED,
712 ret, done, "smb2_setinfo_file "
713 "returned unexpected status");
715 /* re-authenticate as original user again */
717 status = smb2_session_setup_spnego(tree->session,
718 popt_get_cmdline_credentials(),
719 0 /* previous_session_id */);
720 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
721 "smb2_session_setup_spnego failed");
723 /* give full access on the file to anonymous */
725 extra_sid = dom_sid_parse_talloc(tctx, SID_NT_ANONYMOUS);
728 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
730 ace.access_mask = SEC_RIGHTS_FILE_ALL;
731 ace.trustee = *extra_sid;
733 status = security_descriptor_dacl_add(f_sd1, &ace);
734 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
735 "security_descriptor_dacl_add failed");
738 sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
739 sfinfo.set_secdesc.in.file.handle = _h1;
740 sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags;
741 sfinfo.set_secdesc.in.sd = f_sd1;
743 status = smb2_setinfo_file(tree, &sfinfo);
744 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
745 "smb2_setinfo_file failed");
747 /* re-get the security descriptor */
751 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
752 qfinfo.query_secdesc.in.file.handle = _h1;
753 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
755 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
756 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
757 "smb2_getinfo_file failed");
759 /* re-authenticate as anonymous - again */
761 anon_creds = cli_credentials_init_anon(mem_ctx);
762 torture_assert(tctx, (anon_creds != NULL), "talloc error");
764 status = smb2_session_setup_spnego(tree->session,
766 0 /* previous_session_id */);
767 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
768 "smb2_session_setup_spnego failed");
770 /* try to rename the file: fails */
773 sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
774 sfinfo.rename_information.in.file.handle = _h1;
775 sfinfo.rename_information.in.overwrite = true;
776 sfinfo.rename_information.in.new_name = fname2;
778 status = smb2_setinfo_file(tree, &sfinfo);
779 torture_assert_ntstatus_equal_goto(tctx, status,
780 NT_STATUS_ACCESS_DENIED,
781 ret, done, "smb2_setinfo_file "
782 "returned unexpected status");
784 /* give full access on the parent dir to anonymous */
788 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
789 qfinfo.query_secdesc.in.file.handle = _dh1;
790 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
792 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
793 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
794 "smb2_getinfo_file failed");
796 d_sd1 = qfinfo.query_secdesc.out.sd;
799 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
801 ace.access_mask = SEC_RIGHTS_FILE_ALL;
802 ace.trustee = *extra_sid;
804 status = security_descriptor_dacl_add(d_sd1, &ace);
805 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
806 "security_descriptor_dacl_add failed");
809 sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
810 sfinfo.set_secdesc.in.file.handle = _dh1;
811 sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags;
812 sfinfo.set_secdesc.in.secinfo_flags = SECINFO_DACL;
813 sfinfo.set_secdesc.in.sd = d_sd1;
815 status = smb2_setinfo_file(tree, &sfinfo);
816 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
817 "smb2_setinfo_file failed");
821 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
822 qfinfo.query_secdesc.in.file.handle = _dh1;
823 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
825 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
826 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
827 "smb2_getinfo_file failed");
829 status = smb2_util_close(tree, _dh1);
830 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
831 "smb2_util_close failed");
834 /* try to rename the file: still fails */
837 sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
838 sfinfo.rename_information.in.file.handle = _h1;
839 sfinfo.rename_information.in.overwrite = true;
840 sfinfo.rename_information.in.new_name = fname2;
842 status = smb2_setinfo_file(tree, &sfinfo);
843 torture_assert_ntstatus_equal_goto(tctx, status,
844 NT_STATUS_ACCESS_DENIED,
845 ret, done, "smb2_setinfo_file "
846 "returned unexpected status");
848 /* re-authenticate as original user - again */
850 status = smb2_session_setup_spnego(tree->session,
851 popt_get_cmdline_credentials(),
852 0 /* previous_session_id */);
853 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
854 "smb2_session_setup_spnego failed");
856 /* rename the file - for verification that it works */
859 sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
860 sfinfo.rename_information.in.file.handle = _h1;
861 sfinfo.rename_information.in.overwrite = true;
862 sfinfo.rename_information.in.new_name = fname2;
864 status = smb2_setinfo_file(tree, &sfinfo);
865 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
866 "smb2_setinfo_file failed");
868 /* closs the file, check it is gone and reopen under the new name */
870 status = smb2_util_close(tree, _h1);
871 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
872 "smb2_util_close failed");
875 smb2_generic_create_share(&io1,
876 NULL /* lease */, false /* dir */,
879 smb2_util_share_access(""),
880 smb2_util_oplock_level("b"),
881 0 /* leasekey */, 0 /* leasestate */);
883 status = smb2_create(tree, mem_ctx, &io1);
884 torture_assert_ntstatus_equal_goto(tctx, status,
885 NT_STATUS_OBJECT_NAME_NOT_FOUND,
886 ret, done, "smb2_create "
887 "returned unexpected status");
891 smb2_generic_create_share(&io1,
892 NULL /* lease */, false /* dir */,
895 smb2_util_share_access(""),
896 smb2_util_oplock_level("b"),
897 0 /* leasekey */, 0 /* leasestate */);
899 status = smb2_create(tree, mem_ctx, &io1);
900 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
901 "smb2_create failed");
902 _h1 = io1.out.file.handle;
904 CHECK_CREATED(tctx, &io1, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
905 torture_assert_int_equal(tctx, io1.out.oplock_level,
906 smb2_util_oplock_level("b"),
907 "oplock_level incorrect");
909 /* try to access the file via the old handle */
913 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
914 qfinfo.query_secdesc.in.file.handle = _h1;
915 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
917 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
918 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
919 "smb2_getinfo_file failed");
923 smb2_util_close(tree, *dh1);
926 smb2_util_close(tree, *h1);
929 smb2_deltree(tree, dname);
933 talloc_free(mem_ctx);
939 * do reauth with wrong credentials,
940 * hence triggering the error path in reauth.
941 * The invalid reauth deletes the session.
943 bool test_session_reauth6(struct torture_context *tctx, struct smb2_tree *tree)
946 TALLOC_CTX *mem_ctx = talloc_new(tctx);
948 struct smb2_handle _h1;
949 struct smb2_handle *h1 = NULL;
950 struct smb2_create io1;
952 char *corrupted_password;
953 struct cli_credentials *broken_creds;
957 enum credentials_use_kerberos krb_state;
959 krb_state = cli_credentials_get_kerberos_state(
960 popt_get_cmdline_credentials());
961 if (krb_state == CRED_MUST_USE_KERBEROS) {
963 "Can't test failing session setup with kerberos.");
966 encrypted = smb2cli_tcon_is_encryption_on(tree->smbXcli);
968 /* Add some random component to the file name. */
969 snprintf(fname, sizeof(fname), "session_reauth1_%s.dat",
970 generate_random_str(tctx, 8));
972 smb2_util_unlink(tree, fname);
974 smb2_oplock_create_share(&io1, fname,
975 smb2_util_share_access(""),
976 smb2_util_oplock_level("b"));
977 io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
979 status = smb2_create(tree, mem_ctx, &io1);
980 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
981 "smb2_create failed");
982 _h1 = io1.out.file.handle;
984 CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
985 torture_assert_int_equal(tctx, io1.out.oplock_level,
986 smb2_util_oplock_level("b"),
987 "oplock_level incorrect");
990 * reauthentication with invalid credentials:
993 broken_creds = cli_credentials_shallow_copy(mem_ctx,
994 popt_get_cmdline_credentials());
995 torture_assert(tctx, (broken_creds != NULL), "talloc error");
997 corrupted_password = talloc_asprintf(mem_ctx, "%s%s",
998 cli_credentials_get_password(broken_creds),
1000 torture_assert(tctx, (corrupted_password != NULL), "talloc error");
1002 ok = cli_credentials_set_password(broken_creds, corrupted_password,
1004 torture_assert(tctx, ok, "cli_credentials_set_password not ok");
1006 status = smb2_session_setup_spnego(tree->session,
1008 0 /* previous_session_id */);
1009 torture_assert_ntstatus_equal_goto(tctx, status,
1010 NT_STATUS_LOGON_FAILURE, ret, done,
1011 "smb2_session_setup_spnego "
1012 "returned unexpected status");
1014 torture_comment(tctx, "did failed reauth\n");
1016 * now verify that the invalid session reauth has closed our session
1020 expected = NT_STATUS_CONNECTION_DISCONNECTED;
1022 expected = NT_STATUS_USER_SESSION_DELETED;
1025 smb2_oplock_create_share(&io1, fname,
1026 smb2_util_share_access(""),
1027 smb2_util_oplock_level("b"));
1029 status = smb2_create(tree, mem_ctx, &io1);
1030 torture_assert_ntstatus_equal_goto(tctx, status, expected,
1031 ret, done, "smb2_create "
1032 "returned unexpected status");
1036 smb2_util_close(tree, *h1);
1039 smb2_util_unlink(tree, fname);
1043 talloc_free(mem_ctx);
1049 static bool test_session_expire1i(struct torture_context *tctx,
1050 bool force_encryption)
1054 struct smbcli_options options;
1055 const char *host = torture_setting_string(tctx, "host", NULL);
1056 const char *share = torture_setting_string(tctx, "share", NULL);
1057 struct cli_credentials *credentials = popt_get_cmdline_credentials();
1058 struct smb2_tree *tree = NULL;
1059 enum credentials_use_kerberos use_kerberos;
1061 struct smb2_handle _h1;
1062 struct smb2_handle *h1 = NULL;
1063 struct smb2_create io1;
1064 union smb_fileinfo qfinfo;
1067 use_kerberos = cli_credentials_get_kerberos_state(credentials);
1068 if (use_kerberos != CRED_MUST_USE_KERBEROS) {
1069 torture_warning(tctx, "smb2.session.expire1 requires -k yes!");
1070 torture_skip(tctx, "smb2.session.expire1 requires -k yes!");
1073 torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS,
1074 "please use -k yes");
1076 cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1078 lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");
1080 lpcfg_smbcli_options(tctx->lp_ctx, &options);
1081 options.signing = SMB_SIGNING_REQUIRED;
1083 status = smb2_connect(tctx,
1085 lpcfg_smb_ports(tctx->lp_ctx),
1087 lpcfg_resolve_context(tctx->lp_ctx),
1092 lpcfg_socket_options(tctx->lp_ctx),
1093 lpcfg_gensec_settings(tctx, tctx->lp_ctx)
1095 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1096 "smb2_connect failed");
1098 if (force_encryption) {
1099 status = smb2cli_session_encryption_on(tree->session->smbXcli);
1100 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1101 "smb2cli_session_encryption_on failed");
1104 /* Add some random component to the file name. */
1105 snprintf(fname, sizeof(fname), "session_expire1_%s.dat",
1106 generate_random_str(tctx, 8));
1108 smb2_util_unlink(tree, fname);
1110 smb2_oplock_create_share(&io1, fname,
1111 smb2_util_share_access(""),
1112 smb2_util_oplock_level("b"));
1113 io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
1115 status = smb2_create(tree, tctx, &io1);
1116 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1117 "smb2_create failed");
1118 _h1 = io1.out.file.handle;
1120 CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1121 torture_assert_int_equal(tctx, io1.out.oplock_level,
1122 smb2_util_oplock_level("b"),
1123 "oplock_level incorrect");
1125 /* get the security descriptor */
1127 ZERO_STRUCT(qfinfo);
1129 qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
1130 qfinfo.access_information.in.file.handle = _h1;
1132 for (i=0; i < 2; i++) {
1133 torture_comment(tctx, "query info => OK\n");
1135 ZERO_STRUCT(qfinfo.access_information.out);
1136 status = smb2_getinfo_file(tree, tctx, &qfinfo);
1137 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1138 "smb2_getinfo_file failed");
1140 torture_comment(tctx, "sleep 10 seconds\n");
1141 smb_msleep(10*1000);
1143 torture_comment(tctx, "query info => EXPIRED\n");
1144 ZERO_STRUCT(qfinfo.access_information.out);
1145 status = smb2_getinfo_file(tree, tctx, &qfinfo);
1146 torture_assert_ntstatus_equal_goto(tctx, status,
1147 NT_STATUS_NETWORK_SESSION_EXPIRED,
1148 ret, done, "smb2_getinfo_file "
1149 "returned unexpected status");
1152 * the krb5 library may not handle expired creds
1153 * well, lets start with an empty ccache.
1155 cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1157 if (!force_encryption) {
1158 smb2cli_session_require_signed_response(
1159 tree->session->smbXcli, true);
1162 torture_comment(tctx, "reauth => OK\n");
1163 status = smb2_session_setup_spnego(tree->session,
1165 0 /* previous_session_id */);
1166 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1167 "smb2_session_setup_spnego failed");
1169 smb2cli_session_require_signed_response(
1170 tree->session->smbXcli, false);
1173 ZERO_STRUCT(qfinfo.access_information.out);
1174 status = smb2_getinfo_file(tree, tctx, &qfinfo);
1175 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1176 "smb2_getinfo_file failed");
1180 cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1183 smb2_util_close(tree, *h1);
1187 lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0");
1191 static bool test_session_expire1s(struct torture_context *tctx)
1193 return test_session_expire1i(tctx,
1194 false); /* force_encryption */
1197 static bool test_session_expire1e(struct torture_context *tctx)
1199 return test_session_expire1i(tctx,
1200 true); /* force_encryption */
1203 static bool test_session_expire2i(struct torture_context *tctx,
1204 bool force_encryption)
1208 struct smbcli_options options;
1209 const char *host = torture_setting_string(tctx, "host", NULL);
1210 const char *share = torture_setting_string(tctx, "share", NULL);
1211 struct cli_credentials *credentials = popt_get_cmdline_credentials();
1212 struct smb2_tree *tree = NULL;
1213 const char *unc = NULL;
1214 struct smb2_tree *tree2 = NULL;
1215 struct tevent_req *subreq = NULL;
1216 uint32_t timeout_msec;
1217 enum credentials_use_kerberos use_kerberos;
1220 struct smb2_handle dh;
1221 struct smb2_handle dh2;
1222 struct smb2_handle _h1;
1223 struct smb2_handle *h1 = NULL;
1224 struct smb2_create io1;
1225 union smb_fileinfo qfinfo;
1226 union smb_setfileinfo sfinfo;
1227 struct smb2_flush flsh;
1228 struct smb2_read rd;
1229 const uint8_t wd = 0;
1230 struct smb2_lock lck;
1231 struct smb2_lock_element el;
1232 struct smb2_ioctl ctl;
1233 struct smb2_break oack;
1234 struct smb2_lease_break_ack lack;
1235 struct smb2_find fnd;
1236 union smb_search_data *d = NULL;
1238 struct smb2_request *req = NULL;
1239 struct smb2_notify ntf1;
1240 struct smb2_notify ntf2;
1242 use_kerberos = cli_credentials_get_kerberos_state(credentials);
1243 if (use_kerberos != CRED_MUST_USE_KERBEROS) {
1244 torture_warning(tctx, "smb2.session.expire2 requires -k yes!");
1245 torture_skip(tctx, "smb2.session.expire2 requires -k yes!");
1248 torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS,
1249 "please use -k yes");
1251 cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1253 lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");
1255 lpcfg_smbcli_options(tctx->lp_ctx, &options);
1256 options.signing = SMB_SIGNING_REQUIRED;
1258 unc = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
1259 torture_assert(tctx, unc != NULL, "talloc_asprintf");
1261 status = smb2_connect(tctx,
1263 lpcfg_smb_ports(tctx->lp_ctx),
1265 lpcfg_resolve_context(tctx->lp_ctx),
1270 lpcfg_socket_options(tctx->lp_ctx),
1271 lpcfg_gensec_settings(tctx, tctx->lp_ctx)
1273 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1274 "smb2_connect failed");
1276 if (force_encryption) {
1277 status = smb2cli_session_encryption_on(tree->session->smbXcli);
1278 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1279 "smb2cli_session_encryption_on failed");
1282 caps = smb2cli_conn_server_capabilities(tree->session->transport->conn);
1284 /* Add some random component to the file name. */
1285 snprintf(fname, sizeof(fname), "session_expire2_%s.dat",
1286 generate_random_str(tctx, 8));
1288 smb2_util_unlink(tree, fname);
1290 status = smb2_util_roothandle(tree, &dh);
1291 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1292 "smb2_util_roothandle failed");
1294 smb2_oplock_create_share(&io1, fname,
1295 smb2_util_share_access(""),
1296 smb2_util_oplock_level("b"));
1297 io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
1299 status = smb2_create(tree, tctx, &io1);
1300 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1301 "smb2_create failed");
1302 _h1 = io1.out.file.handle;
1304 CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1305 torture_assert_int_equal(tctx, io1.out.oplock_level,
1306 smb2_util_oplock_level("b"),
1307 "oplock_level incorrect");
1309 /* get the security descriptor */
1311 ZERO_STRUCT(qfinfo);
1313 qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
1314 qfinfo.access_information.in.file.handle = _h1;
1316 torture_comment(tctx, "query info => OK\n");
1318 ZERO_STRUCT(qfinfo.access_information.out);
1319 status = smb2_getinfo_file(tree, tctx, &qfinfo);
1320 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1321 "smb2_getinfo_file failed");
1323 torture_comment(tctx, "lock => OK\n");
1326 lck.in.lock_count = 0x0001;
1327 lck.in.lock_sequence = 0x00000000;
1328 lck.in.file.handle = *h1;
1330 el.flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1331 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1332 el.offset = 0x0000000000000000;
1333 el.length = 0x0000000000000001;
1334 status = smb2_lock(tree, &lck);
1335 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1336 "smb2_lock lock failed");
1338 torture_comment(tctx, "1st notify => PENDING\n");
1340 ntf1.in.file.handle = dh;
1341 ntf1.in.recursive = 0x0000;
1342 ntf1.in.buffer_size = 128;
1343 ntf1.in.completion_filter= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1344 ntf1.in.unknown = 0x00000000;
1345 req = smb2_notify_send(tree, &ntf1);
1347 while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) {
1348 if (tevent_loop_once(tctx->ev) != 0) {
1353 torture_assert_goto(tctx, req->state <= SMB2_REQUEST_RECV, ret, done,
1354 "smb2_notify finished");
1356 torture_comment(tctx, "sleep 10 seconds\n");
1357 smb_msleep(10*1000);
1359 torture_comment(tctx, "query info => EXPIRED\n");
1360 ZERO_STRUCT(qfinfo.access_information.out);
1361 status = smb2_getinfo_file(tree, tctx, &qfinfo);
1362 torture_assert_ntstatus_equal_goto(tctx, status,
1363 NT_STATUS_NETWORK_SESSION_EXPIRED,
1364 ret, done, "smb2_getinfo_file "
1365 "returned unexpected status");
1368 torture_comment(tctx, "set info => EXPIRED\n");
1369 ZERO_STRUCT(sfinfo);
1370 sfinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1371 sfinfo.end_of_file_info.in.file.handle = *h1;
1372 sfinfo.end_of_file_info.in.size = 1;
1373 status = smb2_setinfo_file(tree, &sfinfo);
1374 torture_assert_ntstatus_equal_goto(tctx, status,
1375 NT_STATUS_NETWORK_SESSION_EXPIRED,
1376 ret, done, "smb2_setinfo_file "
1377 "returned unexpected status");
1379 torture_comment(tctx, "flush => EXPIRED\n");
1381 flsh.in.file.handle = *h1;
1382 status = smb2_flush(tree, &flsh);
1383 torture_assert_ntstatus_equal_goto(tctx, status,
1384 NT_STATUS_NETWORK_SESSION_EXPIRED,
1385 ret, done, "smb2_flush "
1386 "returned unexpected status");
1388 torture_comment(tctx, "read => EXPIRED\n");
1390 rd.in.file.handle = *h1;
1393 status = smb2_read(tree, tctx, &rd);
1394 torture_assert_ntstatus_equal_goto(tctx, status,
1395 NT_STATUS_NETWORK_SESSION_EXPIRED,
1396 ret, done, "smb2_read "
1397 "returned unexpected status");
1399 torture_comment(tctx, "write => EXPIRED\n");
1400 status = smb2_util_write(tree, *h1, &wd, 0, 1);
1401 torture_assert_ntstatus_equal_goto(tctx, status,
1402 NT_STATUS_NETWORK_SESSION_EXPIRED,
1403 ret, done, "smb2_util_write "
1404 "returned unexpected status");
1406 torture_comment(tctx, "ioctl => EXPIRED\n");
1408 ctl.in.file.handle = *h1;
1409 ctl.in.function = FSCTL_SRV_ENUM_SNAPS;
1410 ctl.in.max_response_size = 16;
1411 ctl.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
1412 status = smb2_ioctl(tree, tctx, &ctl);
1413 torture_assert_ntstatus_equal_goto(tctx, status,
1414 NT_STATUS_NETWORK_SESSION_EXPIRED,
1415 ret, done, "smb2_ioctl "
1416 "returned unexpected status");
1418 torture_comment(tctx, "oplock ack => EXPIRED\n");
1420 oack.in.file.handle = *h1;
1421 status = smb2_break(tree, &oack);
1422 torture_assert_ntstatus_equal_goto(tctx, status,
1423 NT_STATUS_NETWORK_SESSION_EXPIRED,
1424 ret, done, "smb2_break "
1425 "returned unexpected status");
1427 if (caps & SMB2_CAP_LEASING) {
1428 torture_comment(tctx, "lease ack => EXPIRED\n");
1430 lack.in.lease.lease_version = 1;
1431 lack.in.lease.lease_key.data[0] = 1;
1432 lack.in.lease.lease_key.data[1] = 2;
1433 status = smb2_lease_break_ack(tree, &lack);
1434 torture_assert_ntstatus_equal_goto(tctx, status,
1435 NT_STATUS_NETWORK_SESSION_EXPIRED,
1436 ret, done, "smb2_break "
1437 "returned unexpected status");
1440 torture_comment(tctx, "query directory => EXPIRED\n");
1442 fnd.in.file.handle = dh;
1443 fnd.in.pattern = "*";
1444 fnd.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
1445 fnd.in.max_response_size= 0x100;
1446 fnd.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO;
1447 status = smb2_find_level(tree, tree, &fnd, &count, &d);
1448 torture_assert_ntstatus_equal_goto(tctx, status,
1449 NT_STATUS_NETWORK_SESSION_EXPIRED,
1450 ret, done, "smb2_find_level "
1451 "returned unexpected status");
1453 torture_comment(tctx, "1st notify => CANCEL\n");
1456 torture_comment(tctx, "2nd notify => EXPIRED\n");
1458 ntf2.in.file.handle = dh;
1459 ntf2.in.recursive = 0x0000;
1460 ntf2.in.buffer_size = 128;
1461 ntf2.in.completion_filter= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1462 ntf2.in.unknown = 0x00000000;
1463 status = smb2_notify(tree, tctx, &ntf2);
1464 torture_assert_ntstatus_equal_goto(tctx, status,
1465 NT_STATUS_NETWORK_SESSION_EXPIRED,
1466 ret, done, "smb2_notify "
1467 "returned unexpected status");
1469 torture_assert_goto(tctx, req->state > SMB2_REQUEST_RECV, ret, done,
1470 "smb2_notify (1st) not finished");
1472 status = smb2_notify_recv(req, tctx, &ntf1);
1473 torture_assert_ntstatus_equal_goto(tctx, status,
1474 NT_STATUS_CANCELLED,
1475 ret, done, "smb2_notify cancelled"
1476 "returned unexpected status");
1478 torture_comment(tctx, "tcon => EXPIRED\n");
1479 tree2 = smb2_tree_init(tree->session, tctx, false);
1480 torture_assert(tctx, tree2 != NULL, "smb2_tree_init");
1481 timeout_msec = tree->session->transport->options.request_timeout * 1000;
1482 subreq = smb2cli_tcon_send(tree2, tctx->ev,
1483 tree2->session->transport->conn,
1485 tree2->session->smbXcli,
1489 torture_assert(tctx, subreq != NULL, "smb2cli_tcon_send");
1490 torture_assert(tctx,
1491 tevent_req_poll_ntstatus(subreq, tctx->ev, &status),
1492 "tevent_req_poll_ntstatus");
1493 status = smb2cli_tcon_recv(subreq);
1494 TALLOC_FREE(subreq);
1495 torture_assert_ntstatus_equal_goto(tctx, status,
1496 NT_STATUS_NETWORK_SESSION_EXPIRED,
1497 ret, done, "smb2cli_tcon"
1498 "returned unexpected status");
1500 torture_comment(tctx, "create => EXPIRED\n");
1501 status = smb2_util_roothandle(tree, &dh2);
1502 torture_assert_ntstatus_equal_goto(tctx, status,
1503 NT_STATUS_NETWORK_SESSION_EXPIRED,
1504 ret, done, "smb2_util_roothandle"
1505 "returned unexpected status");
1507 torture_comment(tctx, "tdis => EXPIRED\n");
1508 status = smb2_tdis(tree);
1509 torture_assert_ntstatus_equal_goto(tctx, status,
1510 NT_STATUS_NETWORK_SESSION_EXPIRED,
1511 ret, done, "smb2cli_tdis"
1512 "returned unexpected status");
1515 * (Un)Lock, Close and Logoff are still possible
1518 torture_comment(tctx, "1st unlock => OK\n");
1519 el.flags = SMB2_LOCK_FLAG_UNLOCK;
1520 status = smb2_lock(tree, &lck);
1521 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1522 "smb2_lock unlock failed");
1524 torture_comment(tctx, "2nd unlock => RANGE_NOT_LOCKED\n");
1525 status = smb2_lock(tree, &lck);
1526 torture_assert_ntstatus_equal_goto(tctx, status,
1527 NT_STATUS_RANGE_NOT_LOCKED,
1528 ret, done, "smb2_lock 2nd unlock"
1529 "returned unexpected status");
1531 torture_comment(tctx, "lock => EXPIRED\n");
1532 el.flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1533 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1534 status = smb2_lock(tree, &lck);
1535 torture_assert_ntstatus_equal_goto(tctx, status,
1536 NT_STATUS_NETWORK_SESSION_EXPIRED,
1537 ret, done, "smb2_util_roothandle"
1538 "returned unexpected status");
1540 torture_comment(tctx, "close => OK\n");
1541 status = smb2_util_close(tree, *h1);
1543 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1544 "smb2_close failed");
1546 torture_comment(tctx, "echo without session => OK\n");
1547 status = smb2_keepalive(tree->session->transport);
1548 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1549 "smb2_keepalive without session failed");
1551 torture_comment(tctx, "echo with session => OK\n");
1552 req = smb2_keepalive_send(tree->session->transport, tree->session);
1553 status = smb2_keepalive_recv(req);
1554 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1555 "smb2_keepalive with session failed");
1557 torture_comment(tctx, "logoff => OK\n");
1558 status = smb2_logoff(tree->session);
1559 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1560 "smb2_logoff failed");
1564 cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1567 smb2_util_close(tree, *h1);
1571 lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0");
1575 static bool test_session_expire2s(struct torture_context *tctx)
1577 return test_session_expire2i(tctx,
1578 false); /* force_encryption */
1581 static bool test_session_expire2e(struct torture_context *tctx)
1583 return test_session_expire2i(tctx,
1584 true); /* force_encryption */
1587 bool test_session_bind1(struct torture_context *tctx, struct smb2_tree *tree1)
1589 const char *host = torture_setting_string(tctx, "host", NULL);
1590 const char *share = torture_setting_string(tctx, "share", NULL);
1591 struct cli_credentials *credentials = popt_get_cmdline_credentials();
1593 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1595 struct smb2_handle _h1;
1596 struct smb2_handle *h1 = NULL;
1597 struct smb2_create io1;
1598 union smb_fileinfo qfinfo;
1600 struct smb2_tree *tree2 = NULL;
1601 struct smb2_transport *transport1 = tree1->session->transport;
1602 struct smb2_transport *transport2 = NULL;
1603 struct smb2_session *session1_1 = tree1->session;
1604 struct smb2_session *session1_2 = NULL;
1605 struct smb2_session *session2_1 = NULL;
1606 struct smb2_session *session2_2 = NULL;
1609 caps = smb2cli_conn_server_capabilities(transport1->conn);
1610 if (!(caps & SMB2_CAP_MULTI_CHANNEL)) {
1611 torture_skip(tctx, "server doesn't support SMB2_CAP_MULTI_CHANNEL\n");
1614 /* Add some random component to the file name. */
1615 snprintf(fname, sizeof(fname), "session_bind1_%s.dat",
1616 generate_random_str(tctx, 8));
1618 smb2_util_unlink(tree1, fname);
1620 smb2_oplock_create_share(&io1, fname,
1621 smb2_util_share_access(""),
1622 smb2_util_oplock_level("b"));
1624 status = smb2_create(tree1, mem_ctx, &io1);
1625 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1626 "smb2_create failed");
1627 _h1 = io1.out.file.handle;
1629 CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1630 torture_assert_int_equal(tctx, io1.out.oplock_level,
1631 smb2_util_oplock_level("b"),
1632 "oplock_level incorrect");
1634 status = smb2_connect(tctx,
1636 lpcfg_smb_ports(tctx->lp_ctx),
1638 lpcfg_resolve_context(tctx->lp_ctx),
1642 &transport1->options,
1643 lpcfg_socket_options(tctx->lp_ctx),
1644 lpcfg_gensec_settings(tctx, tctx->lp_ctx)
1646 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1647 "smb2_connect failed");
1648 session2_2 = tree2->session;
1649 transport2 = tree2->session->transport;
1652 * Now bind the 2nd transport connection to the 1st session
1654 session1_2 = smb2_session_channel(transport2,
1655 lpcfg_gensec_settings(tctx, tctx->lp_ctx),
1658 torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");
1660 status = smb2_session_setup_spnego(session1_2,
1661 popt_get_cmdline_credentials(),
1662 0 /* previous_session_id */);
1663 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1664 "smb2_session_setup_spnego failed");
1666 /* use the 1st connection, 1st session */
1667 ZERO_STRUCT(qfinfo);
1668 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
1669 qfinfo.generic.in.file.handle = _h1;
1670 tree1->session = session1_1;
1671 status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
1672 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1673 "smb2_getinfo_file failed");
1675 /* use the 2nd connection, 1st session */
1676 ZERO_STRUCT(qfinfo);
1677 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
1678 qfinfo.generic.in.file.handle = _h1;
1679 tree1->session = session1_2;
1680 status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
1681 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1682 "smb2_getinfo_file failed");
1684 tree1->session = session1_1;
1685 status = smb2_util_close(tree1, *h1);
1686 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1687 "smb2_util_close failed");
1691 * Now bind the 1st transport connection to the 2nd session
1693 session2_1 = smb2_session_channel(transport1,
1694 lpcfg_gensec_settings(tctx, tctx->lp_ctx),
1697 torture_assert(tctx, session2_1 != NULL, "smb2_session_channel failed");
1699 status = smb2_session_setup_spnego(session2_1,
1700 popt_get_cmdline_credentials(),
1701 0 /* previous_session_id */);
1702 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1703 "smb2_session_setup_spnego failed");
1705 tree2->session = session2_1;
1706 status = smb2_util_unlink(tree2, fname);
1707 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1708 "smb2_util_unlink failed");
1712 tree1->session = session1_1;
1715 smb2_util_close(tree1, *h1);
1718 smb2_util_unlink(tree1, fname);
1722 talloc_free(mem_ctx);
1727 struct torture_suite *torture_smb2_session_init(TALLOC_CTX *ctx)
1729 struct torture_suite *suite =
1730 torture_suite_create(ctx, "session");
1732 torture_suite_add_1smb2_test(suite, "reconnect1", test_session_reconnect1);
1733 torture_suite_add_1smb2_test(suite, "reconnect2", test_session_reconnect2);
1734 torture_suite_add_1smb2_test(suite, "reauth1", test_session_reauth1);
1735 torture_suite_add_1smb2_test(suite, "reauth2", test_session_reauth2);
1736 torture_suite_add_1smb2_test(suite, "reauth3", test_session_reauth3);
1737 torture_suite_add_1smb2_test(suite, "reauth4", test_session_reauth4);
1738 torture_suite_add_1smb2_test(suite, "reauth5", test_session_reauth5);
1739 torture_suite_add_1smb2_test(suite, "reauth6", test_session_reauth6);
1740 torture_suite_add_simple_test(suite, "expire1s", test_session_expire1s);
1741 torture_suite_add_simple_test(suite, "expire1e", test_session_expire1e);
1742 torture_suite_add_simple_test(suite, "expire2s", test_session_expire2s);
1743 torture_suite_add_simple_test(suite, "expire2e", test_session_expire2e);
1744 torture_suite_add_1smb2_test(suite, "bind1", test_session_bind1);
1746 suite->description = talloc_strdup(suite, "SMB2-SESSION tests");