The Samba-Bugzilla – Attachment 11031 Details for
Bug 11182
Panic triggered by smbd_smb2_request_notify_done() -> smbXsrv_session_find_channel() in smbd
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patches for v4-2-test
tmp42.diff.txt (text/plain), 56.19 KB, created by
Stefan Metzmacher
on 2015-05-07 09:05:58 UTC
(
hide
)
Description:
Patches for v4-2-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2015-05-07 09:05:58 UTC
Size:
56.19 KB
patch
obsolete
>From 02c37ff845fbf3bea4cb14738064af88d3ad7e41 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 1 May 2015 20:04:55 +0200 >Subject: [PATCH 01/18] s3:smbd: add a smbd_notify_cancel_by_map() helper > function > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 2c47fb16089602a42f62124520e58bdcd8c7d053) >--- > 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 ac1a55c..0a0ae83 100644 >--- a/source3/smbd/notify.c >+++ b/source3/smbd/notify.c >@@ -374,6 +374,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. > *****************************************************************************/ >@@ -393,9 +404,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) >@@ -413,9 +422,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); > } > > /**************************************************************************** >-- >1.9.1 > > >From 5691b0db272a1e2ec8c3094259ba25efe1790cd8 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 1 May 2015 20:02:38 +0200 >Subject: [PATCH 02/18] s3:smbd: use STATUS_NOTIFY_CLEANUP when closing a smb2 > directory handle > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit a5981d137461e5715c92a4fb4cdeaa650f34e999) >--- > selftest/knownfail | 1 - > source3/smbd/close.c | 15 +++++++++++---- > 2 files changed, 11 insertions(+), 5 deletions(-) > >diff --git a/selftest/knownfail b/selftest/knownfail >index 2c35a58..febbd2e 100644 >--- a/selftest/knownfail >+++ b/selftest/knownfail >@@ -188,7 +188,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 4fbd442f..fc1d380 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 97be5bc01bc54ebdb15960c7ebc31653c4ed0a15 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 1 May 2015 20:02:38 +0200 >Subject: [PATCH 03/18] s3:smbd: use STATUS_NOTIFY_CLEANUP on smb2 logoff > (explicit and implicit) and tdis > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 5169e9b20c69092d04b596f48ca0e69a46af438f) >--- > source3/smbd/notify.c | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > >diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c >index 0a0ae83..0e4969d 100644 >--- a/source3/smbd/notify.c >+++ b/source3/smbd/notify.c >@@ -378,8 +378,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 9444e35a1dba683fdbbeea8c1dcdcbef38f0e370 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 1 May 2015 20:19:42 +0200 >Subject: [PATCH 04/18] s4:torture/smb2: verify STATUS_NOTIFY_CLEANUP return > value > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 4bfa6b024e530694741c7c07171fa09762578389) >--- > 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 c721d5f..827f5d5 100644 >--- a/source4/torture/smb2/notify.c >+++ b/source4/torture/smb2/notify.c >@@ -1304,6 +1304,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: >@@ -1372,6 +1373,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 e1a52244de571c8996429e4d7047cf1bd038ee39 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 1 May 2015 20:20:50 +0200 >Subject: [PATCH 05/18] s4:torture/smb2: add smb2.notify.close test > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 44f9e1052de81a0a3052997e7e19a01813fbec43) >--- > 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 827f5d5..e9cfeda 100644 >--- a/source4/torture/smb2/notify.c >+++ b/source4/torture/smb2/notify.c >@@ -1313,6 +1313,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 > */ > >@@ -2026,6 +2095,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 b072b09e5751a178f243c30a0c0c60a034125584 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 1 May 2015 20:20:50 +0200 >Subject: [PATCH 06/18] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit a8ec77e86b17213eeb6a51a835639d79e9486223) >--- > 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 e9cfeda..fe496c8 100644 >--- a/source4/torture/smb2/notify.c >+++ b/source4/torture/smb2/notify.c >@@ -1450,6 +1450,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; >@@ -2097,6 +2178,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 a4e0624bb3e8c65481f2890c648abae652291e35 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 2 May 2015 09:57:03 +0200 >Subject: [PATCH 07/18] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit f435c89d61385272bf5b79f82f6e1373908d2b94) >--- > 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 fe496c8..5589559 100644 >--- a/source4/torture/smb2/notify.c >+++ b/source4/torture/smb2/notify.c >@@ -1451,6 +1451,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 > */ > >@@ -2178,6 +2258,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 4f002b94bccda20685fc19bb5f5e97c0236fec07 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 2 May 2015 16:09:40 +0200 >Subject: [PATCH 08/18] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 7fea42110596e8e9da0155d726aaa72223107fbd) >--- > 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 7eca968..14457cf 100644 >--- a/source3/smbd/smbXsrv_session.c >+++ b/source3/smbd/smbXsrv_session.c >@@ -1060,6 +1060,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 20a51d58f1881a099ea7ad109de0893341e34b40 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 2 May 2015 16:17:34 +0200 >Subject: [PATCH 09/18] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit b6c34a07760141bda3e78624d62eb556bb70da65) >--- > 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 14457cf..f38f950 100644 >--- a/source3/smbd/smbXsrv_session.c >+++ b/source3/smbd/smbXsrv_session.c >@@ -1497,6 +1497,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); >@@ -1513,6 +1514,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 6e9c22532c9fc97fe919eb8b247c6d155361adc5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 2 May 2015 09:57:03 +0200 >Subject: [PATCH 10/18] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 4fceb4531ccd6bb1fd6ebd7b6eb5b894959bc010) >--- > 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 eacc5b3..2aed98e 100644 >--- a/source3/smbd/globals.h >+++ b/source3/smbd/globals.h >@@ -535,6 +535,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 f38f950..375d8a2 100644 >--- a/source3/smbd/smbXsrv_session.c >+++ b/source3/smbd/smbXsrv_session.c >@@ -1321,6 +1321,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 0e67689ba0fe8d865893503b38b5137d03f92f27 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 2 May 2015 16:13:27 +0200 >Subject: [PATCH 11/18] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit cc9d52e10f4f1b192171e03674061d4e8e6bcc84) >--- > 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 375d8a2..d968008 100644 >--- a/source3/smbd/smbXsrv_session.c >+++ b/source3/smbd/smbXsrv_session.c >@@ -222,6 +222,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 = >@@ -326,20 +328,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); >@@ -355,6 +359,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 545046f02eeb855f84cb3fd8d7e87cf18f457281 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 2 May 2015 16:20:06 +0200 >Subject: [PATCH 12/18] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 95057fe375348b918cb2ca58109f4c110a4a5f77) >--- > 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 57f623a..b52ed7d0 100644 >--- a/source3/smbd/smb2_sesssetup.c >+++ b/source3/smbd/smb2_sesssetup.c >@@ -855,95 +855,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 f6cbfb41f80c1258057c5cb5fbf21fec18c15755 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 2 May 2015 16:27:26 +0200 >Subject: [PATCH 13/18] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 8f0d4d1132b74615dc6198ab736590dec52effda) >--- > 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 b52ed7d0..b1ba29e 100644 >--- a/source3/smbd/smb2_sesssetup.c >+++ b/source3/smbd/smb2_sesssetup.c >@@ -363,7 +363,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; > } >@@ -582,6 +581,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 2e16aef0ec4abfbd3a7bacf8e2e30ee7c8fbe0e5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 2 May 2015 16:21:25 +0200 >Subject: [PATCH 14/18] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 50aeb6b38b14d6c26229834ece3c32eb50f9e56a) >--- > 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 b1ba29e..c5eec57 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)) { >@@ -783,6 +783,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 e18aa36d8b5d879241b79a39d78ed6745dcb642c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 2 May 2015 16:29:03 +0200 >Subject: [PATCH 15/18] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 5871d3da871349cba058bb91218ae58107cf05c8) >--- > 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 c5eec57..85f8a9a 100644 >--- a/source3/smbd/smb2_sesssetup.c >+++ b/source3/smbd/smb2_sesssetup.c >@@ -443,94 +443,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, >@@ -572,8 +490,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, >@@ -604,11 +520,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, >@@ -663,9 +574,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; > } >@@ -730,9 +638,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; > } >@@ -747,9 +652,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 eeb39ea1895b50b8f524a2f968a6778474a5c16e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 1 May 2015 16:50:55 +0200 >Subject: [PATCH 16/18] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit f71941491bbba20f394bd2f44425d7c21e90ba92) >--- > 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 278fb6f..8a6d339 100644 >--- a/source3/smbd/smb2_tcon.c >+++ b/source3/smbd/smb2_tcon.c >@@ -497,8 +497,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); >@@ -517,35 +516,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 df4c2a4cd8b5ef7ed686360bd9c43567d490417c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 1 May 2015 20:26:41 +0200 >Subject: [PATCH 17/18] 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@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 40599c3..476652e 100755 >--- a/source3/selftest/tests.py >+++ b/source3/selftest/tests.py >@@ -372,6 +372,9 @@ for t in tests: > elif t == "vfs.fruit": > plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD --option=torture:share1=vfs_fruit --option=torture:share2=tmp --option=torture:localdir=$SELFTEST_PREFIX/s3dc/share') > plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD --option=torture:share1=vfs_fruit --option=torture:share2=tmp --option=torture:localdir=$SELFTEST_PREFIX/plugin_s4_dc/share') >+ elif t == "smb2.notify": >+ plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD --signing=required') >+ plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD --signing=required') > else: > plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD') > plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD') >-- >1.9.1 > > >From 40c2fe7af2c529d36dbb706eff26ba58297fb311 Mon Sep 17 00:00:00 2001 >From: Michael Adam <obnox@samba.org> >Date: Wed, 6 May 2015 17:20:55 +0200 >Subject: [PATCH 18/18] s3:smbXsrv: refactor duplicate code into > smbXsrv_session_clear_and_logoff() > >This replaces code in smbXsrv_session_logoff_all_callback() >and smbXsrv_session_clear_and_logoff(). > >Signed-off-by: Michael Adam <obnox@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=11182 > >Autobuild-User(master): Michael Adam <obnox@samba.org> >Autobuild-Date(master): Thu May 7 10:43:29 CEST 2015 on sn-devel-104 > >(cherry picked from commit c7fcab7999c763acbc0f9dadb7fe05b47a257c7a) >--- > source3/smbd/smbXsrv_session.c | 34 ++++++++++------------------------ > 1 file changed, 10 insertions(+), 24 deletions(-) > >diff --git a/source3/smbd/smbXsrv_session.c b/source3/smbd/smbXsrv_session.c >index d968008..9ec118d 100644 >--- a/source3/smbd/smbXsrv_session.c >+++ b/source3/smbd/smbXsrv_session.c >@@ -1088,7 +1088,7 @@ NTSTATUS smb2srv_session_close_previous_recv(struct tevent_req *req) > return NT_STATUS_OK; > } > >-static int smbXsrv_session_destructor(struct smbXsrv_session *session) >+static NTSTATUS smbXsrv_session_clear_and_logoff(struct smbXsrv_session *session) > { > NTSTATUS status; > struct smbXsrv_connection *xconn = NULL; >@@ -1116,6 +1116,14 @@ static int smbXsrv_session_destructor(struct smbXsrv_session *session) > } > > status = smbXsrv_session_logoff(session); >+ return status; >+} >+ >+static int smbXsrv_session_destructor(struct smbXsrv_session *session) >+{ >+ NTSTATUS status; >+ >+ status = smbXsrv_session_clear_and_logoff(session); > if (!NT_STATUS_IS_OK(status)) { > DEBUG(0, ("smbXsrv_session_destructor: " > "smbXsrv_session_logoff() failed: %s\n", >@@ -1649,7 +1657,6 @@ 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); >@@ -1667,28 +1674,7 @@ static int smbXsrv_session_logoff_all_callback(struct db_record *local_rec, > > 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); >+ status = smbXsrv_session_clear_and_logoff(session); > if (!NT_STATUS_IS_OK(status)) { > if (NT_STATUS_IS_OK(state->first_status)) { > state->first_status = status; >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
obnox
:
review+
metze
:
review?
(
jra
)
Actions:
View
Attachments on
bug 11182
:
10995
|
11012
| 11031 |
11037