The Samba-Bugzilla – Attachment 5140 Details for
Bug 7022
Add timeout to rpc call to prevent infinite loop.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch for 3.4
1-NCACN_IP_TCP-infinite-loop-v3-4-test-mbox.diff (text/plain), 10.31 KB, created by
Bo Yang
on 2010-01-06 00:49:46 UTC
(
hide
)
Description:
patch for 3.4
Filename:
MIME Type:
Creator:
Bo Yang
Created:
2010-01-06 00:49:46 UTC
Size:
10.31 KB
patch
obsolete
>From 803c155dfd6a0da70266a4f0fba1528147c43df3 Mon Sep 17 00:00:00 2001 >From: Bo Yang <boyang@samba.org> >Date: Thu, 7 Jan 2010 14:00:06 +0800 >Subject: [PATCH] s3: Add timeout to rpc call to prevent infinite loop when network is down. > >Signed-off-by: Bo Yang <boyang@samba.org> >--- > source3/include/async_smb.h | 4 ++ > source3/include/proto.h | 5 +++ > source3/libsmb/async_smb.c | 24 ++++++++++++++ > source3/rpc_client/cli_pipe.c | 41 +++++++++++++++++++++-- > source3/rpc_client/rpc_transport_np.c | 12 +++++++ > source3/rpc_client/rpc_transport_smbd.c | 10 ++++++ > source3/rpc_client/rpc_transport_sock.c | 53 +++++++++++++++++++++++++++++++ > source3/winbindd/winbindd_cm.c | 3 +- > 8 files changed, 147 insertions(+), 5 deletions(-) > >diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h >index 7fc4ff7..f3f4f24 100644 >--- a/source3/include/async_smb.h >+++ b/source3/include/async_smb.h >@@ -96,6 +96,10 @@ struct cli_request { > } echo; > } data; > >+ /* >+ * timer used for request timeout. >+ */ >+ struct timed_event *timer; > /** > * For requests that don't follow the strict request/reply pattern > * such as the transaction request family and echo requests it is >diff --git a/source3/include/proto.h b/source3/include/proto.h >index d2ae62c..452496a 100644 >--- a/source3/include/proto.h >+++ b/source3/include/proto.h >@@ -5379,6 +5379,7 @@ NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli, > const struct ndr_syntax_id *abstract_syntax, > struct rpc_cli_transport **presult); > struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p); >+void rpccli_close_np_fd(struct rpc_pipe_client *p); > > /* The following definitions come from rpc_client/rpc_transport_smbd.c */ > >@@ -5409,11 +5410,15 @@ NTSTATUS rpc_transport_smbd_init(TALLOC_CTX *mem_ctx, > struct rpc_cli_smbd_conn *conn, > const struct ndr_syntax_id *abstract_syntax, > struct rpc_cli_transport **presult); >+struct cli_state *rpc_pipe_smbd_smb_conn(struct rpc_pipe_client *p); > > /* The following definitions come from rpc_client/rpc_transport_sock.c */ > > NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd, > struct rpc_cli_transport **presult); >+int rpccli_set_sock_timeout(struct rpc_pipe_client *rpccli, int timeout); >+void rpccli_close_sock_fd(struct rpc_pipe_client *rpccli); >+bool rpc_pipe_tcp_connection_ok(struct rpc_pipe_client *rpccli); > > /* The following definitions come from rpc_client/cli_reg.c */ > >diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c >index 07d832e..1429911 100644 >--- a/source3/libsmb/async_smb.c >+++ b/source3/libsmb/async_smb.c >@@ -433,6 +433,24 @@ static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx, > return NULL; > } > >+static void request_timeout_handler(struct event_context *ctx, >+ struct timed_event *te, >+ struct timeval now, >+ void *private_data) >+{ >+ struct cli_request *cli_req = talloc_get_type_abort(private_data, struct cli_request); >+ int num_async = cli_req->num_async; >+ int i; >+ TALLOC_FREE(cli_req->timer); >+ for (i = 0; i < num_async; i++) { >+ if (cli_req->async[i]) { >+ async_req_nterror(cli_req->async[i], NT_STATUS_IO_TIMEOUT); >+ return; >+ } >+ } >+ return; >+} >+ > /** > * @brief prepare a cli_state to accept a chain of requests > * @param[in] cli The cli_state we want to queue up in >@@ -460,6 +478,7 @@ bool cli_chain_cork(struct cli_state *cli, struct event_context *ev, > size_t size_hint) > { > struct cli_request *req = NULL; >+ struct timeval endtime; > > SMB_ASSERT(cli->chain_accumulator == NULL); > >@@ -499,6 +518,11 @@ bool cli_chain_cork(struct cli_state *cli, struct event_context *ev, > > req->enc_state = NULL; > req->recv_helper.fn = NULL; >+ endtime = timeval_current_ofs(0, cli->timeout * 1000); >+ req->timer = event_add_timed(ev, req, endtime, request_timeout_handler, req); >+ if (!req->timer) { >+ goto fail; >+ } > > SSVAL(req->outbuf, smb_tid, cli->cnum); > cli_setup_packet_buf(cli, (char *)req->outbuf); >diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c >index 323f861..49b8763 100644 >--- a/source3/rpc_client/cli_pipe.c >+++ b/source3/rpc_client/cli_pipe.c >@@ -2325,6 +2325,21 @@ NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, > } > > status = rpc_api_pipe_req_recv(req, mem_ctx, out_data); >+ >+ /* >+ * NT_STATUS_IO_TIMEOUT indicates network problem, >+ * tear the connection apart. >+ */ >+ if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { >+ if (cli->transport->transport == NCACN_IP_TCP || >+ cli->transport->transport == NCALRPC) { >+ rpccli_close_sock_fd(cli); >+ } >+ >+ if (cli->transport->transport == NCACN_NP) { >+ rpccli_close_np_fd(cli); >+ } >+ } > fail: > TALLOC_FREE(frame); > return status; >@@ -2953,12 +2968,30 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, > unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli, > unsigned int timeout) > { >- struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli); >+ struct cli_state *cli; > >- if (cli == NULL) { >- return 0; >+ if (rpc_cli->transport->transport == NCACN_NP) { >+ cli = rpc_pipe_np_smb_conn(rpc_cli); >+ if (cli == NULL) { >+ return 0; >+ } >+ return cli_set_timeout(cli, timeout); >+ } >+ >+ if (rpc_cli->transport->transport == NCACN_IP_TCP || >+ rpc_cli->transport->transport == NCALRPC) { >+ return rpccli_set_sock_timeout(rpc_cli, timeout); > } >- return cli_set_timeout(cli, timeout); >+ >+ if (rpc_cli->transport->transport == NCACN_INTERNAL) { >+ cli = rpc_pipe_smbd_smb_conn(rpc_cli); >+ if (!cli) { >+ return 0; >+ } >+ return cli_set_timeout(cli, timeout); >+ } >+ >+ return 0; > } > > bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16]) >diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c >index 80ff384..aa2ed54 100644 >--- a/source3/rpc_client/rpc_transport_np.c >+++ b/source3/rpc_client/rpc_transport_np.c >@@ -407,3 +407,15 @@ struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p) > } > return state->cli; > } >+ >+void rpccli_close_np_fd(struct rpc_pipe_client *p) >+{ >+ struct cli_state *cli = rpc_pipe_np_smb_conn(p); >+ if (cli) { >+ if (cli->fd != -1) { >+ close(cli->fd); >+ cli->fd = -1; >+ } >+ } >+ return; >+} >diff --git a/source3/rpc_client/rpc_transport_smbd.c b/source3/rpc_client/rpc_transport_smbd.c >index 823f216..10fc203 100644 >--- a/source3/rpc_client/rpc_transport_smbd.c >+++ b/source3/rpc_client/rpc_transport_smbd.c >@@ -699,3 +699,13 @@ NTSTATUS rpc_transport_smbd_init(TALLOC_CTX *mem_ctx, > TALLOC_FREE(frame); > return status; > } >+ >+struct cli_state *rpc_pipe_smbd_smb_conn(struct rpc_pipe_client *p) >+{ >+ struct rpc_transport_smbd_state *state = talloc_get_type(p->transport->priv, >+ struct rpc_transport_smbd_state); >+ if (!state || !state->conn) { >+ return NULL; >+ } >+ return state->conn->cli; >+} >diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c >index b1d9d8f..77d282b 100644 >--- a/source3/rpc_client/rpc_transport_sock.c >+++ b/source3/rpc_client/rpc_transport_sock.c >@@ -24,6 +24,7 @@ > > struct rpc_transport_sock_state { > int fd; >+ int timeout; > }; > > static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state *s) >@@ -51,16 +52,23 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, > struct async_req *result; > struct tevent_req *subreq; > struct rpc_sock_read_state *state; >+ struct timeval endtime; > > if (!async_req_setup(mem_ctx, &result, &state, > struct rpc_sock_read_state)) { > return NULL; > } > >+ endtime = timeval_current_ofs(0, sock_transp->timeout * 1000); > subreq = async_recv_send(state, ev, sock_transp->fd, data, size, 0); > if (subreq == NULL) { > goto fail; > } >+ >+ if (!tevent_req_set_endtime(subreq, ev, endtime)) { >+ goto fail; >+ } >+ > tevent_req_set_callback(subreq, rpc_sock_read_done, result); > return result; > fail: >@@ -113,15 +121,22 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, > struct async_req *result; > struct tevent_req *subreq; > struct rpc_sock_write_state *state; >+ struct timeval endtime; > > if (!async_req_setup(mem_ctx, &result, &state, > struct rpc_sock_write_state)) { > return NULL; > } >+ endtime = timeval_current_ofs(0, sock_transp->timeout * 1000); > subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0); > if (subreq == NULL) { > goto fail; > } >+ >+ if (!tevent_req_set_endtime(subreq, ev, endtime)) { >+ goto fail; >+ } >+ > tevent_req_set_callback(subreq, rpc_sock_write_done, result); > return result; > fail: >@@ -176,6 +191,7 @@ NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd, > result->priv = state; > > state->fd = fd; >+ state->timeout = 10000; /* 10 seconds. */ > talloc_set_destructor(state, rpc_transport_sock_state_destructor); > > result->trans_send = NULL; >@@ -188,3 +204,40 @@ NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd, > *presult = result; > return NT_STATUS_OK; > } >+ >+int rpccli_set_sock_timeout(struct rpc_pipe_client *cli, int timeout) >+{ >+ struct rpc_transport_sock_state *state = talloc_get_type(cli->transport->priv, >+ struct rpc_transport_sock_state); >+ int orig_timeout; >+ if (!state) { >+ return 0; >+ } >+ orig_timeout = state->timeout; >+ state->timeout = timeout; >+ return orig_timeout; >+} >+ >+void rpccli_close_sock_fd(struct rpc_pipe_client *cli) >+{ >+ struct rpc_transport_sock_state *state = talloc_get_type(cli->transport->priv, >+ struct rpc_transport_sock_state); >+ if (state) { >+ if (state->fd != -1) { >+ close(state->fd); >+ state->fd = -1; >+ } >+ } >+ return; >+} >+ >+bool rpc_pipe_tcp_connection_ok(struct rpc_pipe_client *cli) >+{ >+ struct rpc_transport_sock_state *state = talloc_get_type(cli->transport->priv, >+ struct rpc_transport_sock_state); >+ if (state && state->fd != -1) { >+ return true; >+ } >+ >+ return false; >+} >diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c >index 32afe40..d61ec60 100644 >--- a/source3/winbindd/winbindd_cm.c >+++ b/source3/winbindd/winbindd_cm.c >@@ -2200,7 +2200,8 @@ NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain, > > if (conn->lsa_pipe_tcp && > conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP && >- conn->lsa_pipe_tcp->auth->auth_level == PIPE_AUTH_LEVEL_PRIVACY) { >+ conn->lsa_pipe_tcp->auth->auth_level == PIPE_AUTH_LEVEL_PRIVACY && >+ rpc_pipe_tcp_connection_ok(conn->lsa_pipe_tcp)) { > goto done; > } > >-- >1.6.0.2 >
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:
jmcd
:
review+
Actions:
View
Attachments on
bug 7022
: 5140