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_expire1(struct torture_context
*tctx
)
1053 struct smbcli_options options
;
1054 const char *host
= torture_setting_string(tctx
, "host", NULL
);
1055 const char *share
= torture_setting_string(tctx
, "share", NULL
);
1056 struct cli_credentials
*credentials
= popt_get_cmdline_credentials();
1057 struct smb2_tree
*tree
= NULL
;
1058 enum credentials_use_kerberos use_kerberos
;
1060 struct smb2_handle _h1
;
1061 struct smb2_handle
*h1
= NULL
;
1062 struct smb2_create io1
;
1063 union smb_fileinfo qfinfo
;
1066 use_kerberos
= cli_credentials_get_kerberos_state(credentials
);
1067 if (use_kerberos
!= CRED_MUST_USE_KERBEROS
) {
1068 torture_warning(tctx
, "smb2.session.expire1 requires -k yes!");
1069 torture_skip(tctx
, "smb2.session.expire1 requires -k yes!");
1072 torture_assert_int_equal(tctx
, use_kerberos
, CRED_MUST_USE_KERBEROS
,
1073 "please use -k yes");
1075 lpcfg_set_option(tctx
->lp_ctx
, "gensec_gssapi:requested_life_time=4");
1077 lpcfg_smbcli_options(tctx
->lp_ctx
, &options
);
1079 status
= smb2_connect(tctx
,
1081 lpcfg_smb_ports(tctx
->lp_ctx
),
1083 lpcfg_resolve_context(tctx
->lp_ctx
),
1088 lpcfg_socket_options(tctx
->lp_ctx
),
1089 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
)
1091 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1092 "smb2_connect failed");
1094 /* Add some random component to the file name. */
1095 snprintf(fname
, sizeof(fname
), "session_expire1_%s.dat",
1096 generate_random_str(tctx
, 8));
1098 smb2_util_unlink(tree
, fname
);
1100 smb2_oplock_create_share(&io1
, fname
,
1101 smb2_util_share_access(""),
1102 smb2_util_oplock_level("b"));
1103 io1
.in
.create_options
|= NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
1105 status
= smb2_create(tree
, tctx
, &io1
);
1106 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1107 "smb2_create failed");
1108 _h1
= io1
.out
.file
.handle
;
1110 CHECK_CREATED(tctx
, &io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
1111 torture_assert_int_equal(tctx
, io1
.out
.oplock_level
,
1112 smb2_util_oplock_level("b"),
1113 "oplock_level incorrect");
1115 /* get the security descriptor */
1117 ZERO_STRUCT(qfinfo
);
1119 qfinfo
.access_information
.level
= RAW_FILEINFO_ACCESS_INFORMATION
;
1120 qfinfo
.access_information
.in
.file
.handle
= _h1
;
1122 for (i
=0; i
< 2; i
++) {
1123 torture_comment(tctx
, "query info => OK\n");
1125 ZERO_STRUCT(qfinfo
.access_information
.out
);
1126 status
= smb2_getinfo_file(tree
, tctx
, &qfinfo
);
1127 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1128 "smb2_getinfo_file failed");
1130 torture_comment(tctx
, "sleep 10 seconds\n");
1131 smb_msleep(10*1000);
1133 torture_comment(tctx
, "query info => EXPIRED\n");
1134 ZERO_STRUCT(qfinfo
.access_information
.out
);
1135 status
= smb2_getinfo_file(tree
, tctx
, &qfinfo
);
1136 torture_assert_ntstatus_equal_goto(tctx
, status
,
1137 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1138 ret
, done
, "smb2_getinfo_file "
1139 "returned unexpected status");
1142 * the krb5 library may not handle expired creds
1143 * well, lets start with an empty ccache.
1145 cli_credentials_invalidate_ccache(credentials
, CRED_SPECIFIED
);
1147 torture_comment(tctx
, "reauth => OK\n");
1148 status
= smb2_session_setup_spnego(tree
->session
,
1150 0 /* previous_session_id */);
1151 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1152 "smb2_session_setup_spnego failed");
1155 ZERO_STRUCT(qfinfo
.access_information
.out
);
1156 status
= smb2_getinfo_file(tree
, tctx
, &qfinfo
);
1157 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1158 "smb2_getinfo_file failed");
1163 smb2_util_close(tree
, *h1
);
1167 lpcfg_set_option(tctx
->lp_ctx
, "gensec_gssapi:requested_life_time=0");
1171 static bool test_session_expire2(struct torture_context
*tctx
)
1175 struct smbcli_options options
;
1176 const char *host
= torture_setting_string(tctx
, "host", NULL
);
1177 const char *share
= torture_setting_string(tctx
, "share", NULL
);
1178 struct cli_credentials
*credentials
= popt_get_cmdline_credentials();
1179 struct smb2_tree
*tree
= NULL
;
1180 const char *unc
= NULL
;
1181 struct smb2_tree
*tree2
= NULL
;
1182 struct tevent_req
*subreq
= NULL
;
1183 uint32_t timeout_msec
;
1184 enum credentials_use_kerberos use_kerberos
;
1187 struct smb2_handle dh
;
1188 struct smb2_handle dh2
;
1189 struct smb2_handle _h1
;
1190 struct smb2_handle
*h1
= NULL
;
1191 struct smb2_create io1
;
1192 union smb_fileinfo qfinfo
;
1193 union smb_setfileinfo sfinfo
;
1194 struct smb2_flush flsh
;
1195 struct smb2_read rd
;
1196 const uint8_t wd
= 0;
1197 struct smb2_lock lck
;
1198 struct smb2_lock_element el
;
1199 struct smb2_ioctl ctl
;
1200 struct smb2_break oack
;
1201 struct smb2_lease_break_ack lack
;
1202 struct smb2_find fnd
;
1203 union smb_search_data
*d
= NULL
;
1205 struct smb2_request
*req
= NULL
;
1206 struct smb2_notify ntf1
;
1207 struct smb2_notify ntf2
;
1209 use_kerberos
= cli_credentials_get_kerberos_state(credentials
);
1210 if (use_kerberos
!= CRED_MUST_USE_KERBEROS
) {
1211 torture_warning(tctx
, "smb2.session.expire2 requires -k yes!");
1212 torture_skip(tctx
, "smb2.session.expire2 requires -k yes!");
1215 torture_assert_int_equal(tctx
, use_kerberos
, CRED_MUST_USE_KERBEROS
,
1216 "please use -k yes");
1218 lpcfg_set_option(tctx
->lp_ctx
, "gensec_gssapi:requested_life_time=4");
1220 lpcfg_smbcli_options(tctx
->lp_ctx
, &options
);
1222 unc
= talloc_asprintf(tctx
, "\\\\%s\\%s", host
, share
);
1223 torture_assert(tctx
, unc
!= NULL
, "talloc_asprintf");
1225 status
= smb2_connect(tctx
,
1227 lpcfg_smb_ports(tctx
->lp_ctx
),
1229 lpcfg_resolve_context(tctx
->lp_ctx
),
1234 lpcfg_socket_options(tctx
->lp_ctx
),
1235 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
)
1237 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1238 "smb2_connect failed");
1240 caps
= smb2cli_conn_server_capabilities(tree
->session
->transport
->conn
);
1242 /* Add some random component to the file name. */
1243 snprintf(fname
, sizeof(fname
), "session_expire2_%s.dat",
1244 generate_random_str(tctx
, 8));
1246 smb2_util_unlink(tree
, fname
);
1248 status
= smb2_util_roothandle(tree
, &dh
);
1249 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1250 "smb2_util_roothandle failed");
1252 smb2_oplock_create_share(&io1
, fname
,
1253 smb2_util_share_access(""),
1254 smb2_util_oplock_level("b"));
1255 io1
.in
.create_options
|= NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
1257 status
= smb2_create(tree
, tctx
, &io1
);
1258 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1259 "smb2_create failed");
1260 _h1
= io1
.out
.file
.handle
;
1262 CHECK_CREATED(tctx
, &io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
1263 torture_assert_int_equal(tctx
, io1
.out
.oplock_level
,
1264 smb2_util_oplock_level("b"),
1265 "oplock_level incorrect");
1267 /* get the security descriptor */
1269 ZERO_STRUCT(qfinfo
);
1271 qfinfo
.access_information
.level
= RAW_FILEINFO_ACCESS_INFORMATION
;
1272 qfinfo
.access_information
.in
.file
.handle
= _h1
;
1274 torture_comment(tctx
, "query info => OK\n");
1276 ZERO_STRUCT(qfinfo
.access_information
.out
);
1277 status
= smb2_getinfo_file(tree
, tctx
, &qfinfo
);
1278 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1279 "smb2_getinfo_file failed");
1281 torture_comment(tctx
, "lock => OK\n");
1284 lck
.in
.lock_count
= 0x0001;
1285 lck
.in
.lock_sequence
= 0x00000000;
1286 lck
.in
.file
.handle
= *h1
;
1288 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1289 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1290 el
.offset
= 0x0000000000000000;
1291 el
.length
= 0x0000000000000001;
1292 status
= smb2_lock(tree
, &lck
);
1293 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1294 "smb2_lock lock failed");
1296 torture_comment(tctx
, "1st notify => PENDING\n");
1298 ntf1
.in
.file
.handle
= dh
;
1299 ntf1
.in
.recursive
= 0x0000;
1300 ntf1
.in
.buffer_size
= 128;
1301 ntf1
.in
.completion_filter
= FILE_NOTIFY_CHANGE_ATTRIBUTES
;
1302 ntf1
.in
.unknown
= 0x00000000;
1303 req
= smb2_notify_send(tree
, &ntf1
);
1305 while (!req
->cancel
.can_cancel
&& req
->state
<= SMB2_REQUEST_RECV
) {
1306 if (tevent_loop_once(tctx
->ev
) != 0) {
1311 torture_assert_goto(tctx
, req
->state
<= SMB2_REQUEST_RECV
, ret
, done
,
1312 "smb2_notify finished");
1314 torture_comment(tctx
, "sleep 10 seconds\n");
1315 smb_msleep(10*1000);
1317 torture_comment(tctx
, "query info => EXPIRED\n");
1318 ZERO_STRUCT(qfinfo
.access_information
.out
);
1319 status
= smb2_getinfo_file(tree
, tctx
, &qfinfo
);
1320 torture_assert_ntstatus_equal_goto(tctx
, status
,
1321 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1322 ret
, done
, "smb2_getinfo_file "
1323 "returned unexpected status");
1326 torture_comment(tctx
, "set info => EXPIRED\n");
1327 ZERO_STRUCT(sfinfo
);
1328 sfinfo
.end_of_file_info
.level
= RAW_SFILEINFO_END_OF_FILE_INFORMATION
;
1329 sfinfo
.end_of_file_info
.in
.file
.handle
= *h1
;
1330 sfinfo
.end_of_file_info
.in
.size
= 1;
1331 status
= smb2_setinfo_file(tree
, &sfinfo
);
1332 torture_assert_ntstatus_equal_goto(tctx
, status
,
1333 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1334 ret
, done
, "smb2_setinfo_file "
1335 "returned unexpected status");
1337 torture_comment(tctx
, "flush => EXPIRED\n");
1339 flsh
.in
.file
.handle
= *h1
;
1340 status
= smb2_flush(tree
, &flsh
);
1341 torture_assert_ntstatus_equal_goto(tctx
, status
,
1342 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1343 ret
, done
, "smb2_flush "
1344 "returned unexpected status");
1346 torture_comment(tctx
, "read => EXPIRED\n");
1348 rd
.in
.file
.handle
= *h1
;
1351 status
= smb2_read(tree
, tctx
, &rd
);
1352 torture_assert_ntstatus_equal_goto(tctx
, status
,
1353 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1354 ret
, done
, "smb2_read "
1355 "returned unexpected status");
1357 torture_comment(tctx
, "write => EXPIRED\n");
1358 status
= smb2_util_write(tree
, *h1
, &wd
, 0, 1);
1359 torture_assert_ntstatus_equal_goto(tctx
, status
,
1360 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1361 ret
, done
, "smb2_util_write "
1362 "returned unexpected status");
1364 torture_comment(tctx
, "ioctl => EXPIRED\n");
1366 ctl
.in
.file
.handle
= *h1
;
1367 ctl
.in
.function
= FSCTL_SRV_ENUM_SNAPS
;
1368 ctl
.in
.max_response_size
= 16;
1369 ctl
.in
.flags
= SMB2_IOCTL_FLAG_IS_FSCTL
;
1370 status
= smb2_ioctl(tree
, tctx
, &ctl
);
1371 torture_assert_ntstatus_equal_goto(tctx
, status
,
1372 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1373 ret
, done
, "smb2_ioctl "
1374 "returned unexpected status");
1376 torture_comment(tctx
, "oplock ack => EXPIRED\n");
1378 oack
.in
.file
.handle
= *h1
;
1379 status
= smb2_break(tree
, &oack
);
1380 torture_assert_ntstatus_equal_goto(tctx
, status
,
1381 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1382 ret
, done
, "smb2_break "
1383 "returned unexpected status");
1385 if (caps
& SMB2_CAP_LEASING
) {
1386 torture_comment(tctx
, "lease ack => EXPIRED\n");
1388 lack
.in
.lease
.lease_version
= 1;
1389 lack
.in
.lease
.lease_key
.data
[0] = 1;
1390 lack
.in
.lease
.lease_key
.data
[1] = 2;
1391 status
= smb2_lease_break_ack(tree
, &lack
);
1392 torture_assert_ntstatus_equal_goto(tctx
, status
,
1393 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1394 ret
, done
, "smb2_break "
1395 "returned unexpected status");
1398 torture_comment(tctx
, "query directory => EXPIRED\n");
1400 fnd
.in
.file
.handle
= dh
;
1401 fnd
.in
.pattern
= "*";
1402 fnd
.in
.continue_flags
= SMB2_CONTINUE_FLAG_SINGLE
;
1403 fnd
.in
.max_response_size
= 0x100;
1404 fnd
.in
.level
= SMB2_FIND_BOTH_DIRECTORY_INFO
;
1405 status
= smb2_find_level(tree
, tree
, &fnd
, &count
, &d
);
1406 torture_assert_ntstatus_equal_goto(tctx
, status
,
1407 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1408 ret
, done
, "smb2_find_level "
1409 "returned unexpected status");
1411 torture_comment(tctx
, "1st notify => CANCEL\n");
1414 torture_comment(tctx
, "2nd notify => EXPIRED\n");
1416 ntf2
.in
.file
.handle
= dh
;
1417 ntf2
.in
.recursive
= 0x0000;
1418 ntf2
.in
.buffer_size
= 128;
1419 ntf2
.in
.completion_filter
= FILE_NOTIFY_CHANGE_ATTRIBUTES
;
1420 ntf2
.in
.unknown
= 0x00000000;
1421 status
= smb2_notify(tree
, tctx
, &ntf2
);
1422 torture_assert_ntstatus_equal_goto(tctx
, status
,
1423 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1424 ret
, done
, "smb2_notify "
1425 "returned unexpected status");
1427 torture_assert_goto(tctx
, req
->state
> SMB2_REQUEST_RECV
, ret
, done
,
1428 "smb2_notify (1st) not finished");
1430 status
= smb2_notify_recv(req
, tctx
, &ntf1
);
1431 torture_assert_ntstatus_equal_goto(tctx
, status
,
1432 NT_STATUS_CANCELLED
,
1433 ret
, done
, "smb2_notify cancelled"
1434 "returned unexpected status");
1436 torture_comment(tctx
, "tcon => EXPIRED\n");
1437 tree2
= smb2_tree_init(tree
->session
, tctx
, false);
1438 torture_assert(tctx
, tree2
!= NULL
, "smb2_tree_init");
1439 timeout_msec
= tree
->session
->transport
->options
.request_timeout
* 1000;
1440 subreq
= smb2cli_tcon_send(tree2
, tctx
->ev
,
1441 tree2
->session
->transport
->conn
,
1443 tree2
->session
->smbXcli
,
1447 torture_assert(tctx
, subreq
!= NULL
, "smb2cli_tcon_send");
1448 torture_assert(tctx
,
1449 tevent_req_poll_ntstatus(subreq
, tctx
->ev
, &status
),
1450 "tevent_req_poll_ntstatus");
1451 status
= smb2cli_tcon_recv(subreq
);
1452 TALLOC_FREE(subreq
);
1453 torture_assert_ntstatus_equal_goto(tctx
, status
,
1454 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1455 ret
, done
, "smb2cli_tcon"
1456 "returned unexpected status");
1458 torture_comment(tctx
, "create => EXPIRED\n");
1459 status
= smb2_util_roothandle(tree
, &dh2
);
1460 torture_assert_ntstatus_equal_goto(tctx
, status
,
1461 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1462 ret
, done
, "smb2_util_roothandle"
1463 "returned unexpected status");
1465 torture_comment(tctx
, "tdis => EXPIRED\n");
1466 status
= smb2_tdis(tree
);
1467 torture_assert_ntstatus_equal_goto(tctx
, status
,
1468 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1469 ret
, done
, "smb2cli_tdis"
1470 "returned unexpected status");
1473 * (Un)Lock, Close and Logoff are still possible
1476 torture_comment(tctx
, "1st unlock => OK\n");
1477 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
1478 status
= smb2_lock(tree
, &lck
);
1479 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1480 "smb2_lock unlock failed");
1482 torture_comment(tctx
, "2nd unlock => RANGE_NOT_LOCKED\n");
1483 status
= smb2_lock(tree
, &lck
);
1484 torture_assert_ntstatus_equal_goto(tctx
, status
,
1485 NT_STATUS_RANGE_NOT_LOCKED
,
1486 ret
, done
, "smb2_lock 2nd unlock"
1487 "returned unexpected status");
1489 torture_comment(tctx
, "lock => EXPIRED\n");
1490 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1491 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1492 status
= smb2_lock(tree
, &lck
);
1493 torture_assert_ntstatus_equal_goto(tctx
, status
,
1494 NT_STATUS_NETWORK_SESSION_EXPIRED
,
1495 ret
, done
, "smb2_util_roothandle"
1496 "returned unexpected status");
1498 torture_comment(tctx
, "close => OK\n");
1499 status
= smb2_util_close(tree
, *h1
);
1501 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1502 "smb2_close failed");
1504 torture_comment(tctx
, "echo without session => OK\n");
1505 status
= smb2_keepalive(tree
->session
->transport
);
1506 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1507 "smb2_keepalive without session failed");
1509 torture_comment(tctx
, "echo with session => OK\n");
1510 req
= smb2_keepalive_send(tree
->session
->transport
, tree
->session
);
1511 status
= smb2_keepalive_recv(req
);
1512 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1513 "smb2_keepalive with session failed");
1515 torture_comment(tctx
, "logoff => OK\n");
1516 status
= smb2_logoff(tree
->session
);
1517 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1518 "smb2_logoff failed");
1523 smb2_util_close(tree
, *h1
);
1527 lpcfg_set_option(tctx
->lp_ctx
, "gensec_gssapi:requested_life_time=0");
1531 bool test_session_bind1(struct torture_context
*tctx
, struct smb2_tree
*tree1
)
1533 const char *host
= torture_setting_string(tctx
, "host", NULL
);
1534 const char *share
= torture_setting_string(tctx
, "share", NULL
);
1535 struct cli_credentials
*credentials
= popt_get_cmdline_credentials();
1537 TALLOC_CTX
*mem_ctx
= talloc_new(tctx
);
1539 struct smb2_handle _h1
;
1540 struct smb2_handle
*h1
= NULL
;
1541 struct smb2_create io1
;
1542 union smb_fileinfo qfinfo
;
1544 struct smb2_tree
*tree2
= NULL
;
1545 struct smb2_transport
*transport1
= tree1
->session
->transport
;
1546 struct smb2_transport
*transport2
= NULL
;
1547 struct smb2_session
*session1_1
= tree1
->session
;
1548 struct smb2_session
*session1_2
= NULL
;
1549 struct smb2_session
*session2_1
= NULL
;
1550 struct smb2_session
*session2_2
= NULL
;
1553 caps
= smb2cli_conn_server_capabilities(transport1
->conn
);
1554 if (!(caps
& SMB2_CAP_MULTI_CHANNEL
)) {
1555 torture_skip(tctx
, "server doesn't support SMB2_CAP_MULTI_CHANNEL\n");
1558 /* Add some random component to the file name. */
1559 snprintf(fname
, sizeof(fname
), "session_bind1_%s.dat",
1560 generate_random_str(tctx
, 8));
1562 smb2_util_unlink(tree1
, fname
);
1564 smb2_oplock_create_share(&io1
, fname
,
1565 smb2_util_share_access(""),
1566 smb2_util_oplock_level("b"));
1568 status
= smb2_create(tree1
, mem_ctx
, &io1
);
1569 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1570 "smb2_create failed");
1571 _h1
= io1
.out
.file
.handle
;
1573 CHECK_CREATED(tctx
, &io1
, CREATED
, FILE_ATTRIBUTE_ARCHIVE
);
1574 torture_assert_int_equal(tctx
, io1
.out
.oplock_level
,
1575 smb2_util_oplock_level("b"),
1576 "oplock_level incorrect");
1578 status
= smb2_connect(tctx
,
1580 lpcfg_smb_ports(tctx
->lp_ctx
),
1582 lpcfg_resolve_context(tctx
->lp_ctx
),
1586 &transport1
->options
,
1587 lpcfg_socket_options(tctx
->lp_ctx
),
1588 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
)
1590 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1591 "smb2_connect failed");
1592 session2_2
= tree2
->session
;
1593 transport2
= tree2
->session
->transport
;
1596 * Now bind the 2nd transport connection to the 1st session
1598 session1_2
= smb2_session_channel(transport2
,
1599 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
),
1602 torture_assert(tctx
, session1_2
!= NULL
, "smb2_session_channel failed");
1604 status
= smb2_session_setup_spnego(session1_2
,
1605 popt_get_cmdline_credentials(),
1606 0 /* previous_session_id */);
1607 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1608 "smb2_session_setup_spnego failed");
1610 /* use the 1st connection, 1st session */
1611 ZERO_STRUCT(qfinfo
);
1612 qfinfo
.generic
.level
= RAW_FILEINFO_POSITION_INFORMATION
;
1613 qfinfo
.generic
.in
.file
.handle
= _h1
;
1614 tree1
->session
= session1_1
;
1615 status
= smb2_getinfo_file(tree1
, mem_ctx
, &qfinfo
);
1616 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1617 "smb2_getinfo_file failed");
1619 /* use the 2nd connection, 1st session */
1620 ZERO_STRUCT(qfinfo
);
1621 qfinfo
.generic
.level
= RAW_FILEINFO_POSITION_INFORMATION
;
1622 qfinfo
.generic
.in
.file
.handle
= _h1
;
1623 tree1
->session
= session1_2
;
1624 status
= smb2_getinfo_file(tree1
, mem_ctx
, &qfinfo
);
1625 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1626 "smb2_getinfo_file failed");
1628 tree1
->session
= session1_1
;
1629 status
= smb2_util_close(tree1
, *h1
);
1630 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1631 "smb2_util_close failed");
1635 * Now bind the 1st transport connection to the 2nd session
1637 session2_1
= smb2_session_channel(transport1
,
1638 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
),
1641 torture_assert(tctx
, session2_1
!= NULL
, "smb2_session_channel failed");
1643 status
= smb2_session_setup_spnego(session2_1
,
1644 popt_get_cmdline_credentials(),
1645 0 /* previous_session_id */);
1646 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1647 "smb2_session_setup_spnego failed");
1649 tree2
->session
= session2_1
;
1650 status
= smb2_util_unlink(tree2
, fname
);
1651 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
1652 "smb2_util_unlink failed");
1656 tree1
->session
= session1_1
;
1659 smb2_util_close(tree1
, *h1
);
1662 smb2_util_unlink(tree1
, fname
);
1666 talloc_free(mem_ctx
);
1671 struct torture_suite
*torture_smb2_session_init(TALLOC_CTX
*ctx
)
1673 struct torture_suite
*suite
=
1674 torture_suite_create(ctx
, "session");
1676 torture_suite_add_1smb2_test(suite
, "reconnect1", test_session_reconnect1
);
1677 torture_suite_add_1smb2_test(suite
, "reconnect2", test_session_reconnect2
);
1678 torture_suite_add_1smb2_test(suite
, "reauth1", test_session_reauth1
);
1679 torture_suite_add_1smb2_test(suite
, "reauth2", test_session_reauth2
);
1680 torture_suite_add_1smb2_test(suite
, "reauth3", test_session_reauth3
);
1681 torture_suite_add_1smb2_test(suite
, "reauth4", test_session_reauth4
);
1682 torture_suite_add_1smb2_test(suite
, "reauth5", test_session_reauth5
);
1683 torture_suite_add_1smb2_test(suite
, "reauth6", test_session_reauth6
);
1684 torture_suite_add_simple_test(suite
, "expire1", test_session_expire1
);
1685 torture_suite_add_simple_test(suite
, "expire2", test_session_expire2
);
1686 torture_suite_add_1smb2_test(suite
, "bind1", test_session_bind1
);
1688 suite
->description
= talloc_strdup(suite
, "SMB2-SESSION tests");