Patches for https://bugzilla.samba.org/show_bug.cgi?id=11182
Michael Adam
obnox at samba.org
Wed May 6 12:53:38 MDT 2015
On 2015-05-06 at 11:20 -0700, Jeremy Allison wrote:
> On Wed, May 06, 2015 at 02:27:41PM +0200, Stefan (metze) Metzmacher wrote:
> > Hi,
> >
> > here's an updated patchset renaming smbXsrv_session_shutdown_send/recv
> > to smb2srv_session_shutdown_send/recv as it only handles smb2/3.
>
> That's really nice work Metze - thanks ! I like the way
> adding the smbd_smb2_session_setup_wrap_send()/_recv()
> gets rid of the horror that was tag_state_session_ptr() :-).
> Makes the whole sessetup SMB2 code path much cleaner.
Indeed.
> Also moving the code out of smbd_smb2_logoff_send()
> into a common function smb2srv_session_shutdown_send()
> to be called on logoff and session setup error is a
> genius move !
:) Indeed again. The main point here is also that
there is now the queue for the outstanding requests
and we put the cleaning of the session at the end of
this queue.
> LGTM.
>
> Reviewed-by: Jeremy Allison <jra at samba.org>
Now I feel kind of stupid having spent my afternoon
reviewing the patches... ;) When I thought I was done,
Ira brought up one potential issue, the discussion of
which kept me busy until dinner time, which is why I
can only follow up now:
In the session_shutdown helpers mentioned above,
compounded requests are excluded from sending
cancels. Ira points out that when there is a
compounded request in progress, the last of which
is a notify, and we are just at one of the earlier
requests when the shutdown_send is called, isn't
there a chance that we block indefinitely waiting
for the notify to vanish from the queue since it
in the compound and we don't send a cancel?
Attached find my reviewed version of the patchset:
- The session_shutdown helper is flagged with a Q(...)
- I have added some refactoring of an obvious code
duplication added by the patches.
(the removal of the code duplication is still there
as separate patches for squashing with metze's original patches)
- I have done minor changes to some commit messages:
- few typo fixes
- added explanation of the session_shutdown helpers
- added bug references where missing
Cheers - Michael
> > Am 06.05.2015 um 10:19 schrieb Stefan (metze) Metzmacher:
> > > Hi Jeremy,
> > >
> > > here're the proposed patches for master regarding
> > > https://bugzilla.samba.org/show_bug.cgi?id=11182
> > >
> > > The main happens when a session setup with a previous session id
> > > removes the previous session while there's a pending change notify
> > > request.
> > >
> > > Please review and push, then I'll prepare backports.
> > >
> > > Thanks!
> > > metze
> > >
>
> > From d95e3048e480b222348b10d03b3e31dca4443c8a Mon Sep 17 00:00:00 2001
> > From: Stefan Metzmacher <metze at samba.org>
> > Date: Fri, 1 May 2015 20:04:55 +0200
> > Subject: [PATCH 01/17] s3:smbd: add a smbd_notify_cancel_by_map() helper
> > function
> >
> > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > ---
> > source3/smbd/notify.c | 19 +++++++++++++------
> > 1 file changed, 13 insertions(+), 6 deletions(-)
> >
> > diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
> > index 3f2d07c..4f4ca2f 100644
> > --- a/source3/smbd/notify.c
> > +++ b/source3/smbd/notify.c
> > @@ -375,6 +375,17 @@ static void change_notify_remove_request(struct smbd_server_connection *sconn,
> > TALLOC_FREE(req);
> > }
> >
> > +static void smbd_notify_cancel_by_map(struct notify_mid_map *map)
> > +{
> > + struct smb_request *smbreq = map->req->req;
> > + struct smbd_server_connection *sconn = smbreq->sconn;
> > + NTSTATUS notify_status = NT_STATUS_CANCELLED;
> > +
> > + change_notify_reply(smbreq, notify_status,
> > + 0, NULL, map->req->reply_fn);
> > + change_notify_remove_request(sconn, map->req);
> > +}
> > +
> > /****************************************************************************
> > Delete entries by mid from the change notify pending queue. Always send reply.
> > *****************************************************************************/
> > @@ -394,9 +405,7 @@ void remove_pending_change_notify_requests_by_mid(
> > return;
> > }
> >
> > - change_notify_reply(map->req->req,
> > - NT_STATUS_CANCELLED, 0, NULL, map->req->reply_fn);
> > - change_notify_remove_request(sconn, map->req);
> > + smbd_notify_cancel_by_map(map);
> > }
> >
> > void smbd_notify_cancel_by_smbreq(const struct smb_request *smbreq)
> > @@ -414,9 +423,7 @@ void smbd_notify_cancel_by_smbreq(const struct smb_request *smbreq)
> > return;
> > }
> >
> > - change_notify_reply(map->req->req,
> > - NT_STATUS_CANCELLED, 0, NULL, map->req->reply_fn);
> > - change_notify_remove_request(sconn, map->req);
> > + smbd_notify_cancel_by_map(map);
> > }
> >
> > static struct files_struct *smbd_notify_cancel_deleted_fn(
> > --
> > 1.9.1
> >
> >
> > From 227ed247a33728327dc8bd81124c7a0352deef03 Mon Sep 17 00:00:00 2001
> > From: Stefan Metzmacher <metze at samba.org>
> > Date: Fri, 1 May 2015 20:02:38 +0200
> > Subject: [PATCH 02/17] s3:smbd: use STATUS_NOTIFY_CLEANUP when closing a smb2
> > directory handle
> >
> > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > ---
> > selftest/knownfail | 1 -
> > source3/smbd/close.c | 15 +++++++++++----
> > 2 files changed, 11 insertions(+), 5 deletions(-)
> >
> > diff --git a/selftest/knownfail b/selftest/knownfail
> > index 3262c9c..26aed77 100644
> > --- a/selftest/knownfail
> > +++ b/selftest/knownfail
> > @@ -189,7 +189,6 @@
> > ^samba3.smb2.create.blob
> > ^samba3.smb2.create.open
> > ^samba3.smb2.notify.valid-req
> > -^samba3.smb2.notify.dir
> > ^samba3.smb2.notify.rec
> > ^samba3.smb2.durable-open.delete_on_close2
> > ^samba3.smb2.durable-v2-open.app-instance
> > diff --git a/source3/smbd/close.c b/source3/smbd/close.c
> > index 09be2e7..0e75bf0 100644
> > --- a/source3/smbd/close.c
> > +++ b/source3/smbd/close.c
> > @@ -1050,6 +1050,13 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
> > NTSTATUS status1 = NT_STATUS_OK;
> > const struct security_token *del_nt_token = NULL;
> > const struct security_unix_token *del_token = NULL;
> > + NTSTATUS notify_status;
> > +
> > + if (fsp->conn->sconn->using_smb2) {
> > + notify_status = STATUS_NOTIFY_CLEANUP;
> > + } else {
> > + notify_status = NT_STATUS_OK;
> > + }
> >
> > /*
> > * NT can set delete_on_close of the last open
> > @@ -1159,8 +1166,8 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
> > * now fail as the directory has been deleted.
> > */
> >
> > - if(NT_STATUS_IS_OK(status)) {
> > - remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
> > + if (NT_STATUS_IS_OK(status)) {
> > + notify_status = NT_STATUS_DELETE_PENDING;
> > }
> > } else {
> > if (!del_share_mode(lck, fsp)) {
> > @@ -1169,10 +1176,10 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
> > }
> >
> > TALLOC_FREE(lck);
> > - remove_pending_change_notify_requests_by_fid(
> > - fsp, NT_STATUS_OK);
> > }
> >
> > + remove_pending_change_notify_requests_by_fid(fsp, notify_status);
> > +
> > status1 = fd_close(fsp);
> >
> > if (!NT_STATUS_IS_OK(status1)) {
> > --
> > 1.9.1
> >
> >
> > From 8aef6501d53dd38002f1f9531ffd3bacbd5de245 Mon Sep 17 00:00:00 2001
> > From: Stefan Metzmacher <metze at samba.org>
> > Date: Fri, 1 May 2015 20:02:38 +0200
> > Subject: [PATCH 03/17] s3:smbd: use STATUS_NOTIFY_CLEANUP on smb2 logoff
> > (explicit and implicit) and tdis
> >
> > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > ---
> > source3/smbd/notify.c | 14 ++++++++++++++
> > 1 file changed, 14 insertions(+)
> >
> > diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
> > index 4f4ca2f..b3079d2 100644
> > --- a/source3/smbd/notify.c
> > +++ b/source3/smbd/notify.c
> > @@ -379,8 +379,22 @@ static void smbd_notify_cancel_by_map(struct notify_mid_map *map)
> > {
> > struct smb_request *smbreq = map->req->req;
> > struct smbd_server_connection *sconn = smbreq->sconn;
> > + struct smbd_smb2_request *smb2req = smbreq->smb2req;
> > NTSTATUS notify_status = NT_STATUS_CANCELLED;
> >
> > + if (smb2req != NULL) {
> > + if (smb2req->session == NULL) {
> > + notify_status = STATUS_NOTIFY_CLEANUP;
> > + } else if (!NT_STATUS_IS_OK(smb2req->session->status)) {
> > + notify_status = STATUS_NOTIFY_CLEANUP;
> > + }
> > + if (smb2req->tcon == NULL) {
> > + notify_status = STATUS_NOTIFY_CLEANUP;
> > + } else if (!NT_STATUS_IS_OK(smb2req->tcon->status)) {
> > + notify_status = STATUS_NOTIFY_CLEANUP;
> > + }
> > + }
> > +
> > change_notify_reply(smbreq, notify_status,
> > 0, NULL, map->req->reply_fn);
> > change_notify_remove_request(sconn, map->req);
> > --
> > 1.9.1
> >
> >
> > From 3d9590a8ab4b8fee4e35228020ee6a52b2ce6f16 Mon Sep 17 00:00:00 2001
> > From: Stefan Metzmacher <metze at samba.org>
> > Date: Fri, 1 May 2015 20:19:42 +0200
> > Subject: [PATCH 04/17] s4:torture/smb2: verify STATUS_NOTIFY_CLEANUP return
> > value
> >
> > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > ---
> > source4/torture/smb2/notify.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/source4/torture/smb2/notify.c b/source4/torture/smb2/notify.c
> > index 0f572b6..6c1bf3a 100644
> > --- a/source4/torture/smb2/notify.c
> > +++ b/source4/torture/smb2/notify.c
> > @@ -1309,6 +1309,7 @@ static bool torture_smb2_notify_tree_disconnect_1(
> > CHECK_STATUS(status, NT_STATUS_OK);
> >
> > status = smb2_notify_recv(req, torture, &(notify.smb2));
> > + CHECK_STATUS(status, STATUS_NOTIFY_CLEANUP);
> > CHECK_VAL(notify.smb2.out.num_changes, 0);
> >
> > done:
> > @@ -1377,6 +1378,7 @@ static bool torture_smb2_notify_ulogoff(struct torture_context *torture,
> > CHECK_STATUS(status, NT_STATUS_OK);
> >
> > status = smb2_notify_recv(req, torture, &(notify.smb2));
> > + CHECK_STATUS(status, STATUS_NOTIFY_CLEANUP);
> > CHECK_VAL(notify.smb2.out.num_changes, 0);
> >
> > done:
> > --
> > 1.9.1
> >
> >
> > From a19aca28e87629d519b9a0d9d6cca3c0736d0e23 Mon Sep 17 00:00:00 2001
> > From: Stefan Metzmacher <metze at samba.org>
> > Date: Fri, 1 May 2015 20:20:50 +0200
> > Subject: [PATCH 05/17] s4:torture/smb2: add smb2.notify.close test
> >
> > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> >
> > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > ---
> > source4/torture/smb2/notify.c | 70 +++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 70 insertions(+)
> >
> > diff --git a/source4/torture/smb2/notify.c b/source4/torture/smb2/notify.c
> > index 6c1bf3a..d2b3594 100644
> > --- a/source4/torture/smb2/notify.c
> > +++ b/source4/torture/smb2/notify.c
> > @@ -1318,6 +1318,75 @@ done:
> > }
> >
> > /*
> > + basic testing of change notifies followed by a close
> > +*/
> > +
> > +static bool torture_smb2_notify_close(struct torture_context *torture,
> > + struct smb2_tree *tree1)
> > +{
> > + bool ret = true;
> > + NTSTATUS status;
> > + union smb_notify notify;
> > + union smb_open io;
> > + struct smb2_handle h1;
> > + struct smb2_request *req;
> > +
> > + smb2_deltree(tree1, BASEDIR);
> > + smb2_util_rmdir(tree1, BASEDIR);
> > +
> > + torture_comment(torture, "TESTING CHANGE NOTIFY FOLLOWED BY ULOGOFF\n");
> > +
> > + /*
> > + get a handle on the directory
> > + */
> > + ZERO_STRUCT(io.smb2);
> > + io.generic.level = RAW_OPEN_SMB2;
> > + io.smb2.in.create_flags = 0;
> > + io.smb2.in.desired_access = SEC_FILE_ALL;
> > + io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
> > + io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
> > + io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
> > + NTCREATEX_SHARE_ACCESS_WRITE;
> > + io.smb2.in.alloc_size = 0;
> > + io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
> > + io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
> > + io.smb2.in.security_flags = 0;
> > + io.smb2.in.fname = BASEDIR;
> > +
> > + status = smb2_create(tree1, torture, &(io.smb2));
> > + CHECK_STATUS(status, NT_STATUS_OK);
> > +
> > + io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
> > + status = smb2_create(tree1, torture, &(io.smb2));
> > + CHECK_STATUS(status, NT_STATUS_OK);
> > + h1 = io.smb2.out.file.handle;
> > +
> > + /* ask for a change notify,
> > + on file or directory name changes */
> > + ZERO_STRUCT(notify.smb2);
> > + notify.smb2.level = RAW_NOTIFY_SMB2;
> > + notify.smb2.in.buffer_size = 1000;
> > + notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
> > + notify.smb2.in.file.handle = h1;
> > + notify.smb2.in.recursive = true;
> > +
> > + req = smb2_notify_send(tree1, &(notify.smb2));
> > +
> > + WAIT_FOR_ASYNC_RESPONSE(req);
> > +
> > + status = smb2_util_close(tree1, h1);
> > + CHECK_STATUS(status, NT_STATUS_OK);
> > +
> > + status = smb2_notify_recv(req, torture, &(notify.smb2));
> > + CHECK_STATUS(status, STATUS_NOTIFY_CLEANUP);
> > + CHECK_VAL(notify.smb2.out.num_changes, 0);
> > +
> > +done:
> > + smb2_deltree(tree1, BASEDIR);
> > + return ret;
> > +}
> > +
> > +/*
> > basic testing of change notifies followed by a ulogoff
> > */
> >
> > @@ -2133,6 +2202,7 @@ struct torture_suite *torture_smb2_notify_init(void)
> > torture_suite_add_1smb2_test(suite, "tdis", torture_smb2_notify_tree_disconnect);
> > torture_suite_add_1smb2_test(suite, "tdis1", torture_smb2_notify_tree_disconnect_1);
> > torture_suite_add_2smb2_test(suite, "mask-change", torture_smb2_notify_mask_change);
> > + torture_suite_add_1smb2_test(suite, "close", torture_smb2_notify_close);
> > torture_suite_add_1smb2_test(suite, "logoff", torture_smb2_notify_ulogoff);
> > torture_suite_add_1smb2_test(suite, "tree", torture_smb2_notify_tree);
> > torture_suite_add_2smb2_test(suite, "basedir", torture_smb2_notify_basedir);
> > --
> > 1.9.1
> >
> >
> > From 20dc433dda00cf9576e8ce553c5ee0a3cc725a47 Mon Sep 17 00:00:00 2001
> > From: Stefan Metzmacher <metze at samba.org>
> > Date: Fri, 1 May 2015 20:20:50 +0200
> > Subject: [PATCH 06/17] s4:torture/smb2: add smb2.notify.invalid-reauth test
> >
> > An invalid reauth closes the session.
> >
> > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> >
> > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > ---
> > source4/torture/smb2/notify.c | 82 +++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 82 insertions(+)
> >
> > diff --git a/source4/torture/smb2/notify.c b/source4/torture/smb2/notify.c
> > index d2b3594..33df249 100644
> > --- a/source4/torture/smb2/notify.c
> > +++ b/source4/torture/smb2/notify.c
> > @@ -1455,6 +1455,87 @@ done:
> > return ret;
> > }
> >
> > +/*
> > + basic testing of change notifies followed by an invalid reauth
> > +*/
> > +
> > +static bool torture_smb2_notify_invalid_reauth(struct torture_context *torture,
> > + struct smb2_tree *tree1,
> > + struct smb2_tree *tree2)
> > +{
> > + bool ret = true;
> > + NTSTATUS status;
> > + union smb_notify notify;
> > + union smb_open io;
> > + struct smb2_handle h1;
> > + struct smb2_request *req;
> > + struct cli_credentials *invalid_creds;
> > +
> > + smb2_deltree(tree2, BASEDIR);
> > + smb2_util_rmdir(tree2, BASEDIR);
> > +
> > + torture_comment(torture, "TESTING CHANGE NOTIFY FOLLOWED BY invalid REAUTH\n");
> > +
> > + /*
> > + get a handle on the directory
> > + */
> > + ZERO_STRUCT(io.smb2);
> > + io.generic.level = RAW_OPEN_SMB2;
> > + io.smb2.in.create_flags = 0;
> > + io.smb2.in.desired_access = SEC_FILE_ALL;
> > + io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
> > + io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
> > + io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
> > + NTCREATEX_SHARE_ACCESS_WRITE;
> > + io.smb2.in.alloc_size = 0;
> > + io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
> > + io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
> > + io.smb2.in.security_flags = 0;
> > + io.smb2.in.fname = BASEDIR;
> > +
> > + status = smb2_create(tree1, torture, &(io.smb2));
> > + CHECK_STATUS(status, NT_STATUS_OK);
> > +
> > + io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
> > + status = smb2_create(tree1, torture, &(io.smb2));
> > + CHECK_STATUS(status, NT_STATUS_OK);
> > + h1 = io.smb2.out.file.handle;
> > +
> > + /* ask for a change notify,
> > + on file or directory name changes */
> > + ZERO_STRUCT(notify.smb2);
> > + notify.smb2.level = RAW_NOTIFY_SMB2;
> > + notify.smb2.in.buffer_size = 1000;
> > + notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
> > + notify.smb2.in.file.handle = h1;
> > + notify.smb2.in.recursive = true;
> > +
> > + req = smb2_notify_send(tree1, &(notify.smb2));
> > +
> > + WAIT_FOR_ASYNC_RESPONSE(req);
> > +
> > + invalid_creds = cli_credentials_init(torture);
> > + torture_assert(torture, (invalid_creds != NULL), "talloc error");
> > + cli_credentials_set_username(invalid_creds, "__none__invalid__none__", CRED_SPECIFIED);
> > + cli_credentials_set_domain(invalid_creds, "__none__invalid__none__", CRED_SPECIFIED);
> > + cli_credentials_set_password(invalid_creds, "__none__invalid__none__", CRED_SPECIFIED);
> > + cli_credentials_set_realm(invalid_creds, NULL, CRED_SPECIFIED);
> > + cli_credentials_set_workstation(invalid_creds, "", CRED_UNINITIALISED);
> > +
> > + status = smb2_session_setup_spnego(tree1->session,
> > + invalid_creds,
> > + 0 /* previous_session_id */);
> > + CHECK_STATUS(status, NT_STATUS_LOGON_FAILURE);
> > +
> > + status = smb2_notify_recv(req, torture, &(notify.smb2));
> > + CHECK_STATUS(status, STATUS_NOTIFY_CLEANUP);
> > + CHECK_VAL(notify.smb2.out.num_changes, 0);
> > +
> > +done:
> > + smb2_deltree(tree2, BASEDIR);
> > + return ret;
> > +}
> > +
> > static void tcp_dis_handler(struct smb2_transport *t, void *p)
> > {
> > struct smb2_tree *tree = (struct smb2_tree *)p;
> > @@ -2204,6 +2285,7 @@ struct torture_suite *torture_smb2_notify_init(void)
> > torture_suite_add_2smb2_test(suite, "mask-change", torture_smb2_notify_mask_change);
> > torture_suite_add_1smb2_test(suite, "close", torture_smb2_notify_close);
> > torture_suite_add_1smb2_test(suite, "logoff", torture_smb2_notify_ulogoff);
> > + torture_suite_add_2smb2_test(suite, "invalid-reauth", torture_smb2_notify_invalid_reauth);
> > torture_suite_add_1smb2_test(suite, "tree", torture_smb2_notify_tree);
> > torture_suite_add_2smb2_test(suite, "basedir", torture_smb2_notify_basedir);
> > torture_suite_add_2smb2_test(suite, "double", torture_smb2_notify_double);
> > --
> > 1.9.1
> >
> >
> > From 4e6d97ee5efbbbd093fd0a966811585a8c305e05 Mon Sep 17 00:00:00 2001
> > From: Stefan Metzmacher <metze at samba.org>
> > Date: Sat, 2 May 2015 09:57:03 +0200
> > Subject: [PATCH 07/17] s4:torture/smb2: add smb2.notify.session-reconnect test
> >
> > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> >
> > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > ---
> > source4/torture/smb2/notify.c | 81 +++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 81 insertions(+)
> >
> > diff --git a/source4/torture/smb2/notify.c b/source4/torture/smb2/notify.c
> > index 33df249..b804ebc 100644
> > --- a/source4/torture/smb2/notify.c
> > +++ b/source4/torture/smb2/notify.c
> > @@ -1456,6 +1456,86 @@ done:
> > }
> >
> > /*
> > + basic testing of change notifies followed by a session reconnect
> > +*/
> > +
> > +static bool torture_smb2_notify_session_reconnect(struct torture_context *torture,
> > + struct smb2_tree *tree1)
> > +{
> > + bool ret = true;
> > + NTSTATUS status;
> > + union smb_notify notify;
> > + union smb_open io;
> > + struct smb2_handle h1;
> > + struct smb2_request *req;
> > + uint64_t previous_session_id = 0;
> > + struct smb2_session *session2 = NULL;
> > +
> > + smb2_deltree(tree1, BASEDIR);
> > + smb2_util_rmdir(tree1, BASEDIR);
> > +
> > + torture_comment(torture, "TESTING CHANGE NOTIFY FOLLOWED BY SESSION RECONNECT\n");
> > +
> > + /*
> > + get a handle on the directory
> > + */
> > + ZERO_STRUCT(io.smb2);
> > + io.generic.level = RAW_OPEN_SMB2;
> > + io.smb2.in.create_flags = 0;
> > + io.smb2.in.desired_access = SEC_FILE_ALL;
> > + io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
> > + io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
> > + io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
> > + NTCREATEX_SHARE_ACCESS_WRITE;
> > + io.smb2.in.alloc_size = 0;
> > + io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
> > + io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
> > + io.smb2.in.security_flags = 0;
> > + io.smb2.in.fname = BASEDIR;
> > +
> > + status = smb2_create(tree1, torture, &(io.smb2));
> > + CHECK_STATUS(status, NT_STATUS_OK);
> > +
> > + io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
> > + status = smb2_create(tree1, torture, &(io.smb2));
> > + CHECK_STATUS(status, NT_STATUS_OK);
> > + h1 = io.smb2.out.file.handle;
> > +
> > + /* ask for a change notify,
> > + on file or directory name changes */
> > + ZERO_STRUCT(notify.smb2);
> > + notify.smb2.level = RAW_NOTIFY_SMB2;
> > + notify.smb2.in.buffer_size = 1000;
> > + notify.smb2.in.completion_filter = FILE_NO