s4:torture/smb2/session: test smbXcli_session_set_disconnect_expired() works
authorRalph Boehme <slow@samba.org>
Tue, 13 Nov 2018 11:08:10 +0000 (12:08 +0100)
committerRalph Boehme <slow@samba.org>
Tue, 13 Nov 2018 13:32:15 +0000 (14:32 +0100)
This adds a simple test that verifies that after having set
smbXcli_session_set_disconnect_expired() a session gets disconnected
when it expires.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=9175

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
selftest/knownfail.d/samba3.smb2.session [new file with mode: 0644]
source4/torture/smb2/session.c

diff --git a/selftest/knownfail.d/samba3.smb2.session b/selftest/knownfail.d/samba3.smb2.session
new file mode 100644 (file)
index 0000000..1ef3605
--- /dev/null
@@ -0,0 +1,2 @@
+^samba3.smb2.session krb5.expire_disconnect\(ad_dc\)
+^samba3.smb2.session krb5.expire_disconnect\(ad_member\)
index 57a5addcfcc4201be88afcc0c9c2306f41bdcb3c..3917e0c09c49cbf45ea6797b2d63f4f67d1388e7 100644 (file)
@@ -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");