[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Thu Dec 21 22:29:02 UTC 2017


The branch, master has been updated
       via  c4919d4 s3:smb2_server: allow logoff, close, unlock, cancel and echo on expired sessions
       via  cfaba68 s3:smbd: return the correct error for cancelled SMB2 notifies on expired sessions
       via  f60af3b s4:torture: add smb2.session.expire2 test
       via  ca289d4 torture: Fix a typo
       via  75e7da9 sysacls: change datatypes to 32 bits
       via  d6f5ee6 pysmbd: fix use of sysacl API
      from  6a6f095 samba-tool domain schemaupgrade: Avoid reindex after every hunk

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit c4919d4d5f78aeb54a438b95d4eab2f082a8174e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Dec 20 14:05:54 2017 +0100

    s3:smb2_server: allow logoff, close, unlock, cancel and echo on expired sessions
    
    Windows client at least doesn't have code to replay
    a SMB2 Close after getting NETWORK_SESSION_EXPIRED,
    which locks out a the client and generates an endless
    loop around NT_STATUS_SHARING_VIOLATION.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13197
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Thu Dec 21 23:28:42 CET 2017 on sn-devel-144

commit cfaba684785529d656138df454165aa08a775a01
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Dec 21 14:47:06 2017 +0100

    s3:smbd: return the correct error for cancelled SMB2 notifies on expired sessions
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13197
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f60af3b61c4a374d7d1c575049a932d1824489b6
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Dec 21 12:53:02 2017 +0100

    s4:torture: add smb2.session.expire2 test
    
    This demonstrates the interaction of NT_STATUS_NETWORK_SESSION_EXPIRED
    and various SMB2 opcodes.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13197
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit ca289d4d14556736c1ac77936c94d365618f33e5
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 21 11:01:18 2017 +0100

    torture: Fix a typo
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Richard Sharpe <realrichardsharpe at gmail.com>

commit 75e7da9741c529f96fa409655ac5b326a6c071c5
Author: Uri Simchoni <uri at samba.org>
Date:   Tue Dec 5 20:56:49 2017 +0200

    sysacls: change datatypes to 32 bits
    
    The SMB_ACL_PERMSET_T and SMB_ACL_PERM_T were defined as
    mode_t, which is 16-bits on some (non-Linux) systems. However,
    pidl *always* encodes mode_t as uint32_t. That created a bug on
    big-endian systems as sys_acl_get_permset() returns a SMB_ACL_PERMSET_T
    pointer to an internal a_perm structure member defined in IDL as a mode_t,
    which pidl turns into a uin32_t in the emitted header file.
    
    Changing to 32 bits fixes that.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13176
    
    Signed-off-by: Uri Simchoni <uri at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit d6f5ee6707fa5404e2bef6fc81ae06b393ebd8ff
Author: Uri Simchoni <uri at samba.org>
Date:   Tue Dec 5 20:49:03 2017 +0200

    pysmbd: fix use of sysacl API
    
    Fix pysmbd to use the sysacl (POSIX ACL support) as intended, and
    not assume too much about the inner structure and implementation
    of the permissions in the sysacl API.
    
    This will allow the inner structure to change in a following commit.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13176
    
    Signed-off-by: Uri Simchoni <uri at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/include/smb_acls.h      |  10 +-
 source3/smbd/notify.c           |  17 +-
 source3/smbd/pysmbd.c           |  43 ++++-
 source3/smbd/smb2_lock.c        |  17 ++
 source3/smbd/smb2_server.c      |  19 +++
 source4/libcli/smb2/keepalive.c |   7 +-
 source4/torture/smb2/session.c  | 364 +++++++++++++++++++++++++++++++++++++++-
 7 files changed, 463 insertions(+), 14 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/smb_acls.h b/source3/include/smb_acls.h
index 73b67af..c5a2339 100644
--- a/source3/include/smb_acls.h
+++ b/source3/include/smb_acls.h
@@ -27,8 +27,14 @@ struct files_struct;
 struct smb_filename;
 
 typedef int			SMB_ACL_TYPE_T;
-typedef mode_t			*SMB_ACL_PERMSET_T;
-typedef mode_t			SMB_ACL_PERM_T;
+/*
+ * struct smb_acl_entry is defined in IDL as
+ * using mode_t values, pidl always converts these
+ * to uint32_t. Ensure the external type definitions
+ * match.
+ */
+typedef uint32_t		*SMB_ACL_PERMSET_T;
+typedef uint32_t		SMB_ACL_PERM_T;
 
 typedef enum smb_acl_tag_t SMB_ACL_TAG_T;
 typedef struct smb_acl_t *SMB_ACL_T;
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index f64185d..add5908 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -391,12 +391,21 @@ static void smbd_notify_cancel_by_map(struct notify_mid_map *map)
 	NTSTATUS notify_status = NT_STATUS_CANCELLED;
 
 	if (smb2req != NULL) {
+		NTSTATUS sstatus;
+
 		if (smb2req->session == NULL) {
-			notify_status = STATUS_NOTIFY_CLEANUP;
-		} else if (!NT_STATUS_IS_OK(smb2req->session->status)) {
-			notify_status = STATUS_NOTIFY_CLEANUP;
+			sstatus = NT_STATUS_USER_SESSION_DELETED;
+		} else {
+			sstatus = smb2req->session->status;
 		}
-		if (smb2req->tcon == NULL) {
+
+		if (NT_STATUS_EQUAL(sstatus, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
+			sstatus = NT_STATUS_OK;
+		}
+
+		if (!NT_STATUS_IS_OK(sstatus)) {
+			notify_status = STATUS_NOTIFY_CLEANUP;
+		} else if (smb2req->tcon == NULL) {
 			notify_status = STATUS_NOTIFY_CLEANUP;
 		} else if (!NT_STATUS_IS_OK(smb2req->tcon->status)) {
 			notify_status = STATUS_NOTIFY_CLEANUP;
diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
index 63fc5d6..be30b86 100644
--- a/source3/smbd/pysmbd.c
+++ b/source3/smbd/pysmbd.c
@@ -234,6 +234,39 @@ static NTSTATUS get_nt_acl_conn(TALLOC_CTX *mem_ctx,
 	return status;
 }
 
+static int set_acl_entry_perms(SMB_ACL_ENTRY_T entry, mode_t perm_mask)
+{
+	SMB_ACL_PERMSET_T perms = NULL;
+
+	if (sys_acl_get_permset(entry, &perms) != 0) {
+		return -1;
+	}
+
+	if (sys_acl_clear_perms(perms) != 0) {
+		return -1;
+	}
+
+	if ((perm_mask & SMB_ACL_READ) != 0 &&
+	    sys_acl_add_perm(perms, SMB_ACL_READ) != 0) {
+		return -1;
+	}
+
+	if ((perm_mask & SMB_ACL_WRITE) != 0 &&
+	    sys_acl_add_perm(perms, SMB_ACL_WRITE) != 0) {
+		return -1;
+	}
+
+	if ((perm_mask & SMB_ACL_EXECUTE) != 0 &&
+	    sys_acl_add_perm(perms, SMB_ACL_EXECUTE) != 0) {
+		return -1;
+	}
+
+	if (sys_acl_set_permset(entry, perms) != 0) {
+		return -1;
+	}
+
+	return 0;
+}
 
 static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
 {
@@ -261,7 +294,7 @@ static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
 		return NULL;
 	}
 
-	if (sys_acl_set_permset(entry, &mode_user) != 0) {
+	if (set_acl_entry_perms(entry, mode_user) != 0) {
 		TALLOC_FREE(frame);
 		return NULL;
 	}
@@ -276,7 +309,7 @@ static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
 		return NULL;
 	}
 
-	if (sys_acl_set_permset(entry, &mode_group) != 0) {
+	if (set_acl_entry_perms(entry, mode_group) != 0) {
 		TALLOC_FREE(frame);
 		return NULL;
 	}
@@ -291,7 +324,7 @@ static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
 		return NULL;
 	}
 
-	if (sys_acl_set_permset(entry, &mode_other) != 0) {
+	if (set_acl_entry_perms(entry, mode_other) != 0) {
 		TALLOC_FREE(frame);
 		return NULL;
 	}
@@ -312,7 +345,7 @@ static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
 			return NULL;
 		}
 
-		if (sys_acl_set_permset(entry, &mode_group) != 0) {
+		if (set_acl_entry_perms(entry, mode_group) != 0) {
 			TALLOC_FREE(frame);
 			return NULL;
 		}
@@ -328,7 +361,7 @@ static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
 		return NULL;
 	}
 
-	if (sys_acl_set_permset(entry, &mode) != 0) {
+	if (set_acl_entry_perms(entry, mode) != 0) {
 		TALLOC_FREE(frame);
 		return NULL;
 	}
diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c
index 2fcd359..45b833c 100644
--- a/source3/smbd/smb2_lock.c
+++ b/source3/smbd/smb2_lock.c
@@ -98,6 +98,23 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
 	in_locks[l].flags	= IVAL(lock_buffer, 0x10);
 	/* 0x14 - 4 reserved bytes */
 
+	status = req->session->status;
+	if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
+		/*
+		 * We need to catch NT_STATUS_NETWORK_SESSION_EXPIRED
+		 * for lock requests only.
+		 *
+		 * Unlock requests still need to be processed!
+		 *
+		 * This means smbd_smb2_request_check_session()
+		 * can't handle the difference and always
+		 * allows SMB2_OP_LOCK.
+		 */
+		if (in_locks[0].flags != SMB2_LOCK_FLAG_UNLOCK) {
+			return smbd_smb2_request_error(req, status);
+		}
+	}
+
 	lock_buffer = SMBD_SMB2_IN_DYN_PTR(req);
 
 	for (l=1; l < in_lock_count; l++) {
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 68a024f..5290c05 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -1902,6 +1902,25 @@ static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
 		case SMB2_OP_SESSSETUP:
 			status = NT_STATUS_OK;
 			break;
+		case SMB2_OP_LOGOFF:
+		case SMB2_OP_CLOSE:
+		case SMB2_OP_LOCK:
+		case SMB2_OP_CANCEL:
+		case SMB2_OP_KEEPALIVE:
+			/*
+			 * [MS-SMB2] 3.3.5.2.9 Verifying the Session
+			 * specifies that LOGOFF, CLOSE and (UN)LOCK
+			 * should always be processed even on expired sessions.
+			 *
+			 * Also see the logic in
+			 * smbd_smb2_request_process_lock().
+			 *
+			 * The smb2.session.expire2 test shows that
+			 * CANCEL and KEEPALIVE/ECHO should also
+			 * be processed.
+			 */
+			status = NT_STATUS_OK;
+			break;
 		default:
 			break;
 		}
diff --git a/source4/libcli/smb2/keepalive.c b/source4/libcli/smb2/keepalive.c
index 402b063..71004aa14 100644
--- a/source4/libcli/smb2/keepalive.c
+++ b/source4/libcli/smb2/keepalive.c
@@ -26,7 +26,8 @@
 /*
   send a keepalive request
 */
-struct smb2_request *smb2_keepalive_send(struct smb2_transport *transport)
+struct smb2_request *smb2_keepalive_send(struct smb2_transport *transport,
+					 struct smb2_session *session)
 {
 	struct smb2_request *req;
 
@@ -35,6 +36,8 @@ struct smb2_request *smb2_keepalive_send(struct smb2_transport *transport)
 
 	SSVAL(req->out.body, 0x02, 0);
 
+	req->session = session;
+
 	smb2_transport_send(req);
 
 	return req;
@@ -60,6 +63,6 @@ NTSTATUS smb2_keepalive_recv(struct smb2_request *req)
 */
 NTSTATUS smb2_keepalive(struct smb2_transport *transport)
 {
-	struct smb2_request *req = smb2_keepalive_send(transport);
+	struct smb2_request *req = smb2_keepalive_send(transport, NULL);
 	return smb2_keepalive_recv(req);
 }
diff --git a/source4/torture/smb2/session.c b/source4/torture/smb2/session.c
index fca0552..aad8610 100644
--- a/source4/torture/smb2/session.c
+++ b/source4/torture/smb2/session.c
@@ -31,6 +31,7 @@
 #include "libcli/security/security.h"
 #include "libcli/resolve/resolve.h"
 #include "lib/param/param.h"
+#include "lib/util/tevent_ntstatus.h"
 
 #define CHECK_CREATED(tctx, __io, __created, __attribute)			\
 	do {									\
@@ -1148,7 +1149,7 @@ static bool test_session_expire1(struct torture_context *tctx)
 						   credentials,
 						   0 /* previous_session_id */);
 		torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
-					"smb2_session_seutup_spnego failed");
+					"smb2_session_setup_spnego failed");
 	}
 
 	ZERO_STRUCT(qfinfo.access_information.out);
@@ -1167,6 +1168,366 @@ done:
 	return ret;
 }
 
+static bool test_session_expire2(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;
+	const char *unc = NULL;
+	struct smb2_tree *tree2 = NULL;
+	struct tevent_req *subreq = NULL;
+	uint32_t timeout_msec;
+	enum credentials_use_kerberos use_kerberos;
+	uint32_t caps;
+	char fname[256];
+	struct smb2_handle dh;
+	struct smb2_handle dh2;
+	struct smb2_handle _h1;
+	struct smb2_handle *h1 = NULL;
+	struct smb2_create io1;
+	union smb_fileinfo qfinfo;
+	union smb_setfileinfo sfinfo;
+	struct smb2_flush flsh;
+	struct smb2_read rd;
+	const uint8_t wd = 0;
+	struct smb2_lock lck;
+	struct smb2_lock_element el;
+	struct smb2_ioctl ctl;
+	struct smb2_break oack;
+	struct smb2_lease_break_ack lack;
+	struct smb2_find fnd;
+	union smb_search_data *d = NULL;
+	unsigned int count;
+	struct smb2_request *req = NULL;
+	struct smb2_notify ntf1;
+	struct smb2_notify ntf2;
+
+	use_kerberos = cli_credentials_get_kerberos_state(credentials);
+	if (use_kerberos != CRED_MUST_USE_KERBEROS) {
+		torture_warning(tctx, "smb2.session.expire2 requires -k yes!");
+		torture_skip(tctx, "smb2.session.expire2 requires -k yes!");
+	}
+
+	torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS,
+				 "please use -k yes");
+
+	lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");
+
+	lpcfg_smbcli_options(tctx->lp_ctx, &options);
+
+	unc = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
+	torture_assert(tctx, unc != NULL, "talloc_asprintf");
+
+	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");
+
+	caps = smb2cli_conn_server_capabilities(tree->session->transport->conn);
+
+	/* Add some random component to the file name. */
+	snprintf(fname, sizeof(fname), "session_expire2_%s.dat",
+		 generate_random_str(tctx, 8));
+
+	smb2_util_unlink(tree, fname);
+
+	status = smb2_util_roothandle(tree, &dh);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_util_roothandle failed");
+
+	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, "lock => OK\n");
+	ZERO_STRUCT(lck);
+	lck.in.locks		= ⪙
+	lck.in.lock_count	= 0x0001;
+	lck.in.lock_sequence	= 0x00000000;
+	lck.in.file.handle	= *h1;
+	ZERO_STRUCT(el);
+	el.flags		= SMB2_LOCK_FLAG_EXCLUSIVE |
+				  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
+	el.offset		= 0x0000000000000000;
+	el.length		= 0x0000000000000001;
+	status = smb2_lock(tree, &lck);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_lock lock failed");
+
+	torture_comment(tctx, "1st notify => PENDING\n");
+	ZERO_STRUCT(ntf1);
+	ntf1.in.file.handle	= dh;
+	ntf1.in.recursive	= 0x0000;
+	ntf1.in.buffer_size	= 128;
+	ntf1.in.completion_filter= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+	ntf1.in.unknown		= 0x00000000;
+	req = smb2_notify_send(tree, &ntf1);
+
+	while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) {
+		if (tevent_loop_once(tctx->ev) != 0) {
+			break;
+		}
+	}
+
+	torture_assert_goto(tctx, req->state <= SMB2_REQUEST_RECV, ret, done,
+			    "smb2_notify finished");
+
+	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");
+
+
+	torture_comment(tctx, "set info => EXPIRED\n");
+	ZERO_STRUCT(sfinfo);
+	sfinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
+	sfinfo.end_of_file_info.in.file.handle = *h1;
+	sfinfo.end_of_file_info.in.size = 1;
+	status = smb2_setinfo_file(tree, &sfinfo);
+	torture_assert_ntstatus_equal_goto(tctx, status,
+				NT_STATUS_NETWORK_SESSION_EXPIRED,
+				ret, done, "smb2_setinfo_file "
+				"returned unexpected status");
+
+	torture_comment(tctx, "flush => EXPIRED\n");
+	ZERO_STRUCT(flsh);
+	flsh.in.file.handle = *h1;
+	status = smb2_flush(tree, &flsh);
+	torture_assert_ntstatus_equal_goto(tctx, status,
+				NT_STATUS_NETWORK_SESSION_EXPIRED,
+				ret, done, "smb2_flush "
+				"returned unexpected status");
+
+	torture_comment(tctx, "read => EXPIRED\n");
+	ZERO_STRUCT(rd);
+	rd.in.file.handle = *h1;
+	rd.in.length      = 5;
+	rd.in.offset      = 0;
+	status = smb2_read(tree, tctx, &rd);
+	torture_assert_ntstatus_equal_goto(tctx, status,
+				NT_STATUS_NETWORK_SESSION_EXPIRED,
+				ret, done, "smb2_read "
+				"returned unexpected status");
+
+	torture_comment(tctx, "write => EXPIRED\n");
+	status = smb2_util_write(tree, *h1, &wd, 0, 1);
+	torture_assert_ntstatus_equal_goto(tctx, status,
+				NT_STATUS_NETWORK_SESSION_EXPIRED,
+				ret, done, "smb2_util_write "
+				"returned unexpected status");
+
+	torture_comment(tctx, "ioctl => EXPIRED\n");
+	ZERO_STRUCT(ctl);
+	ctl.in.file.handle = *h1;
+	ctl.in.function = FSCTL_SRV_ENUM_SNAPS;
+	ctl.in.max_response_size = 16;
+	ctl.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
+	status = smb2_ioctl(tree, tctx, &ctl);
+	torture_assert_ntstatus_equal_goto(tctx, status,
+				NT_STATUS_NETWORK_SESSION_EXPIRED,
+				ret, done, "smb2_ioctl "
+				"returned unexpected status");
+
+	torture_comment(tctx, "oplock ack => EXPIRED\n");
+	ZERO_STRUCT(oack);
+	oack.in.file.handle = *h1;
+	status = smb2_break(tree, &oack);
+	torture_assert_ntstatus_equal_goto(tctx, status,
+				NT_STATUS_NETWORK_SESSION_EXPIRED,
+				ret, done, "smb2_break "
+				"returned unexpected status");
+
+	if (caps & SMB2_CAP_LEASING) {
+		torture_comment(tctx, "lease ack => EXPIRED\n");
+		ZERO_STRUCT(lack);
+		lack.in.lease.lease_version = 1;
+		lack.in.lease.lease_key.data[0] = 1;
+		lack.in.lease.lease_key.data[0] = 2;
+		status = smb2_lease_break_ack(tree, &lack);
+		torture_assert_ntstatus_equal_goto(tctx, status,
+					NT_STATUS_NETWORK_SESSION_EXPIRED,
+					ret, done, "smb2_break "
+					"returned unexpected status");
+	}
+
+	torture_comment(tctx, "query directory => EXPIRED\n");
+	ZERO_STRUCT(fnd);
+	fnd.in.file.handle	= dh;
+	fnd.in.pattern		= "*";
+	fnd.in.continue_flags	= SMB2_CONTINUE_FLAG_SINGLE;
+	fnd.in.max_response_size= 0x100;
+	fnd.in.level		= SMB2_FIND_BOTH_DIRECTORY_INFO;
+	status = smb2_find_level(tree, tree, &fnd, &count, &d);
+	torture_assert_ntstatus_equal_goto(tctx, status,
+				NT_STATUS_NETWORK_SESSION_EXPIRED,
+				ret, done, "smb2_find_level "
+				"returned unexpected status");
+
+	torture_comment(tctx, "1st notify => CANCEL\n");
+	smb2_cancel(req);
+
+	torture_comment(tctx, "2nd notify => EXPIRED\n");
+	ZERO_STRUCT(ntf2);
+	ntf2.in.file.handle	= dh;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list