From e791b7753c070f977b750c36f8775da1e9332686 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 May 2015 03:00:17 +0200 Subject: [PATCH] s3:libsmb: remove the cli_session_request as early as possible via a nb_connect_cleanup() hook cli_session_request_send() is likely to use tevent_fd objects on the given socket fd, so we need to destroy the request before closing the socket fd. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke (cherry picked from commit 992be06f165c3d05e85d16baf514dba49f55d1ec) --- source3/libsmb/smbsock_connect.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/source3/libsmb/smbsock_connect.c b/source3/libsmb/smbsock_connect.c index 403750d7192..054b8af09e3 100644 --- a/source3/libsmb/smbsock_connect.c +++ b/source3/libsmb/smbsock_connect.c @@ -157,12 +157,13 @@ struct nb_connect_state { const struct sockaddr_storage *addr; const char *called_name; int sock; - + struct tevent_req *session_subreq; struct nmb_name called; struct nmb_name calling; }; -static int nb_connect_state_destructor(struct nb_connect_state *state); +static void nb_connect_cleanup(struct tevent_req *req, + enum tevent_req_state req_state); static void nb_connect_connected(struct tevent_req *subreq); static void nb_connect_done(struct tevent_req *subreq); @@ -189,7 +190,7 @@ static struct tevent_req *nb_connect_send(TALLOC_CTX *mem_ctx, make_nmb_name(&state->called, called_name, called_type); make_nmb_name(&state->calling, calling_name, calling_type); - talloc_set_destructor(state, nb_connect_state_destructor); + tevent_req_set_cleanup_fn(req, nb_connect_cleanup); subreq = open_socket_out_send(state, ev, addr, NBT_SMB_PORT, 5000); if (tevent_req_nomem(subreq, req)) { @@ -199,12 +200,31 @@ static struct tevent_req *nb_connect_send(TALLOC_CTX *mem_ctx, return req; } -static int nb_connect_state_destructor(struct nb_connect_state *state) +static void nb_connect_cleanup(struct tevent_req *req, + enum tevent_req_state req_state) { + struct nb_connect_state *state = tevent_req_data( + req, struct nb_connect_state); + + /* + * we need to free a pending request before closing the + * socket, see bug #11141 + */ + TALLOC_FREE(state->session_subreq); + + if (req_state == TEVENT_REQ_DONE) { + /* + * we keep the socket open for the caller to use + */ + return; + } + if (state->sock != -1) { close(state->sock); + state->sock = -1; } - return 0; + + return; } static void nb_connect_connected(struct tevent_req *subreq) @@ -227,6 +247,7 @@ static void nb_connect_connected(struct tevent_req *subreq) return; } tevent_req_set_callback(subreq, nb_connect_done, req); + state->session_subreq = subreq; } static void nb_connect_done(struct tevent_req *subreq) @@ -239,6 +260,8 @@ static void nb_connect_done(struct tevent_req *subreq) int err; uint8_t resp; + state->session_subreq = NULL; + ret = cli_session_request_recv(subreq, &err, &resp); TALLOC_FREE(subreq); if (!ret) { @@ -286,7 +309,6 @@ static void nb_connect_done(struct tevent_req *subreq) tevent_req_done(req); return; - } static NTSTATUS nb_connect_recv(struct tevent_req *req, int *sock) @@ -296,10 +318,12 @@ static NTSTATUS nb_connect_recv(struct tevent_req *req, int *sock) NTSTATUS status; if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); return status; } *sock = state->sock; state->sock = -1; + tevent_req_received(req); return NT_STATUS_OK; } -- 2.11.4.GIT