summaryrefslogtreecommitdiff
path: root/source3/smbd/smb2_sesssetup.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2014-03-10 09:53:18 +0100
committerJeremy Allison <jra@samba.org>2014-03-12 09:27:37 -0700
commit506817dfc9d18c2c5c35d60a6e61a82917665e2d (patch)
treebd4a48343942ae39e38efc24903f1d05a7d0ce61 /source3/smbd/smb2_sesssetup.c
parent4d1d288b89d259f1b69eb3ed643b86d39e03f6bf (diff)
downloadsamba-506817dfc9d18c2c5c35d60a6e61a82917665e2d.tar.gz
s3:smb2_sesssetup: split smbd_smb2_logoff into an async *_send/recv pair.
Bug: https://bugzilla.samba.org/show_bug.cgi?id=10344 Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> Signed-off-by: Jeremy Allison <jra@samba.org> Signed-off-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source3/smbd/smb2_sesssetup.c')
-rw-r--r--source3/smbd/smb2_sesssetup.c112
1 files changed, 92 insertions, 20 deletions
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 9d7193b14e3..786bfe83b5c 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -788,44 +788,116 @@ static NTSTATUS smbd_smb2_session_setup_recv(struct tevent_req *req,
return status;
}
+static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct smbd_smb2_request *smb2req);
+static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req);
+static void smbd_smb2_request_logoff_done(struct tevent_req *subreq);
+
NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
{
NTSTATUS status;
- DATA_BLOB outbody;
+ struct tevent_req *subreq = NULL;
status = smbd_smb2_request_verify_sizes(req, 0x04);
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
}
+ subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
+ if (subreq == NULL) {
+ return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
+ }
+ tevent_req_set_callback(subreq, smbd_smb2_request_logoff_done, req);
+
/*
- * TODO: cancel all outstanding requests on the session
+ * Wait a long time before going async on this to allow
+ * requests we're waiting on to finish. Set timeout to 10 secs.
*/
- status = smbXsrv_session_logoff(req->session);
+ return smbd_smb2_request_pending_queue(req, subreq, 10000000);
+}
+
+static void smbd_smb2_request_logoff_done(struct tevent_req *subreq)
+{
+ struct smbd_smb2_request *smb2req =
+ tevent_req_callback_data(subreq,
+ struct smbd_smb2_request);
+ DATA_BLOB outbody;
+ NTSTATUS status;
+ NTSTATUS error;
+
+ status = smbd_smb2_logoff_recv(subreq);
+ TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("smbd_smb2_request_process_logoff: "
- "smbXsrv_session_logoff() failed: %s\n",
- nt_errstr(status)));
- /*
- * If we hit this case, there is something completely
- * wrong, so we better disconnect the transport connection.
- */
- return status;
+ error = smbd_smb2_request_error(smb2req, status);
+ if (!NT_STATUS_IS_OK(error)) {
+ smbd_server_connection_terminate(smb2req->sconn,
+ nt_errstr(error));
+ return;
+ }
+ return;
+ }
+
+ outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
+ if (outbody.data == NULL) {
+ error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
+ if (!NT_STATUS_IS_OK(error)) {
+ smbd_server_connection_terminate(smb2req->sconn,
+ nt_errstr(error));
+ return;
+ }
+ return;
+ }
+
+ SSVAL(outbody.data, 0x00, 0x04); /* struct size */
+ SSVAL(outbody.data, 0x02, 0); /* reserved */
+
+ error = smbd_smb2_request_done(smb2req, outbody, NULL);
+ if (!NT_STATUS_IS_OK(error)) {
+ smbd_server_connection_terminate(smb2req->sconn,
+ nt_errstr(error));
+ return;
+ }
+}
+
+struct smbd_smb2_logout_state {
+ struct smbd_smb2_request *smb2req;
+};
+
+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;
+ NTSTATUS status;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct smbd_smb2_logout_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->smb2req = smb2req;
+
+ /*
+ * TODO: cancel all outstanding requests on the session
+ */
+ status = smbXsrv_session_logoff(state->smb2req->session);
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
}
/*
* we may need to sign the response, so we need to keep
* the session until the response is sent to the wire.
*/
- talloc_steal(req, req->session);
-
- outbody = smbd_smb2_generate_outbody(req, 0x04);
- if (outbody.data == NULL) {
- return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
- }
+ talloc_steal(state->smb2req, state->smb2req->session);
- SSVAL(outbody.data, 0x00, 0x04); /* struct size */
- SSVAL(outbody.data, 0x02, 0); /* reserved */
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+}
- return smbd_smb2_request_done(req, outbody, NULL);
+static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
}