Patches for https://bugzilla.samba.org/show_bug.cgi?id=11182

Ira Cooper ira at samba.org
Wed May 6 13:11:32 MDT 2015


On Wed, May 6, 2015 at 2:53 PM, Michael Adam <obnox at samba.org> wrote:

> 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
>


I haven't reviewed Michael's patches.  I did ask Michael about those issues
knowing he knew about the code.

Barring the issues mentioned, I do agree, it is a nice cleanup.

So +1 to Michael.

-Ira



> > > 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_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);
> > > +
> > > +   previous_session_id =
> smb2cli_session_current_id(tree1->session->smbXcli);
> > > +   torture_assert(torture, torture_smb2_session_setup(torture,
> > > +                  tree1->session->transport,
> > > +                  previous_session_id,
> > > +                  torture, &session2),
> > > +                  "session setup with previous_session_id failed");
> > > +
> > > +   status = smb2_notify_recv(req, torture, &(notify.smb2));
> > > +   CHECK_STATUS(status, STATUS_NOTIFY_CLEANUP);
> > > +   CHECK_VAL(notify.smb2.out.num_changes, 0);
> > > +
> > > +   status = smb2_logoff(tree1->session);
> > > +   CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
> > > +
> > > +   status = smb2_logoff(session2);
> > > +   CHECK_STATUS(status, NT_STATUS_OK);
> > > +done:
> > > +   smb2_deltree(tree1, BASEDIR);
> > > +   return ret;
> > > +}
> > > +
> > > +/*
> > >    basic testing of change notifies followed by an invalid reauth
> > >  */
> > >
> > > @@ -2285,6 +2365,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_1smb2_test(suite, "session-reconnect",
> torture_smb2_notify_session_reconnect);
> > >     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);
> > > --
> > > 1.9.1
> > >
> > >
> > > From 10c41f4a6635cbfed0df3457604256f0592fe423 Mon Sep 17 00:00:00 2001
> > > From: Stefan Metzmacher <metze at samba.org>
> > > Date: Sat, 2 May 2015 16:09:40 +0200
> > > Subject: [PATCH 08/17] s3:smbXsrv_session: clear smb2req->session of
> pending
> > >  requests in smbXsrv_session_destructor()
> > >
> > > This won't be needed typically needed as the caller is supposted to
> cancel
> > > the requests already, but this makes sure we don't keep dangling
> pointers.
> > >
> > > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> > >
> > > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > > ---
> > >  source3/smbd/smbXsrv_session.c | 23 +++++++++++++++++++++++
> > >  1 file changed, 23 insertions(+)
> > >
> > > diff --git a/source3/smbd/smbXsrv_session.c
> b/source3/smbd/smbXsrv_session.c
> > > index a49e246..41625fc 100644
> > > --- a/source3/smbd/smbXsrv_session.c
> > > +++ b/source3/smbd/smbXsrv_session.c
> > > @@ -1066,6 +1066,29 @@ NTSTATUS
> smb2srv_session_close_previous_recv(struct tevent_req *req)
> > >  static int smbXsrv_session_destructor(struct smbXsrv_session *session)
> > >  {
> > >     NTSTATUS status;
> > > +   struct smbXsrv_connection *xconn = NULL;
> > > +
> > > +   if (session->client != NULL) {
> > > +           xconn = session->client->connections;
> > > +   }
> > > +
> > > +   for (; xconn != NULL; xconn = xconn->next) {
> > > +           struct smbd_smb2_request *preq;
> > > +
> > > +           for (preq = xconn->smb2.requests; preq != NULL; preq =
> preq->next) {
> > > +                   if (preq->session != session) {
> > > +                           continue;
> > > +                   }
> > > +
> > > +                   preq->session = NULL;
> > > +                   /*
> > > +                    * If we no longer have a session we can't
> > > +                    * sign or encrypt replies.
> > > +                    */
> > > +                   preq->do_signing = false;
> > > +                   preq->do_encryption = false;
> > > +           }
> > > +   }
> > >
> > >     status = smbXsrv_session_logoff(session);
> > >     if (!NT_STATUS_IS_OK(status)) {
> > > --
> > > 1.9.1
> > >
> > >
> > > From 2793e29e742f45db2c05c8e571a9cdfe0d96468e Mon Sep 17 00:00:00 2001
> > > From: Stefan Metzmacher <metze at samba.org>
> > > Date: Sat, 2 May 2015 16:17:34 +0200
> > > Subject: [PATCH 09/17] s3:smbXsrv_session: clear smb2req->session of
> pending
> > >  requests in smbXsrv_session_logoff_all_callback()
> > >
> > > smbXsrv_session_logoff_all_callback() is called when the last transport
> > > connection is gone, which means we won't need to sign any response...
> > >
> > > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> > >
> > > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > > ---
> > >  source3/smbd/smbXsrv_session.c | 23 +++++++++++++++++++++++
> > >  1 file changed, 23 insertions(+)
> > >
> > > diff --git a/source3/smbd/smbXsrv_session.c
> b/source3/smbd/smbXsrv_session.c
> > > index 41625fc..5ee4bbe 100644
> > > --- a/source3/smbd/smbXsrv_session.c
> > > +++ b/source3/smbd/smbXsrv_session.c
> > > @@ -1503,6 +1503,7 @@ static int
> smbXsrv_session_logoff_all_callback(struct db_record *local_rec,
> > >     TDB_DATA val;
> > >     void *ptr = NULL;
> > >     struct smbXsrv_session *session = NULL;
> > > +   struct smbXsrv_connection *xconn = NULL;
> > >     NTSTATUS status;
> > >
> > >     val = dbwrap_record_get_value(local_rec);
> > > @@ -1519,6 +1520,28 @@ static int
> smbXsrv_session_logoff_all_callback(struct db_record *local_rec,
> > >     session = talloc_get_type_abort(ptr, struct smbXsrv_session);
> > >
> > >     session->db_rec = local_rec;
> > > +
> > > +   if (session->client != NULL) {
> > > +           xconn = session->client->connections;
> > > +   }
> > > +   for (; xconn != NULL; xconn = xconn->next) {
> > > +           struct smbd_smb2_request *preq;
> > > +
> > > +           for (preq = xconn->smb2.requests; preq != NULL; preq =
> preq->next) {
> > > +                   if (preq->session != session) {
> > > +                           continue;
> > > +                   }
> > > +
> > > +                   preq->session = NULL;
> > > +                   /*
> > > +                    * If we no longer have a session we can't
> > > +                    * sign or encrypt replies.
> > > +                    */
> > > +                   preq->do_signing = false;
> > > +                   preq->do_encryption = false;
> > > +           }
> > > +   }
> > > +
> > >     status = smbXsrv_session_logoff(session);
> > >     if (!NT_STATUS_IS_OK(status)) {
> > >             if (NT_STATUS_IS_OK(state->first_status)) {
> > > --
> > > 1.9.1
> > >
> > >
> > > From 9ef38da3bd9e69e01da1a69fad30d824d355bcdf 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 10/17] s3:smbXsrv_session: add
> > >  smb2srv_session_shutdown_send/recv helper functions
> > >
> > > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> > >
> > > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > > ---
> > >  source3/smbd/globals.h         |   5 ++
> > >  source3/smbd/smbXsrv_session.c | 121
> +++++++++++++++++++++++++++++++++++++++++
> > >  2 files changed, 126 insertions(+)
> > >
> > > diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
> > > index c7e2608..22cf5d6 100644
> > > --- a/source3/smbd/globals.h
> > > +++ b/source3/smbd/globals.h
> > > @@ -537,6 +537,11 @@ struct smbXsrv_channel_global0;
> > >  NTSTATUS smbXsrv_session_find_channel(const struct smbXsrv_session
> *session,
> > >                                   const struct smbXsrv_connection
> *conn,
> > >                                   struct smbXsrv_channel_global0 **_c);
> > > +struct tevent_req *smb2srv_session_shutdown_send(TALLOC_CTX *mem_ctx,
> > > +                                   struct tevent_context *ev,
> > > +                                   struct smbXsrv_session *session,
> > > +                                   struct smbd_smb2_request
> *current_req);
> > > +NTSTATUS smb2srv_session_shutdown_recv(struct tevent_req *req);
> > >  NTSTATUS smbXsrv_session_logoff(struct smbXsrv_session *session);
> > >  NTSTATUS smbXsrv_session_logoff_all(struct smbXsrv_connection *conn);
> > >  NTSTATUS smb1srv_session_table_init(struct smbXsrv_connection *conn);
> > > diff --git a/source3/smbd/smbXsrv_session.c
> b/source3/smbd/smbXsrv_session.c
> > > index 5ee4bbe..f4617f7 100644
> > > --- a/source3/smbd/smbXsrv_session.c
> > > +++ b/source3/smbd/smbXsrv_session.c
> > > @@ -1327,6 +1327,127 @@ NTSTATUS smbXsrv_session_find_channel(const
> struct smbXsrv_session *session,
> > >     return NT_STATUS_USER_SESSION_DELETED;
> > >  }
> > >
> > > +struct smb2srv_session_shutdown_state {
> > > +   struct tevent_queue *wait_queue;
> > > +};
> > > +
> > > +static void smb2srv_session_shutdown_wait_done(struct tevent_req
> *subreq);
> > > +
> > > +struct tevent_req *smb2srv_session_shutdown_send(TALLOC_CTX *mem_ctx,
> > > +                                   struct tevent_context *ev,
> > > +                                   struct smbXsrv_session *session,
> > > +                                   struct smbd_smb2_request
> *current_req)
> > > +{
> > > +   struct tevent_req *req;
> > > +   struct smb2srv_session_shutdown_state *state;
> > > +   struct tevent_req *subreq;
> > > +   struct smbXsrv_connection *xconn = NULL;
> > > +   size_t len = 0;
> > > +
> > > +   /*
> > > +    * Make sure that no new request will be able to use this session.
> > > +    */
> > > +   session->status = NT_STATUS_USER_SESSION_DELETED;
> > > +
> > > +   req = tevent_req_create(mem_ctx, &state,
> > > +                           struct smb2srv_session_shutdown_state);
> > > +   if (req == NULL) {
> > > +           return NULL;
> > > +   }
> > > +
> > > +   state->wait_queue = tevent_queue_create(state,
> "smb2srv_session_shutdown_queue");
> > > +   if (tevent_req_nomem(state->wait_queue, req)) {
> > > +           return tevent_req_post(req, ev);
> > > +   }
> > > +
> > > +   for (xconn = session->client->connections; xconn != NULL; xconn =
> xconn->next) {
> > > +           struct smbd_smb2_request *preq;
> > > +
> > > +           for (preq = xconn->smb2.requests; preq != NULL; preq =
> preq->next) {
> > > +                   if (preq == current_req) {
> > > +                           /* Can't cancel current request. */
> > > +                           continue;
> > > +                   }
> > > +                   if (preq->session != session) {
> > > +                           /* Request on different session. */
> > > +                           continue;
> > > +                   }
> > > +
> > > +                   if (!NT_STATUS_IS_OK(xconn->transport.status)) {
> > > +                           preq->session = NULL;
> > > +                           /*
> > > +                            * If we no longer have a session we can't
> > > +                            * sign or encrypt replies.
> > > +                            */
> > > +                           preq->do_signing = false;
> > > +                           preq->do_encryption = false;
> > > +
> > > +                           if (preq->subreq != NULL) {
> > > +                                   tevent_req_cancel(preq->subreq);
> > > +                           }
> > > +                           continue;
> > > +                   }
> > > +
> > > +                   /*
> > > +                    * Never cancel anything in a compound
> > > +                    * request. Way too hard to deal with
> > > +                    * the result.
> > > +                    */
> > > +                   if (!preq->compound_related && preq->subreq !=
> NULL) {
> > > +                           tevent_req_cancel(preq->subreq);
> > > +                   }
> > > +
> > > +                   /*
> > > +                    * Now wait until the request is finished.
> > > +                    *
> > > +                    * We don't set a callback, as we just want to
> block the
> > > +                    * wait queue and the talloc_free() of the request
> will
> > > +                    * remove the item from the wait queue.
> > > +                    */
> > > +                   subreq = tevent_queue_wait_send(preq, ev,
> state->wait_queue);
> > > +                   if (tevent_req_nomem(subreq, req)) {
> > > +                           return tevent_req_post(req, ev);
> > > +                   }
> > > +           }
> > > +   }
> > > +
> > > +   len = tevent_queue_length(state->wait_queue);
> > > +   if (len == 0) {
> > > +           tevent_req_done(req);
> > > +           return tevent_req_post(req, ev);
> > > +   }
> > > +
> > > +   /*
> > > +    * Now we add our own waiter to the end of the queue,
> > > +    * this way we get notified when all pending requests are finished
> > > +    * and send to the socket.
> > > +    */
> > > +   subreq = tevent_queue_wait_send(state, ev, state->wait_queue);
> > > +   if (tevent_req_nomem(subreq, req)) {
> > > +           return tevent_req_post(req, ev);
> > > +   }
> > > +   tevent_req_set_callback(subreq,
> smb2srv_session_shutdown_wait_done, req);
> > > +
> > > +   return req;
> > > +}
> > > +
> > > +static void smb2srv_session_shutdown_wait_done(struct tevent_req
> *subreq)
> > > +{
> > > +   struct tevent_req *req =
> > > +           tevent_req_callback_data(subreq,
> > > +           struct tevent_req);
> > > +
> > > +   tevent_queue_wait_recv(subreq);
> > > +   TALLOC_FREE(subreq);
> > > +
> > > +   tevent_req_done(req);
> > > +}
> > > +
> > > +NTSTATUS smb2srv_session_shutdown_recv(struct tevent_req *req)
> > > +{
> > > +   return tevent_req_simple_recv_ntstatus(req);
> > > +}
> > > +
> > >  NTSTATUS smbXsrv_session_logoff(struct smbXsrv_session *session)
> > >  {
> > >     struct smbXsrv_session_table *table;
> > > --
> > > 1.9.1
> > >
> > >
> > > From db39da8d22db275c913a3b172915510595477397 Mon Sep 17 00:00:00 2001
> > > From: Stefan Metzmacher <metze at samba.org>
> > > Date: Sat, 2 May 2015 16:13:27 +0200
> > > Subject: [PATCH 11/17] s3:smbXsrv_session: cancel pending requests
> when we
> > >  logoff a previous session
> > >
> > > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> > >
> > > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > > ---
> > >  source3/smbd/smbXsrv_session.c | 45
> +++++++++++++++++++++++++++++++++++-------
> > >  1 file changed, 38 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/source3/smbd/smbXsrv_session.c
> b/source3/smbd/smbXsrv_session.c
> > > index f4617f7..2ccae0e 100644
> > > --- a/source3/smbd/smbXsrv_session.c
> > > +++ b/source3/smbd/smbXsrv_session.c
> > > @@ -226,6 +226,8 @@ static NTSTATUS smbXsrv_session_table_init(struct
> smbXsrv_connection *conn,
> > >     return NT_STATUS_OK;
> > >  }
> > >
> > > +static void smbXsrv_session_close_shutdown_done(struct tevent_req
> *subreq);
> > > +
> > >  static void smbXsrv_session_close_loop(struct tevent_req *subreq)
> > >  {
> > >     struct smbXsrv_client *client =
> > > @@ -330,20 +332,22 @@ static void smbXsrv_session_close_loop(struct
> tevent_req *subreq)
> > >             goto next;
> > >     }
> > >
> > > -   /*
> > > -    * TODO: cancel all outstanding requests on the session
> > > -    */
> > > -   status = smbXsrv_session_logoff(session);
> > > -   if (!NT_STATUS_IS_OK(status)) {
> > > +   subreq = smb2srv_session_shutdown_send(session, client->ev_ctx,
> > > +                                          session, NULL);
> > > +   if (subreq == NULL) {
> > > +           status = NT_STATUS_NO_MEMORY;
> > >             DEBUG(0, ("smbXsrv_session_close_loop: "
> > > -                     "smbXsrv_session_logoff(%llu) failed: %s\n",
> > > +                     "smb2srv_session_shutdown_send(%llu) failed:
> %s\n",
> > >                       (unsigned long
> long)session->global->session_wire_id,
> > >                       nt_errstr(status)));
> > >             if (DEBUGLVL(1)) {
> > >                     NDR_PRINT_DEBUG(smbXsrv_session_closeB,
> &close_blob);
> > >             }
> > > +           goto next;
> > >     }
> > > -   TALLOC_FREE(session);
> > > +   tevent_req_set_callback(subreq,
> > > +                           smbXsrv_session_close_shutdown_done,
> > > +                           session);
> > >
> > >  next:
> > >     TALLOC_FREE(rec);
> > > @@ -359,6 +363,33 @@ next:
> > >     tevent_req_set_callback(subreq, smbXsrv_session_close_loop,
> client);
> > >  }
> > >
> > > +static void smbXsrv_session_close_shutdown_done(struct tevent_req
> *subreq)
> > > +{
> > > +   struct smbXsrv_session *session =
> > > +           tevent_req_callback_data(subreq,
> > > +           struct smbXsrv_session);
> > > +   NTSTATUS status;
> > > +
> > > +   status = smb2srv_session_shutdown_recv(subreq);
> > > +   TALLOC_FREE(subreq);
> > > +   if (!NT_STATUS_IS_OK(status)) {
> > > +           DEBUG(0, ("smbXsrv_session_close_loop: "
> > > +                     "smb2srv_session_shutdown_recv(%llu) failed:
> %s\n",
> > > +                     (unsigned long
> long)session->global->session_wire_id,
> > > +                     nt_errstr(status)));
> > > +   }
> > > +
> > > +   status = smbXsrv_session_logoff(session);
> > > +   if (!NT_STATUS_IS_OK(status)) {
> > > +           DEBUG(0, ("smbXsrv_session_close_loop: "
> > > +                     "smbXsrv_session_logoff(%llu) failed: %s\n",
> > > +                     (unsigned long
> long)session->global->session_wire_id,
> > > +                     nt_errstr(status)));
> > > +   }
> > > +
> > > +   TALLOC_FREE(session);
> > > +}
> > > +
> > >  struct smb1srv_session_local_allocate_state {
> > >     const uint32_t lowest_id;
> > >     const uint32_t highest_id;
> > > --
> > > 1.9.1
> > >
> > >
> > > From 5a25052bca611617fd5bbab4fec493a247186cc5 Mon Sep 17 00:00:00 2001
> > > From: Stefan Metzmacher <metze at samba.org>
> > > Date: Sat, 2 May 2015 16:20:06 +0200
> > > Subject: [PATCH 12/17] s3:smb2_sesssetup: let smbd_smb2_logoff_* use
> > >  smbXsrv_session_shutdown_*
> > >
> > > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> > >
> > > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > > ---
> > >  source3/smbd/smb2_sesssetup.c | 75
> +++++++++----------------------------------
> > >  1 file changed, 15 insertions(+), 60 deletions(-)
> > >
> > > diff --git a/source3/smbd/smb2_sesssetup.c
> b/source3/smbd/smb2_sesssetup.c
> > > index fb7edce..5cd3446 100644
> > > --- a/source3/smbd/smb2_sesssetup.c
> > > +++ b/source3/smbd/smb2_sesssetup.c
> > > @@ -860,95 +860,50 @@ static void smbd_smb2_request_logoff_done(struct
> tevent_req *subreq)
> > >     }
> > >  }
> > >
> > > -struct smbd_smb2_logout_state {
> > > +struct smbd_smb2_logoff_state {
> > >     struct smbd_smb2_request *smb2req;
> > > -   struct tevent_queue *wait_queue;
> > >  };
> > >
> > > -static void smbd_smb2_logoff_wait_done(struct tevent_req *subreq);
> > > +static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq);
> > >
> > >  static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
> > >                                     struct tevent_context *ev,
> > >                                     struct smbd_smb2_request *smb2req)
> > >  {
> > >     struct tevent_req *req;
> > > -   struct smbd_smb2_logout_state *state;
> > > +   struct smbd_smb2_logoff_state *state;
> > >     struct tevent_req *subreq;
> > > -   struct smbd_smb2_request *preq;
> > > -   struct smbXsrv_connection *xconn = smb2req->xconn;
> > >
> > >     req = tevent_req_create(mem_ctx, &state,
> > > -                   struct smbd_smb2_logout_state);
> > > +                   struct smbd_smb2_logoff_state);
> > >     if (req == NULL) {
> > >             return NULL;
> > >     }
> > >     state->smb2req = smb2req;
> > >
> > > -   state->wait_queue = tevent_queue_create(state,
> "logoff_wait_queue");
> > > -   if (tevent_req_nomem(state->wait_queue, req)) {
> > > -           return tevent_req_post(req, ev);
> > > -   }
> > > -
> > > -   /*
> > > -    * Make sure that no new request will be able to use this session.
> > > -    */
> > > -   smb2req->session->status = NT_STATUS_USER_SESSION_DELETED;
> > > -
> > > -   for (preq = xconn->smb2.requests; preq != NULL; preq = preq->next)
> {
> > > -           if (preq == smb2req) {
> > > -                   /* Can't cancel current request. */
> > > -                   continue;
> > > -           }
> > > -           if (preq->session != smb2req->session) {
> > > -                   /* Request on different session. */
> > > -                   continue;
> > > -           }
> > > -
> > > -           /*
> > > -            * Never cancel anything in a compound
> > > -            * request. Way too hard to deal with
> > > -            * the result.
> > > -            */
> > > -           if (!preq->compound_related && preq->subreq != NULL) {
> > > -                   tevent_req_cancel(preq->subreq);
> > > -           }
> > > -
> > > -           /*
> > > -            * Now wait until the request is finished.
> > > -            *
> > > -            * We don't set a callback, as we just want to block the
> > > -            * wait queue and the talloc_free() of the request will
> > > -            * remove the item from the wait queue.
> > > -            */
> > > -           subreq = tevent_queue_wait_send(preq, ev,
> state->wait_queue);
> > > -           if (tevent_req_nomem(subreq, req)) {
> > > -                   return tevent_req_post(req, ev);
> > > -           }
> > > -   }
> > > -
> > > -   /*
> > > -    * Now we add our own waiter to the end of the queue,
> > > -    * this way we get notified when all pending requests are finished
> > > -    * and send to the socket.
> > > -    */
> > > -   subreq = tevent_queue_wait_send(state, ev, state->wait_queue);
> > > +   subreq = smb2srv_session_shutdown_send(state, ev,
> > > +                                          smb2req->session,
> > > +                                          smb2req);
> > >     if (tevent_req_nomem(subreq, req)) {
> > >             return tevent_req_post(req, ev);
> > >     }
> > > -   tevent_req_set_callback(subreq, smbd_smb2_logoff_wait_done, req);
> > > +   tevent_req_set_callback(subreq, smbd_smb2_logoff_shutdown_done,
> req);
> > >
> > >     return req;
> > >  }
> > >
> > > -static void smbd_smb2_logoff_wait_done(struct tevent_req *subreq)
> > > +static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq)
> > >  {
> > >     struct tevent_req *req = tevent_req_callback_data(
> > >             subreq, struct tevent_req);
> > > -   struct smbd_smb2_logout_state *state = tevent_req_data(
> > > -           req, struct smbd_smb2_logout_state);
> > > +   struct smbd_smb2_logoff_state *state = tevent_req_data(
> > > +           req, struct smbd_smb2_logoff_state);
> > >     NTSTATUS status;
> > >
> > > -   tevent_queue_wait_recv(subreq);
> > > +   status = smb2srv_session_shutdown_recv(subreq);
> > > +   if (tevent_req_nterror(req, status)) {
> > > +           return;
> > > +   }
> > >     TALLOC_FREE(subreq);
> > >
> > >     /*
> > > --
> > > 1.9.1
> > >
> > >
> > > From f5b8aa1a1b6ca7db1d67af3feecc0ae07fbad32e Mon Sep 17 00:00:00 2001
> > > From: Stefan Metzmacher <metze at samba.org>
> > > Date: Sat, 2 May 2015 16:27:26 +0200
> > > Subject: [PATCH 13/17] s3:smb2_sesssetup: always assign
> smb2req->session when
> > >  a session was created.
> > >
> > > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> > >
> > > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > > ---
> > >  source3/smbd/smb2_sesssetup.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/source3/smbd/smb2_sesssetup.c
> b/source3/smbd/smb2_sesssetup.c
> > > index 5cd3446..e7eb414 100644
> > > --- a/source3/smbd/smb2_sesssetup.c
> > > +++ b/source3/smbd/smb2_sesssetup.c
> > > @@ -368,7 +368,6 @@ static NTSTATUS
> smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
> > >      * we attach the session to the request
> > >      * so that the response can be signed
> > >      */
> > > -   smb2req->session = session;
> > >     if (!guest) {
> > >             smb2req->do_signing = true;
> > >     }
> > > @@ -587,6 +586,7 @@ static struct tevent_req
> *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
> > >             if (tevent_req_nterror(req, status)) {
> > >                     return tevent_req_post(req, ev);
> > >             }
> > > +           smb2req->session = state->session;
> > >     } else {
> > >             if (smb2req->session == NULL) {
> > >                     tevent_req_nterror(req,
> NT_STATUS_USER_SESSION_DELETED);
> > > --
> > > 1.9.1
> > >
> > >
> > > From 53604c3b1cc52d8ad00133e1c069917a841b47ae Mon Sep 17 00:00:00 2001
> > > From: Stefan Metzmacher <metze at samba.org>
> > > Date: Sat, 2 May 2015 16:21:25 +0200
> > > Subject: [PATCH 14/17] s3:smb2_sesssetup: add
> > >  smbd_smb2_session_setup_wrap_send/recv()
> > >
> > > The wrapper calls smbXsrv_session_shutdown_send/recv() in case of an
> error,
> > > this makes sure a failing reauth shuts down the session like an
> explicit logoff.
> > >
> > > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> > >
> > > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > > ---
> > >  source3/smbd/smb2_sesssetup.c | 186
> ++++++++++++++++++++++++++++++++++++++----
> > >  1 file changed, 171 insertions(+), 15 deletions(-)
> > >
> > > diff --git a/source3/smbd/smb2_sesssetup.c
> b/source3/smbd/smb2_sesssetup.c
> > > index e7eb414..5ddaa48 100644
> > > --- a/source3/smbd/smb2_sesssetup.c
> > > +++ b/source3/smbd/smb2_sesssetup.c
> > > @@ -29,7 +29,7 @@
> > >  #include "../libcli/security/security.h"
> > >  #include "../lib/util/tevent_ntstatus.h"
> > >
> > > -static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX
> *mem_ctx,
> > > +static struct tevent_req
> *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
> > >                                     struct tevent_context *ev,
> > >                                     struct smbd_smb2_request *smb2req,
> > >                                     uint64_t in_session_id,
> > > @@ -37,7 +37,7 @@ static struct tevent_req
> *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
> > >                                     uint8_t in_security_mode,
> > >                                     uint64_t in_previous_session_id,
> > >                                     DATA_BLOB in_security_buffer);
> > > -static NTSTATUS smbd_smb2_session_setup_recv(struct tevent_req *req,
> > > +static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req
> *req,
> > >                                     uint16_t *out_session_flags,
> > >                                     TALLOC_CTX *mem_ctx,
> > >                                     DATA_BLOB *out_security_buffer,
> > > @@ -87,14 +87,14 @@ NTSTATUS
> smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req)
> > >     in_security_buffer.data = SMBD_SMB2_IN_DYN_PTR(smb2req);
> > >     in_security_buffer.length = in_security_length;
> > >
> > > -   subreq = smbd_smb2_session_setup_send(smb2req,
> > > -                                         smb2req->sconn->ev_ctx,
> > > -                                         smb2req,
> > > -                                         in_session_id,
> > > -                                         in_flags,
> > > -                                         in_security_mode,
> > > -                                         in_previous_session_id,
> > > -                                         in_security_buffer);
> > > +   subreq = smbd_smb2_session_setup_wrap_send(smb2req,
> > > +                                              smb2req->sconn->ev_ctx,
> > > +                                              smb2req,
> > > +                                              in_session_id,
> > > +                                              in_flags,
> > > +                                              in_security_mode,
> > > +                                              in_previous_session_id,
> > > +                                              in_security_buffer);
> > >     if (subreq == NULL) {
> > >             return smbd_smb2_request_error(smb2req,
> NT_STATUS_NO_MEMORY);
> > >     }
> > > @@ -118,11 +118,11 @@ static void
> smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
> > >     NTSTATUS status;
> > >     NTSTATUS error; /* transport error */
> > >
> > > -   status = smbd_smb2_session_setup_recv(subreq,
> > > -                                         &out_session_flags,
> > > -                                         smb2req,
> > > -                                         &out_security_buffer,
> > > -                                         &out_session_id);
> > > +   status = smbd_smb2_session_setup_wrap_recv(subreq,
> > > +                                              &out_session_flags,
> > > +                                              smb2req,
> > > +                                              &out_security_buffer,
> > > +                                              &out_session_id);
> > >     TALLOC_FREE(subreq);
> > >     if (!NT_STATUS_IS_OK(status) &&
> > >         !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
> > > @@ -788,6 +788,162 @@ static NTSTATUS
> smbd_smb2_session_setup_recv(struct tevent_req *req,
> > >     return status;
> > >  }
> > >
> > > +struct smbd_smb2_session_setup_wrap_state {
> > > +   struct tevent_context *ev;
> > > +   struct smbd_smb2_request *smb2req;
> > > +   uint64_t in_session_id;
> > > +   uint8_t in_flags;
> > > +   uint8_t in_security_mode;
> > > +   uint64_t in_previous_session_id;
> > > +   DATA_BLOB in_security_buffer;
> > > +   uint16_t out_session_flags;
> > > +   DATA_BLOB out_security_buffer;
> > > +   uint64_t out_session_id;
> > > +   NTSTATUS error;
> > > +};
> > > +
> > > +static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req
> *subreq);
> > > +static void smbd_smb2_session_setup_wrap_shutdown_done(struct
> tevent_req *subreq);
> > > +
> > > +static struct tevent_req
> *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
> > > +                                   struct tevent_context *ev,
> > > +                                   struct smbd_smb2_request *smb2req,
> > > +                                   uint64_t in_session_id,
> > > +                                   uint8_t in_flags,
> > > +                                   uint8_t in_security_mode,
> > > +                                   uint64_t in_previous_session_id,
> > > +                                   DATA_BLOB in_security_buffer)
> > > +{
> > > +   struct tevent_req *req;
> > > +   struct smbd_smb2_session_setup_wrap_state *state;
> > > +   struct tevent_req *subreq;
> > > +
> > > +   req = tevent_req_create(mem_ctx, &state,
> > > +                           struct smbd_smb2_session_setup_wrap_state);
> > > +   if (req == NULL) {
> > > +           return NULL;
> > > +   }
> > > +   state->ev = ev;
> > > +   state->smb2req = smb2req;
> > > +   state->in_session_id = in_session_id;
> > > +   state->in_flags = in_flags;
> > > +   state->in_security_mode = in_security_mode;
> > > +   state->in_previous_session_id = in_previous_session_id;
> > > +   state->in_security_buffer = in_security_buffer;
> > > +
> > > +   subreq = smbd_smb2_session_setup_send(state, state->ev,
> > > +                                         state->smb2req,
> > > +                                         state->in_session_id,
> > > +                                         state->in_flags,
> > > +                                         state->in_security_mode,
> > > +
>  state->in_previous_session_id,
> > > +                                         state->in_security_buffer);
> > > +   if (tevent_req_nomem(subreq, req)) {
> > > +           return tevent_req_post(req, ev);
> > > +   }
> > > +   tevent_req_set_callback(subreq,
> > > +                           smbd_smb2_session_setup_wrap_setup_done,
> req);
> > > +
> > > +   return req;
> > > +}
> > > +
> > > +static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req
> *subreq)
> > > +{
> > > +   struct tevent_req *req =
> > > +           tevent_req_callback_data(subreq,
> > > +           struct tevent_req);
> > > +   struct smbd_smb2_session_setup_wrap_state *state =
> > > +           tevent_req_data(req,
> > > +           struct smbd_smb2_session_setup_wrap_state);
> > > +   NTSTATUS status;
> > > +
> > > +   status = smbd_smb2_session_setup_recv(subreq,
> > > +                                         &state->out_session_flags,
> > > +                                         state,
> > > +                                         &state->out_security_buffer,
> > > +                                         &state->out_session_id);
> > > +   TALLOC_FREE(subreq);
> > > +   if (NT_STATUS_IS_OK(status)) {
> > > +           tevent_req_done(req);
> > > +           return;
> > > +   }
> > > +   if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
> > > +           tevent_req_nterror(req, status);
> > > +           return;
> > > +   }
> > > +
> > > +   if (state->smb2req->session == NULL) {
> > > +           tevent_req_nterror(req, status);
> > > +           return;
> > > +   }
> > > +
> > > +   state->error = status;
> > > +
> > > +   subreq = smb2srv_session_shutdown_send(state, state->ev,
> > > +                                          state->smb2req->session,
> > > +                                          state->smb2req);
> > > +   if (tevent_req_nomem(subreq, req)) {
> > > +           return;
> > > +   }
> > > +   tevent_req_set_callback(subreq,
> > > +                           smbd_smb2_session_setup_wrap_shutdown_done,
> > > +                           req);
> > > +}
> > > +
> > > +static void smbd_smb2_session_setup_wrap_shutdown_done(struct
> tevent_req *subreq)
> > > +{
> > > +   struct tevent_req *req =
> > > +           tevent_req_callback_data(subreq,
> > > +           struct tevent_req);
> > > +   struct smbd_smb2_session_setup_wrap_state *state =
> > > +           tevent_req_data(req,
> > > +           struct smbd_smb2_session_setup_wrap_state);
> > > +   NTSTATUS status;
> > > +
> > > +   status = smb2srv_session_shutdown_recv(subreq);
> > > +   TALLOC_FREE(subreq);
> > > +   if (tevent_req_nterror(req, status)) {
> > > +           return;
> > > +   }
> > > +
> > > +   /*
> > > +    * we may need to sign the response, so we need to keep
> > > +    * the session until the response is sent to the wire.
> > > +    */
> > > +   talloc_steal(state->smb2req, state->smb2req->session);
> > > +
> > > +   tevent_req_nterror(req, state->error);
> > > +}
> > > +
> > > +static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req
> *req,
> > > +                                   uint16_t *out_session_flags,
> > > +                                   TALLOC_CTX *mem_ctx,
> > > +                                   DATA_BLOB *out_security_buffer,
> > > +                                   uint64_t *out_session_id)
> > > +{
> > > +   struct smbd_smb2_session_setup_wrap_state *state =
> > > +           tevent_req_data(req,
> > > +           struct smbd_smb2_session_setup_wrap_state);
> > > +   NTSTATUS status;
> > > +
> > > +   if (tevent_req_is_nterror(req, &status)) {
> > > +           if (!NT_STATUS_EQUAL(status,
> NT_STATUS_MORE_PROCESSING_REQUIRED)) {
> > > +                   tevent_req_received(req);
> > > +                   return nt_status_squash(status);
> > > +           }
> > > +   } else {
> > > +           status = NT_STATUS_OK;
> > > +   }
> > > +
> > > +   *out_session_flags = state->out_session_flags;
> > > +   *out_security_buffer = state->out_security_buffer;
> > > +   *out_session_id = state->out_session_id;
> > > +
> > > +   talloc_steal(mem_ctx, out_security_buffer->data);
> > > +   tevent_req_received(req);
> > > +   return status;
> > > +}
> > > +
> > >  static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
> > >                                     struct tevent_context *ev,
> > >                                     struct smbd_smb2_request *smb2req);
> > > --
> > > 1.9.1
> > >
> > >
> > > From 5943d75702246d791138092a2b609b95ba674777 Mon Sep 17 00:00:00 2001
> > > From: Stefan Metzmacher <metze at samba.org>
> > > Date: Sat, 2 May 2015 16:29:03 +0200
> > > Subject: [PATCH 15/17] s3:smb2_sesssetup: remove unused
> > >  smbd_smb2_session_setup_* destructors
> > >
> > > The cleanup of a failing session setup is now handled in
> > > smbd_smb2_session_setup_wrap_*().
> > >
> > > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> > >
> > > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > > ---
> > >  source3/smbd/smb2_sesssetup.c | 98
> -------------------------------------------
> > >  1 file changed, 98 deletions(-)
> > >
> > > diff --git a/source3/smbd/smb2_sesssetup.c
> b/source3/smbd/smb2_sesssetup.c
> > > index 5ddaa48..c56e480 100644
> > > --- a/source3/smbd/smb2_sesssetup.c
> > > +++ b/source3/smbd/smb2_sesssetup.c
> > > @@ -448,94 +448,12 @@ struct smbd_smb2_session_setup_state {
> > >     uint16_t out_session_flags;
> > >     DATA_BLOB out_security_buffer;
> > >     uint64_t out_session_id;
> > > -   /* The following pointer is owned by state->session. */
> > > -   struct smbd_smb2_session_setup_state **pp_self_ref;
> > >  };
> > >
> > > -static int pp_self_ref_destructor(struct
> smbd_smb2_session_setup_state **pp_state)
> > > -{
> > > -   (*pp_state)->session = NULL;
> > > -   /*
> > > -    * To make things clearer, ensure the pp_self_ref
> > > -    * pointer is nulled out. We're never going to
> > > -    * access this again.
> > > -    */
> > > -   (*pp_state)->pp_self_ref = NULL;
> > > -   return 0;
> > > -}
> > > -
> > > -static int smbd_smb2_session_setup_state_destructor(struct
> smbd_smb2_session_setup_state *state)
> > > -{
> > > -   struct smbXsrv_connection *xconn;
> > > -   struct smbd_smb2_request *preq;
> > > -
> > > -   /*
> > > -    * If state->session is not NULL,
> > > -    * we move the session from the session table to the request on
> failure
> > > -    * so that the error response can be correctly signed, but the
> session
> > > -    * is then really deleted when the request is done.
> > > -    */
> > > -
> > > -   if (state->session == NULL) {
> > > -           return 0;
> > > -   }
> > > -
> > > -   state->session->status = NT_STATUS_USER_SESSION_DELETED;
> > > -   state->smb2req->session = talloc_move(state->smb2req,
> &state->session);
> > > -
> > > -   /*
> > > -    * We own the session now - we don't need the
> > > -    * tag talloced on session that keeps track of session
> independently.
> > > -    */
> > > -   TALLOC_FREE(state->pp_self_ref);
> > > -
> > > -   /*
> > > -    * We've made this session owned by the current request.
> > > -    * Ensure that any outstanding requests don't also refer
> > > -    * to it.
> > > -    */
> > > -   xconn = state->smb2req->xconn;
> > > -
> > > -   for (preq = xconn->smb2.requests; preq != NULL; preq = preq->next)
> {
> > > -           if (preq == state->smb2req) {
> > > -                   continue;
> > > -           }
> > > -           if (preq->session == state->smb2req->session) {
> > > -                   preq->session = NULL;
> > > -                   /*
> > > -                    * If we no longer have a session we can't
> > > -                    * sign or encrypt replies.
> > > -                    */
> > > -                   preq->do_signing = false;
> > > -                   preq->do_encryption = false;
> > > -           }
> > > -   }
> > > -
> > > -   return 0;
> > > -}
> > > -
> > >  static void smbd_smb2_session_setup_gensec_done(struct tevent_req
> *subreq);
> > >  static void smbd_smb2_session_setup_previous_done(struct tevent_req
> *subreq);
> > >  static void smbd_smb2_session_setup_auth_return(struct tevent_req
> *req);
> > >
> > >
> -/************************************************************************
> > > - We have to tag the state->session pointer with memory talloc'ed
> > > - on it to ensure it gets NULL'ed out if the underlying struct
> smbXsrv_session
> > > - is deleted by shutdown whilst this request is in flight.
> > >
> -************************************************************************/
> > > -
> > > -static NTSTATUS tag_state_session_ptr(struct
> smbd_smb2_session_setup_state *state)
> > > -{
> > > -   state->pp_self_ref = talloc_zero(state->session,
> > > -                   struct smbd_smb2_session_setup_state *);
> > > -   if (state->pp_self_ref == NULL) {
> > > -           return NT_STATUS_NO_MEMORY;
> > > -   }
> > > -   *state->pp_self_ref = state;
> > > -   talloc_set_destructor(state->pp_self_ref, pp_self_ref_destructor);
> > > -   return NT_STATUS_OK;
> > > -}
> > > -
> > >  static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX
> *mem_ctx,
> > >                                     struct tevent_context *ev,
> > >                                     struct smbd_smb2_request *smb2req,
> > > @@ -577,8 +495,6 @@ static struct tevent_req
> *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
> > >             return tevent_req_post(req, ev);
> > >     }
> > >
> > > -   talloc_set_destructor(state,
> smbd_smb2_session_setup_state_destructor);
> > > -
> > >     if (state->in_session_id == 0) {
> > >             /* create a new session */
> > >             status = smbXsrv_session_create(state->smb2req->xconn,
> > > @@ -609,11 +525,6 @@ static struct tevent_req
> *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
> > >             }
> > >     }
> > >
> > > -   status = tag_state_session_ptr(state);
> > > -   if (tevent_req_nterror(req, status)) {
> > > -           return tevent_req_post(req, ev);
> > > -   }
> > > -
> > >     if (state->session->gensec == NULL) {
> > >             status = auth_generic_prepare(state->session,
> > >
>  state->smb2req->xconn->remote_address,
> > > @@ -668,9 +579,6 @@ static void
> smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
> > >
> > >     if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
> > >             state->out_session_id =
> state->session->global->session_wire_id;
> > > -           /* we want to keep the session */
> > > -           state->session = NULL;
> > > -           TALLOC_FREE(state->pp_self_ref);
> > >             tevent_req_nterror(req, status);
> > >             return;
> > >     }
> > > @@ -735,9 +643,6 @@ static void
> smbd_smb2_session_setup_auth_return(struct tevent_req *req)
> > >             if (tevent_req_nterror(req, status)) {
> > >                     return;
> > >             }
> > > -           /* we want to keep the session */
> > > -           state->session = NULL;
> > > -           TALLOC_FREE(state->pp_self_ref);
> > >             tevent_req_done(req);
> > >             return;
> > >     }
> > > @@ -752,9 +657,6 @@ static void
> smbd_smb2_session_setup_auth_return(struct tevent_req *req)
> > >             return;
> > >     }
> > >
> > > -   /* we want to keep the session */
> > > -   state->session = NULL;
> > > -   TALLOC_FREE(state->pp_self_ref);
> > >     tevent_req_done(req);
> > >     return;
> > >  }
> > > --
> > > 1.9.1
> > >
> > >
> > > From b414e5fc8339fbf893aedd5d3f457c17d3e59265 Mon Sep 17 00:00:00 2001
> > > From: Stefan Metzmacher <metze at samba.org>
> > > Date: Fri, 1 May 2015 16:50:55 +0200
> > > Subject: [PATCH 16/17] s3:smb2_tcon: cancel pending requests on all
> > >  connections on tdis
> > >
> > > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> > >
> > > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > > ---
> > >  source3/smbd/smb2_tcon.c | 66
> +++++++++++++++++++++++++-----------------------
> > >  1 file changed, 35 insertions(+), 31 deletions(-)
> > >
> > > diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
> > > index cf085a5..3750bc1 100644
> > > --- a/source3/smbd/smb2_tcon.c
> > > +++ b/source3/smbd/smb2_tcon.c
> > > @@ -502,8 +502,7 @@ static struct tevent_req
> *smbd_smb2_tdis_send(TALLOC_CTX *mem_ctx,
> > >     struct tevent_req *req;
> > >     struct smbd_smb2_tdis_state *state;
> > >     struct tevent_req *subreq;
> > > -   struct smbd_smb2_request *preq;
> > > -   struct smbXsrv_connection *xconn = smb2req->xconn;
> > > +   struct smbXsrv_connection *xconn = NULL;
> > >
> > >     req = tevent_req_create(mem_ctx, &state,
> > >                     struct smbd_smb2_tdis_state);
> > > @@ -522,35 +521,40 @@ static struct tevent_req
> *smbd_smb2_tdis_send(TALLOC_CTX *mem_ctx,
> > >      */
> > >     smb2req->tcon->status = NT_STATUS_NETWORK_NAME_DELETED;
> > >
> > > -   for (preq = xconn->smb2.requests; preq != NULL; preq = preq->next)
> {
> > > -           if (preq == smb2req) {
> > > -                   /* Can't cancel current request. */
> > > -                   continue;
> > > -           }
> > > -           if (preq->tcon != smb2req->tcon) {
> > > -                   /* Request on different tcon. */
> > > -                   continue;
> > > -           }
> > > -
> > > -           /*
> > > -            * Never cancel anything in a compound
> > > -            * request. Way too hard to deal with
> > > -            * the result.
> > > -            */
> > > -           if (!preq->compound_related && preq->subreq != NULL) {
> > > -                   tevent_req_cancel(preq->subreq);
> > > -           }
> > > -
> > > -           /*
> > > -            * Now wait until the request is finished.
> > > -            *
> > > -            * We don't set a callback, as we just want to block the
> > > -            * wait queue and the talloc_free() of the request will
> > > -            * remove the item from the wait queue.
> > > -            */
> > > -           subreq = tevent_queue_wait_send(preq, ev,
> state->wait_queue);
> > > -           if (tevent_req_nomem(subreq, req)) {
> > > -                   return tevent_req_post(req, ev);
> > > +   xconn = smb2req->xconn->client->connections;
> > > +   for (; xconn != NULL; xconn = xconn->next) {
> > > +           struct smbd_smb2_request *preq;
> > > +
> > > +           for (preq = xconn->smb2.requests; preq != NULL; preq =
> preq->next) {
> > > +                   if (preq == smb2req) {
> > > +                           /* Can't cancel current request. */
> > > +                           continue;
> > > +                   }
> > > +                   if (preq->tcon != smb2req->tcon) {
> > > +                           /* Request on different tcon. */
> > > +                           continue;
> > > +                   }
> > > +
> > > +                   /*
> > > +                    * Never cancel anything in a compound
> > > +                    * request. Way too hard to deal with
> > > +                    * the result.
> > > +                    */
> > > +                   if (!preq->compound_related && preq->subreq !=
> NULL) {
> > > +                           tevent_req_cancel(preq->subreq);
> > > +                   }
> > > +
> > > +                   /*
> > > +                    * Now wait until the request is finished.
> > > +                    *
> > > +                    * We don't set a callback, as we just want to
> block the
> > > +                    * wait queue and the talloc_free() of the request
> will
> > > +                    * remove the item from the wait queue.
> > > +                    */
> > > +                   subreq = tevent_queue_wait_send(preq, ev,
> state->wait_queue);
> > > +                   if (tevent_req_nomem(subreq, req)) {
> > > +                           return tevent_req_post(req, ev);
> > > +                   }
> > >             }
> > >     }
> > >
> > > --
> > > 1.9.1
> > >
> > >
> > > From 67c3692a5404f888b637328fdb32c6d4d2f748e3 Mon Sep 17 00:00:00 2001
> > > From: Stefan Metzmacher <metze at samba.org>
> > > Date: Fri, 1 May 2015 20:26:41 +0200
> > > Subject: [PATCH 17/17] s3:selftest: run smb2.notify with
> --signing=required
> > >
> > > This reproduces a bug withe implicit canceled requests.
> > >
> > > Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182
> > >
> > > Signed-off-by: Stefan Metzmacher <metze at samba.org>
> > > ---
> > >  source3/selftest/tests.py | 3 +++
> > >  1 file changed, 3 insertions(+)
> > >
> > > diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
> > > index 7436d26..dd06e07 100755
> > > --- a/source3/selftest/tests.py
> > > +++ b/source3/selftest/tests.py
> > > @@ -383,6 +383,9 @@ for t in tests:
> > >      elif t == "local.nss":
> > >          for env in ["nt4_dc:local", "ad_member:local",
> "nt4_member:local", "ad_dc:local", "ad_dc_ntvfs:local"]:
> > >              plansmbtorture4testsuite(t, env, '//$SERVER/tmp
> -U$USERNAME%$PASSWORD')
> > > +    elif t == "smb2.notify":
> > > +        plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp
> -U$USERNAME%$PASSWORD --signing=required')
> > > +        plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp
> -U$USERNAME%$PASSWORD --signing=required')
> > >      else:
> > >          plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp
> -U$USERNAME%$PASSWORD')
> > >          plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp
> -U$USERNAME%$PASSWORD')
> > > --
> > > 1.9.1
> > >
> >
> >
>


More information about the samba-technical mailing list