diff options
author | Jeremy Allison <jra@samba.org> | 2014-03-10 09:53:18 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2014-03-12 09:27:37 -0700 |
commit | 506817dfc9d18c2c5c35d60a6e61a82917665e2d (patch) | |
tree | bd4a48343942ae39e38efc24903f1d05a7d0ce61 /source3/smbd/smb2_sesssetup.c | |
parent | 4d1d288b89d259f1b69eb3ed643b86d39e03f6bf (diff) | |
download | samba-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.c | 112 |
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); } |