diff --git a/selftest/knownfail.d/samba3.smb2.session b/selftest/knownfail.d/samba3.smb2.session new file mode 100644 index 00000000000..1ef3605d6b8 --- /dev/null +++ b/selftest/knownfail.d/samba3.smb2.session @@ -0,0 +1,2 @@ +^samba3.smb2.session krb5.expire_disconnect\(ad_dc\) +^samba3.smb2.session krb5.expire_disconnect\(ad_member\) diff --git a/source4/torture/smb2/session.c b/source4/torture/smb2/session.c index 57a5addcfcc..3917e0c09c4 100644 --- a/source4/torture/smb2/session.c +++ b/source4/torture/smb2/session.c @@ -1596,6 +1596,114 @@ static bool test_session_expire2e(struct torture_context *tctx) true); /* force_encryption */ } +static bool test_session_expire_disconnect(struct torture_context *tctx) +{ + NTSTATUS status; + bool ret = false; + struct smbcli_options options; + const char *host = torture_setting_string(tctx, "host", NULL); + const char *share = torture_setting_string(tctx, "share", NULL); + struct cli_credentials *credentials = popt_get_cmdline_credentials(); + struct smb2_tree *tree = NULL; + enum credentials_use_kerberos use_kerberos; + char fname[256]; + struct smb2_handle _h1; + struct smb2_handle *h1 = NULL; + struct smb2_create io1; + union smb_fileinfo qfinfo; + bool connected; + + use_kerberos = cli_credentials_get_kerberos_state(credentials); + if (use_kerberos != CRED_MUST_USE_KERBEROS) { + torture_warning(tctx, "smb2.session.expire1 requires -k yes!"); + torture_skip(tctx, "smb2.session.expire1 requires -k yes!"); + } + + cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); + + lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4"); + lpcfg_smbcli_options(tctx->lp_ctx, &options); + options.signing = SMB_SIGNING_REQUIRED; + + status = smb2_connect(tctx, + host, + lpcfg_smb_ports(tctx->lp_ctx), + share, + lpcfg_resolve_context(tctx->lp_ctx), + credentials, + &tree, + tctx->ev, + &options, + lpcfg_socket_options(tctx->lp_ctx), + lpcfg_gensec_settings(tctx, tctx->lp_ctx) + ); + torture_assert_ntstatus_ok_goto(tctx, status, ret, done, + "smb2_connect failed"); + + smbXcli_session_set_disconnect_expired(tree->session->smbXcli); + + /* Add some random component to the file name. */ + snprintf(fname, sizeof(fname), "session_expire1_%s.dat", + generate_random_str(tctx, 8)); + + smb2_util_unlink(tree, fname); + + smb2_oplock_create_share(&io1, fname, + smb2_util_share_access(""), + smb2_util_oplock_level("b")); + io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE; + + status = smb2_create(tree, tctx, &io1); + torture_assert_ntstatus_ok_goto(tctx, status, ret, done, + "smb2_create failed"); + _h1 = io1.out.file.handle; + h1 = &_h1; + CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE); + torture_assert_int_equal(tctx, io1.out.oplock_level, + smb2_util_oplock_level("b"), + "oplock_level incorrect"); + + /* get the security descriptor */ + + ZERO_STRUCT(qfinfo); + + qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; + qfinfo.access_information.in.file.handle = _h1; + + torture_comment(tctx, "query info => OK\n"); + + ZERO_STRUCT(qfinfo.access_information.out); + status = smb2_getinfo_file(tree, tctx, &qfinfo); + torture_assert_ntstatus_ok_goto(tctx, status, ret, done, + "smb2_getinfo_file failed"); + + torture_comment(tctx, "sleep 10 seconds\n"); + smb_msleep(10*1000); + + torture_comment(tctx, "query info => EXPIRED\n"); + ZERO_STRUCT(qfinfo.access_information.out); + status = smb2_getinfo_file(tree, tctx, &qfinfo); + torture_assert_ntstatus_equal_goto(tctx, status, + NT_STATUS_NETWORK_SESSION_EXPIRED, + ret, done, "smb2_getinfo_file " + "returned unexpected status"); + + connected = smbXcli_conn_is_connected(tree->session->transport->conn); + torture_assert_goto(tctx, !connected, ret, done, "connected\n"); + + ret = true; +done: + cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); + + if (h1 != NULL) { + smb2_util_close(tree, *h1); + } + + talloc_free(tree); + lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0"); + return ret; +} + bool test_session_bind1(struct torture_context *tctx, struct smb2_tree *tree1) { const char *host = torture_setting_string(tctx, "host", NULL); @@ -1754,6 +1862,8 @@ struct torture_suite *torture_smb2_session_init(TALLOC_CTX *ctx) torture_suite_add_simple_test(suite, "expire1e", test_session_expire1e); torture_suite_add_simple_test(suite, "expire2s", test_session_expire2s); torture_suite_add_simple_test(suite, "expire2e", test_session_expire2e); + torture_suite_add_simple_test(suite, "expire_disconnect", + test_session_expire_disconnect); torture_suite_add_1smb2_test(suite, "bind1", test_session_bind1); suite->description = talloc_strdup(suite, "SMB2-SESSION tests");