From 87e7e8876fb9296f96ea979c7218f7ab50a978c9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 Feb 2010 09:08:16 +0100 Subject: [PATCH 01/16] s3:rpc_transport_np: handle trans rdata like the output of a normal read Inspired by bug #7159. metze (cherry picked from commit 911287285cc4c8485b75edfad3c1ece901a69b0b) --- source3/rpc_client/rpc_transport_np.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-) diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index 1b9c7fc..df7a96f 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -206,6 +206,7 @@ static NTSTATUS rpc_np_read_recv(struct tevent_req *req, ssize_t *preceived) struct rpc_np_trans_state { uint16_t setup[2]; + uint32_t max_rdata_len; uint8_t *rdata; uint32_t rdata_len; }; @@ -228,6 +229,8 @@ static struct tevent_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx, return NULL; } + state->max_rdata_len = max_rdata_len; + SSVAL(state->setup+0, 0, TRANSACT_DCERPCCMD); SSVAL(state->setup+1, 0, np_transport->fnum); @@ -257,10 +260,24 @@ static void rpc_np_trans_done(struct tevent_req *subreq) status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, &state->rdata, &state->rdata_len); TALLOC_FREE(subreq); + if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) { + status = NT_STATUS_OK; + } if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); return; } + + if (state->rdata_len > state->max_rdata_len) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + if (state->rdata_len == 0) { + tevent_req_nterror(req, NT_STATUS_PIPE_BROKEN); + return; + } + tevent_req_done(req); } -- 1.6.3.3 From 76efe93ebfcdff5855365c6d00f2c149d079675c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Mar 2010 18:23:40 +0200 Subject: [PATCH 02/16] s3:libsmb: don't let cli_shutdown() segfault with a NULL cli_state metze (similar to commit 47e10ab9a85960c78af807b66b99bcd139713644) --- source3/libsmb/clientgen.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1ea8033..b9f0024 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -695,6 +695,10 @@ void cli_nt_pipes_close(struct cli_state *cli) void cli_shutdown(struct cli_state *cli) { + if (cli == NULL) { + return; + } + if (cli->prev == NULL) { /* * Possible head of a DFS list, -- 1.6.3.3 From aee33dc893df25df230d752f980832ed2964d193 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 13:20:56 +0100 Subject: [PATCH 03/16] s3:libsmb: add cli_state_is_connected() function metze (cherry picked from commit d7bf30ef92031ffddcde3680b38e602510bcae24) --- source3/include/proto.h | 1 + source3/libsmb/clierror.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 65fd9a8..4e2c75f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2334,6 +2334,7 @@ bool cli_is_dos_error(struct cli_state *cli); NTSTATUS cli_get_nt_error(struct cli_state *cli); void cli_set_nt_error(struct cli_state *cli, NTSTATUS status); void cli_reset_error(struct cli_state *cli); +bool cli_state_is_connected(struct cli_state *cli); /* The following definitions come from libsmb/clifile.c */ diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 54f8a7a..015afb1 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -359,3 +359,21 @@ void cli_reset_error(struct cli_state *cli) SSVAL(cli->inbuf,smb_err,0); } } + +bool cli_state_is_connected(struct cli_state *cli) +{ + if (cli == NULL) { + return false; + } + + if (!cli->initialised) { + return false; + } + + if (cli->fd == -1) { + return false; + } + + return true; +} + -- 1.6.3.3 From 91f053241074bfc8f989c7540eb13f58051f3b0b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 14:08:42 +0100 Subject: [PATCH 04/16] s3:rpc_transport_np: use cli_state_is_connected() helper metze (cherry picked from commit b862351da8624df893ec77e020a456c1d23c58ed) --- source3/rpc_client/rpc_transport_np.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index df7a96f..7ac0fa1 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -30,7 +30,7 @@ struct rpc_transport_np_state { static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s) { - if (s->cli->fd == -1) { + if (!cli_state_is_connected(s->cli)) { DEBUG(10, ("socket was closed, no need to send close request.\n")); return 0; } -- 1.6.3.3 From f6d8a1c4b4d14ab28ab7daf56c6d0717c66229cc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 14:10:25 +0100 Subject: [PATCH 05/16] s3:rpc_transport_np: add comment about bad usage in a destructor metze (cherry picked from commit 5f8fc63515a02aaf55719cb8d3be8ce695178fe9) --- source3/rpc_client/rpc_transport_np.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index 7ac0fa1..014ce92 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -34,7 +34,8 @@ static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s) DEBUG(10, ("socket was closed, no need to send close request.\n")); return 0; } - + + /* TODO: do not use a sync call with a destructor!!! */ if (!NT_STATUS_IS_OK(cli_close(s->cli, s->fnum))) { DEBUG(1, ("rpc_transport_np_state_destructor: cli_close " "failed on pipe %s. Error was %s\n", s->pipe_name, -- 1.6.3.3 From 79098a006d17203992ffd1471c03c5a7718ce7ec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Mar 2010 14:58:19 +0200 Subject: [PATCH 06/16] s3:rpc_client: don't mix layers and keep a reference to cli_state in the caller We should not rely on the backend to have a reference to the cli_state. This will make it possible for the backend to set its cli_state reference to NULL, when the transport is dead. metze (cherry picked from commit dc09b12681ea0e6d4c2b0f1c99dfeb1f23019c65) --- source3/rpc_client/cli_pipe.c | 25 +++++++++++++++++-------- 1 files changed, 17 insertions(+), 8 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2f84828..bb037e8 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3562,14 +3562,14 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, return status; } -static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p) -{ +struct rpc_pipe_client_np_ref { struct cli_state *cli; + struct rpc_pipe_client *pipe; +}; - cli = rpc_pipe_np_smb_conn(p); - if (cli != NULL) { - DLIST_REMOVE(cli->pipe_list, p); - } +static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref) +{ + DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe); return 0; } @@ -3592,6 +3592,7 @@ static NTSTATUS rpc_pipe_open_np(struct cli_state *cli, { struct rpc_pipe_client *result; NTSTATUS status; + struct rpc_pipe_client_np_ref *np_ref; /* sanity check to protect against crashes */ @@ -3630,8 +3631,16 @@ static NTSTATUS rpc_pipe_open_np(struct cli_state *cli, result->transport->transport = NCACN_NP; - DLIST_ADD(cli->pipe_list, result); - talloc_set_destructor(result, rpc_pipe_client_np_destructor); + np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref); + if (np_ref == NULL) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + np_ref->cli = cli; + np_ref->pipe = result; + + DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe); + talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor); *presult = result; return NT_STATUS_OK; -- 1.6.3.3 From b837acc4d3995689cd804ee7c49215d4841f9e17 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:00:38 +0100 Subject: [PATCH 07/16] s3:rpc_client: add rpccli_is_connected() metze (cherry picked from commit 4f41b53487ac9bc96c7960e8edab464558656373) --- source3/include/client.h | 3 + source3/include/proto.h | 1 + source3/rpc_client/cli_pipe.c | 13 +++++ source3/rpc_client/rpc_transport_np.c | 66 ++++++++++++++++++++++++++- source3/rpc_client/rpc_transport_smbd.c | 76 ++++++++++++++++++++++++++++--- source3/rpc_client/rpc_transport_sock.c | 34 +++++++++----- 6 files changed, 175 insertions(+), 18 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index cc32cd1..252d9b3 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -110,6 +110,9 @@ struct rpc_cli_transport { */ NTSTATUS (*trans_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **prdata, uint32_t *prdata_len); + + bool (*is_connected)(void *priv); + void *priv; }; diff --git a/source3/include/proto.h b/source3/include/proto.h index 4e2c75f..3da0ff8 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5292,6 +5292,7 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, struct cli_pipe_auth_data *auth); unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, unsigned int timeout); +bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli); bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16]); NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, struct cli_pipe_auth_data **presult); diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index bb037e8..e27f829 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3060,6 +3060,19 @@ unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli, return 0; } +bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli) +{ + if (rpc_cli == NULL) { + return false; + } + + if (rpc_cli->transport == NULL) { + return false; + } + + return rpc_cli->transport->is_connected(rpc_cli->transport->priv); +} + bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16]) { struct cli_state *cli; diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index 014ce92..0fe3d02 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -28,9 +28,28 @@ struct rpc_transport_np_state { uint16_t fnum; }; +static bool rpc_np_is_connected(void *priv) +{ + struct rpc_transport_np_state *np_transport = talloc_get_type_abort( + priv, struct rpc_transport_np_state); + bool ok; + + if (np_transport->cli == NULL) { + return false; + } + + ok = cli_state_is_connected(np_transport->cli); + if (!ok) { + np_transport->cli = NULL; + return false; + } + + return true; +} + static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s) { - if (!cli_state_is_connected(s->cli)) { + if (!rpc_np_is_connected(s)) { DEBUG(10, ("socket was closed, no need to send close request.\n")); return 0; } @@ -49,6 +68,7 @@ static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s) } struct rpc_np_write_state { + struct rpc_transport_np_state *np_transport; size_t size; size_t written; }; @@ -64,13 +84,23 @@ static struct tevent_req *rpc_np_write_send(TALLOC_CTX *mem_ctx, priv, struct rpc_transport_np_state); struct tevent_req *req, *subreq; struct rpc_np_write_state *state; + bool ok; req = tevent_req_create(mem_ctx, &state, struct rpc_np_write_state); if (req == NULL) { return NULL; } + + ok = rpc_np_is_connected(np_transport); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID); + return tevent_req_post(req, ev); + } + + state->np_transport = np_transport; state->size = size; + subreq = cli_write_andx_send(mem_ctx, ev, np_transport->cli, np_transport->fnum, 8, /* 8 means message mode. */ @@ -93,6 +123,7 @@ static void rpc_np_write_done(struct tevent_req *subreq) status = cli_write_andx_recv(subreq, &state->written); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { + state->np_transport->cli = NULL; tevent_req_nterror(req, status); return; } @@ -113,6 +144,7 @@ static NTSTATUS rpc_np_write_recv(struct tevent_req *req, ssize_t *pwritten) } struct rpc_np_read_state { + struct rpc_transport_np_state *np_transport; uint8_t *data; size_t size; ssize_t received; @@ -129,11 +161,20 @@ static struct tevent_req *rpc_np_read_send(TALLOC_CTX *mem_ctx, priv, struct rpc_transport_np_state); struct tevent_req *req, *subreq; struct rpc_np_read_state *state; + bool ok; req = tevent_req_create(mem_ctx, &state, struct rpc_np_read_state); if (req == NULL) { return NULL; } + + ok = rpc_np_is_connected(np_transport); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID); + return tevent_req_post(req, ev); + } + + state->np_transport = np_transport; state->data = data; state->size = size; @@ -171,18 +212,21 @@ static void rpc_np_read_done(struct tevent_req *subreq) } if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(subreq); + state->np_transport->cli = NULL; tevent_req_nterror(req, status); return; } if (state->received > state->size) { TALLOC_FREE(subreq); + state->np_transport->cli = NULL; tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); return; } if (state->received == 0) { TALLOC_FREE(subreq); + state->np_transport->cli = NULL; tevent_req_nterror(req, NT_STATUS_PIPE_BROKEN); return; } @@ -206,6 +250,7 @@ static NTSTATUS rpc_np_read_recv(struct tevent_req *req, ssize_t *preceived) } struct rpc_np_trans_state { + struct rpc_transport_np_state *np_transport; uint16_t setup[2]; uint32_t max_rdata_len; uint8_t *rdata; @@ -224,12 +269,20 @@ static struct tevent_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx, priv, struct rpc_transport_np_state); struct tevent_req *req, *subreq; struct rpc_np_trans_state *state; + bool ok; req = tevent_req_create(mem_ctx, &state, struct rpc_np_trans_state); if (req == NULL) { return NULL; } + ok = rpc_np_is_connected(np_transport); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID); + return tevent_req_post(req, ev); + } + + state->np_transport = np_transport; state->max_rdata_len = max_rdata_len; SSVAL(state->setup+0, 0, TRANSACT_DCERPCCMD); @@ -265,16 +318,19 @@ static void rpc_np_trans_done(struct tevent_req *subreq) status = NT_STATUS_OK; } if (!NT_STATUS_IS_OK(status)) { + state->np_transport->cli = NULL; tevent_req_nterror(req, status); return; } if (state->rdata_len > state->max_rdata_len) { + state->np_transport->cli = NULL; tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); return; } if (state->rdata_len == 0) { + state->np_transport->cli = NULL; tevent_req_nterror(req, NT_STATUS_PIPE_BROKEN); return; } @@ -311,6 +367,7 @@ struct tevent_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct rpc_transport_np_init_state *state; + bool ok; req = tevent_req_create(mem_ctx, &state, struct rpc_transport_np_init_state); @@ -318,6 +375,12 @@ struct tevent_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx, return NULL; } + ok = cli_state_is_connected(cli); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID); + return tevent_req_post(req, ev); + } + state->transport = talloc(state, struct rpc_cli_transport); if (tevent_req_nomem(state->transport, req)) { return tevent_req_post(req, ev); @@ -383,6 +446,7 @@ NTSTATUS rpc_transport_np_init_recv(struct tevent_req *req, state->transport->read_recv = rpc_np_read_recv; state->transport->trans_send = rpc_np_trans_send; state->transport->trans_recv = rpc_np_trans_recv; + state->transport->is_connected = rpc_np_is_connected; *presult = talloc_move(mem_ctx, &state->transport); return NT_STATUS_OK; diff --git a/source3/rpc_client/rpc_transport_smbd.c b/source3/rpc_client/rpc_transport_smbd.c index 929e553..47c426f 100644 --- a/source3/rpc_client/rpc_transport_smbd.c +++ b/source3/rpc_client/rpc_transport_smbd.c @@ -419,8 +419,53 @@ NTSTATUS rpc_cli_smbd_conn_init(TALLOC_CTX *mem_ctx, return status; } +static void rpc_smbd_disconnect(struct rpc_transport_smbd_state *transp) +{ + if (transp == NULL) { + return; + } + + if (transp->conn == NULL) { + return; + } + + if (transp->conn->cli == NULL) { + return; + } + + if (transp->conn->cli->fd != -1) { + close(transp->conn->cli->fd); + transp->conn->cli->fd = -1; + } + + transp->conn = NULL; +} + +static bool rpc_smbd_is_connected(void *priv) +{ + struct rpc_transport_smbd_state *transp = talloc_get_type_abort( + priv, struct rpc_transport_smbd_state); + bool ok; + + if (transp->conn == NULL) { + return false; + } + + if (transp->sub_transp == NULL) { + return false; + } + + ok = transp->sub_transp->is_connected(transp->sub_transp->priv); + if (!ok) { + rpc_smbd_disconnect(transp); + return false; + } + + return true; +} + struct rpc_smbd_write_state { - struct rpc_cli_transport *sub_transp; + struct rpc_transport_smbd_state *transp; ssize_t written; }; @@ -435,12 +480,20 @@ static struct tevent_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx, priv, struct rpc_transport_smbd_state); struct tevent_req *req, *subreq; struct rpc_smbd_write_state *state; + bool ok; req = tevent_req_create(mem_ctx, &state, struct rpc_smbd_write_state); if (req == NULL) { return NULL; } - state->sub_transp = transp->sub_transp; + + ok = rpc_smbd_is_connected(transp); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID); + return tevent_req_post(req, ev); + } + + state->transp = transp; subreq = transp->sub_transp->write_send(state, ev, data, size, transp->sub_transp->priv); @@ -468,9 +521,10 @@ static void rpc_smbd_write_done(struct tevent_req *subreq) req, struct rpc_smbd_write_state); NTSTATUS status; - status = state->sub_transp->write_recv(subreq, &state->written); + status = state->transp->sub_transp->write_recv(subreq, &state->written); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { + rpc_smbd_disconnect(state->transp); tevent_req_nterror(req, status); return; } @@ -491,7 +545,7 @@ static NTSTATUS rpc_smbd_write_recv(struct tevent_req *req, ssize_t *pwritten) } struct rpc_smbd_read_state { - struct rpc_cli_transport *sub_transp; + struct rpc_transport_smbd_state *transp; ssize_t received; }; @@ -506,12 +560,20 @@ static struct tevent_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx, priv, struct rpc_transport_smbd_state); struct tevent_req *req, *subreq; struct rpc_smbd_read_state *state; + bool ok; req = tevent_req_create(mem_ctx, &state, struct rpc_smbd_read_state); if (req == NULL) { return NULL; } - state->sub_transp = transp->sub_transp; + + ok = rpc_smbd_is_connected(transp); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID); + return tevent_req_post(req, ev); + } + + state->transp = transp; subreq = transp->sub_transp->read_send(state, ev, data, size, transp->sub_transp->priv); @@ -538,9 +600,10 @@ static void rpc_smbd_read_done(struct tevent_req *subreq) req, struct rpc_smbd_read_state); NTSTATUS status; - status = state->sub_transp->read_recv(subreq, &state->received); + status = state->transp->sub_transp->read_recv(subreq, &state->received); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { + rpc_smbd_disconnect(state->transp); tevent_req_nterror(req, status); return; } @@ -645,6 +708,7 @@ NTSTATUS rpc_transport_smbd_init_recv(struct tevent_req *req, state->transport->read_recv = rpc_smbd_read_recv; state->transport->trans_send = NULL; state->transport->trans_recv = NULL; + state->transport->is_connected = rpc_smbd_is_connected; *presult = talloc_move(mem_ctx, &state->transport); return NT_STATUS_OK; diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index 4ab17db..5132504 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -27,15 +27,32 @@ struct rpc_transport_sock_state { int timeout; }; -static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state *s) +static void rpc_sock_disconnect(struct rpc_transport_sock_state *s) { if (s->fd != -1) { close(s->fd); s->fd = -1; } +} + +static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state *s) +{ + rpc_sock_disconnect(s); return 0; } +static bool rpc_sock_is_connected(void *priv) +{ + struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( + priv, struct rpc_transport_sock_state); + + if (sock_transp->fd == -1) { + return false; + } + + return true; +} + struct rpc_sock_read_state { struct rpc_transport_sock_state *transp; ssize_t received; @@ -58,7 +75,7 @@ static struct tevent_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } - if (sock_transp->fd == -1) { + if (!rpc_sock_is_connected(sock_transp)) { tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID); return tevent_req_post(req, ev); } @@ -94,11 +111,8 @@ static void rpc_sock_read_done(struct tevent_req *subreq) state->received = async_recv_recv(subreq, &err); if (state->received == -1) { - if (state->transp->fd != -1) { - close(state->transp->fd); - state->transp->fd = -1; - } TALLOC_FREE(subreq); + rpc_sock_disconnect(state->transp); tevent_req_nterror(req, map_nt_error_from_unix(err)); return; } @@ -141,7 +155,7 @@ static struct tevent_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } - if (sock_transp->fd == -1) { + if (!rpc_sock_is_connected(sock_transp)) { tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID); return tevent_req_post(req, ev); } @@ -177,11 +191,8 @@ static void rpc_sock_write_done(struct tevent_req *subreq) state->sent = async_send_recv(subreq, &err); if (state->sent == -1) { - if (state->transp->fd != -1) { - close(state->transp->fd); - state->transp->fd = -1; - } TALLOC_FREE(subreq); + rpc_sock_disconnect(state->transp); tevent_req_nterror(req, map_nt_error_from_unix(err)); return; } @@ -229,6 +240,7 @@ NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd, result->write_recv = rpc_sock_write_recv; result->read_send = rpc_sock_read_send; result->read_recv = rpc_sock_read_recv; + result->is_connected = rpc_sock_is_connected; *presult = result; return NT_STATUS_OK; -- 1.6.3.3 From b14f91ab67c6739472f26778ae52f1eaaa30574e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:51:51 +0100 Subject: [PATCH 08/16] s3:rpc_client: add set_timeout hook to rpc_cli_transport metze (cherry picked from commit 99664ad15460530b6fb44957b6c57823f09884bf) --- source3/include/client.h | 1 + source3/rpc_client/cli_pipe.c | 25 +++++-------------------- source3/rpc_client/rpc_transport_np.c | 19 +++++++++++++++++++ source3/rpc_client/rpc_transport_smbd.c | 19 +++++++++++++++++++ source3/rpc_client/rpc_transport_sock.c | 20 ++++++++++++++++++++ 5 files changed, 64 insertions(+), 20 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index 252d9b3..39480d3 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -112,6 +112,7 @@ struct rpc_cli_transport { uint8_t **prdata, uint32_t *prdata_len); bool (*is_connected)(void *priv); + unsigned int (*set_timeout)(void *priv, unsigned int timeout); void *priv; }; diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index e27f829..4fc3658 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3034,30 +3034,15 @@ 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; - - 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); + if (rpc_cli->transport == NULL) { + return 0; } - 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); + if (rpc_cli->transport->set_timeout == NULL) { + return 0; } - return 0; + return rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout); } bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli) diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index 0fe3d02..11cfc85 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -47,6 +47,24 @@ static bool rpc_np_is_connected(void *priv) return true; } +static unsigned int rpc_np_set_timeout(void *priv, unsigned int timeout) +{ + struct rpc_transport_np_state *np_transport = talloc_get_type_abort( + priv, struct rpc_transport_np_state); + bool ok; + + if (np_transport->cli == NULL) { + return false; + } + + ok = rpc_np_is_connected(np_transport); + if (!ok) { + return 0; + } + + return cli_set_timeout(np_transport->cli, timeout); +} + static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s) { if (!rpc_np_is_connected(s)) { @@ -447,6 +465,7 @@ NTSTATUS rpc_transport_np_init_recv(struct tevent_req *req, state->transport->trans_send = rpc_np_trans_send; state->transport->trans_recv = rpc_np_trans_recv; state->transport->is_connected = rpc_np_is_connected; + state->transport->set_timeout = rpc_np_set_timeout; *presult = talloc_move(mem_ctx, &state->transport); return NT_STATUS_OK; diff --git a/source3/rpc_client/rpc_transport_smbd.c b/source3/rpc_client/rpc_transport_smbd.c index 47c426f..690314c 100644 --- a/source3/rpc_client/rpc_transport_smbd.c +++ b/source3/rpc_client/rpc_transport_smbd.c @@ -464,6 +464,24 @@ static bool rpc_smbd_is_connected(void *priv) return true; } +static unsigned int rpc_smbd_set_timeout(void *priv, unsigned int timeout) +{ + struct rpc_transport_smbd_state *transp = talloc_get_type_abort( + priv, struct rpc_transport_smbd_state); + bool ok; + + ok = rpc_smbd_is_connected(transp); + if (!ok) { + return 0; + } + + if (transp->sub_transp->set_timeout == NULL) { + return 0; + } + + return transp->sub_transp->set_timeout(transp->sub_transp->priv, timeout); +} + struct rpc_smbd_write_state { struct rpc_transport_smbd_state *transp; ssize_t written; @@ -709,6 +727,7 @@ NTSTATUS rpc_transport_smbd_init_recv(struct tevent_req *req, state->transport->trans_send = NULL; state->transport->trans_recv = NULL; state->transport->is_connected = rpc_smbd_is_connected; + state->transport->set_timeout = rpc_smbd_set_timeout; *presult = talloc_move(mem_ctx, &state->transport); return NT_STATUS_OK; diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index 5132504..1c49412 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -53,6 +53,25 @@ static bool rpc_sock_is_connected(void *priv) return true; } +static unsigned int rpc_sock_set_timeout(void *priv, unsigned int timeout) +{ + struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( + priv, struct rpc_transport_sock_state); + int orig_timeout; + bool ok; + + ok = rpc_sock_is_connected(sock_transp); + if (!ok) { + return 0; + } + + orig_timeout = sock_transp->timeout; + + sock_transp->timeout = timeout; + + return orig_timeout; +} + struct rpc_sock_read_state { struct rpc_transport_sock_state *transp; ssize_t received; @@ -241,6 +260,7 @@ NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd, result->read_send = rpc_sock_read_send; result->read_recv = rpc_sock_read_recv; result->is_connected = rpc_sock_is_connected; + result->set_timeout = rpc_sock_set_timeout; *presult = result; return NT_STATUS_OK; -- 1.6.3.3 From 670488d977c5947acca23c7c14cc00605d37b484 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Mar 2010 19:34:34 +0200 Subject: [PATCH 09/16] s3:rpc_client: return at least 10 sec as old timeout in rpccli_set_timeout() instead of 0 metze (cherry picked from commit 3e70da3f470eeb122f95477fb48d89939f501b3e) --- source3/rpc_client/cli_pipe.c | 15 ++++++++++++--- 1 files changed, 12 insertions(+), 3 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 4fc3658..ee60c1d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3031,18 +3031,27 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, return status; } +#define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */ + unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli, unsigned int timeout) { + unsigned int old; + if (rpc_cli->transport == NULL) { - return 0; + return RPCCLI_DEFAULT_TIMEOUT; } if (rpc_cli->transport->set_timeout == NULL) { - return 0; + return RPCCLI_DEFAULT_TIMEOUT; + } + + old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout); + if (old == 0) { + return RPCCLI_DEFAULT_TIMEOUT; } - return rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout); + return old; } bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli) -- 1.6.3.3 From 7daffac708602c74844323f3bbddd5d219d6be4b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:14:02 +0100 Subject: [PATCH 10/16] s3:winbindd_cm: use cli_state_is_connected() helper function metze (cherry picked from commit 408a3eb35a0e61b5d66a3b48ebbd1a6796672d0f) --- source3/winbindd/winbindd_cm.c | 18 ++++-------------- 1 files changed, 4 insertions(+), 14 deletions(-) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index ed06dde..e36b456 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -1606,21 +1606,11 @@ void close_conns_after_fork(void) static bool connection_ok(struct winbindd_domain *domain) { - if (domain->conn.cli == NULL) { - DEBUG(8, ("connection_ok: Connection to %s for domain %s has NULL " - "cli!\n", domain->dcname, domain->name)); - return False; - } - - if (!domain->conn.cli->initialised) { - DEBUG(3, ("connection_ok: Connection to %s for domain %s was never " - "initialised!\n", domain->dcname, domain->name)); - return False; - } + bool ok; - if (domain->conn.cli->fd == -1) { - DEBUG(3, ("connection_ok: Connection to %s for domain %s has died or was " - "never started (fd == -1)\n", + ok = cli_state_is_connected(domain->conn.cli); + if (!ok) { + DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n", domain->dcname, domain->name)); return False; } -- 1.6.3.3 From 27fdd870b03b052fb4bd855d8bbc654e8bade894 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:15:57 +0100 Subject: [PATCH 11/16] s3:winbindd_cm: use rpccli_is_connected() helper function metze (cherry picked from commit d980c06a994d032a833adc8d56d2f2c037f8fdaf) --- source3/winbindd/winbindd_cm.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index e36b456..62307d8 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2017,7 +2017,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, conn = &domain->conn; - if (conn->samr_pipe != NULL) { + if (rpccli_is_connected(conn->samr_pipe)) { goto done; } @@ -2202,7 +2202,7 @@ 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 == DCERPC_AUTH_LEVEL_PRIVACY && - rpc_pipe_tcp_connection_ok(conn->lsa_pipe_tcp)) { + rpccli_is_connected(conn->lsa_pipe_tcp)) { goto done; } @@ -2244,7 +2244,7 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, conn = &domain->conn; - if (conn->lsa_pipe != NULL) { + if (rpccli_is_connected(conn->lsa_pipe)) { goto done; } @@ -2375,7 +2375,7 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, conn = &domain->conn; - if (conn->netlogon_pipe != NULL) { + if (rpccli_is_connected(conn->netlogon_pipe)) { *cli = conn->netlogon_pipe; return NT_STATUS_OK; } -- 1.6.3.3 From 5596eba15504223de197b8af9e3d7ec88c59d263 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:17:07 +0100 Subject: [PATCH 12/16] s3:winbindd: consistently use TALLOC_FREE(conn->foo_pipe) is we create a new connection metze (cherry picked from commit 4f391fedac7111683d13f2d79fee7c0dbc27f86e) --- source3/winbindd/winbindd_cm.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 62307d8..96ad9f2 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2021,6 +2021,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, goto done; } + TALLOC_FREE(conn->samr_pipe); /* * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated @@ -2248,6 +2249,8 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, goto done; } + TALLOC_FREE(conn->lsa_pipe); + if ((conn->cli->user_name[0] == '\0') || (conn->cli->domain[0] == '\0') || (conn->cli->password == NULL || conn->cli->password[0] == '\0')) { @@ -2380,6 +2383,8 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, return NT_STATUS_OK; } + TALLOC_FREE(conn->netlogon_pipe); + result = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_netlogon.syntax_id, &netlogon_pipe); -- 1.6.3.3 From 52ff6d57bbbb049399025020ea97fc1bf315b071 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:25:47 +0100 Subject: [PATCH 13/16] s3:winbindd_cm: invalidate connection if cm_connect_netlogon() fails metze (cherry picked from commit 94a4bcd2f0c0464e192556679c6636639cb307ea) --- source3/winbindd/winbindd_cm.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 96ad9f2..e8677bb 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2463,8 +2463,8 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error " "was %s\n", nt_errstr(result))); - /* make sure we return something besides OK */ - return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE; + invalidate_cm_connection(conn); + return result; } /* -- 1.6.3.3 From 7ed4e1bb7cb8f8192a5f101fa9b3048713fc8b76 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Mar 2010 16:31:13 +0200 Subject: [PATCH 14/16] s3:winbindd_reconnect: don't only reconnect on NT_STATUS_UNSUCCESSFUL metze (cherry picked from commit 6bd5a2a3739938f95fce23ab2da652c9b5a48111) --- source3/winbindd/winbindd_reconnect.c | 73 ++++++++++++++++++++++++++------ 1 files changed, 59 insertions(+), 14 deletions(-) diff --git a/source3/winbindd/winbindd_reconnect.c b/source3/winbindd/winbindd_reconnect.c index bf6e577..28fbcb9 100644 --- a/source3/winbindd/winbindd_reconnect.c +++ b/source3/winbindd/winbindd_reconnect.c @@ -27,6 +27,51 @@ extern struct winbindd_methods msrpc_methods; +static bool reconnect_need_retry(NTSTATUS status) +{ + if (NT_STATUS_IS_OK(status)) { + return false; + } + + if (!NT_STATUS_IS_ERR(status)) { + return false; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) { + return false; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) { + return false; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_GROUP)) { + return false; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_ALIAS)) { + return false; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_MEMBER)) { + return false; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) { + return false; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_PRIVILEGE)) { + return false; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) { + return false; + } + + return true; +} + /* List all users */ static NTSTATUS query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, @@ -38,7 +83,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, result = msrpc_methods.query_user_list(domain, mem_ctx, num_entries, info); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.query_user_list(domain, mem_ctx, num_entries, info); return result; @@ -55,7 +100,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, result = msrpc_methods.enum_dom_groups(domain, mem_ctx, num_entries, info); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.enum_dom_groups(domain, mem_ctx, num_entries, info); return result; @@ -73,7 +118,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain, result = msrpc_methods.enum_local_groups(domain, mem_ctx, num_entries, info); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.enum_local_groups(domain, mem_ctx, num_entries, info); @@ -94,7 +139,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, result = msrpc_methods.name_to_sid(domain, mem_ctx, domain_name, name, flags, sid, type); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.name_to_sid(domain, mem_ctx, domain_name, name, flags, sid, type); @@ -117,7 +162,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, result = msrpc_methods.sid_to_name(domain, mem_ctx, sid, domain_name, name, type); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.sid_to_name(domain, mem_ctx, sid, domain_name, name, type); @@ -138,7 +183,7 @@ static NTSTATUS rids_to_names(struct winbindd_domain *domain, result = msrpc_methods.rids_to_names(domain, mem_ctx, sid, rids, num_rids, domain_name, names, types); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { + if (reconnect_need_retry(result)) { result = msrpc_methods.rids_to_names(domain, mem_ctx, sid, rids, num_rids, domain_name, names, @@ -159,7 +204,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain, result = msrpc_methods.query_user(domain, mem_ctx, user_sid, user_info); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.query_user(domain, mem_ctx, user_sid, user_info); @@ -178,7 +223,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, user_sid, num_groups, user_gids); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.lookup_usergroups(domain, mem_ctx, user_sid, num_groups, user_gids); @@ -198,7 +243,7 @@ static NTSTATUS lookup_useraliases(struct winbindd_domain *domain, num_aliases, alias_rids); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.lookup_useraliases(domain, mem_ctx, num_sids, sids, num_aliases, @@ -223,7 +268,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, sid_mem, names, name_types); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.lookup_groupmem(domain, mem_ctx, group_sid, type, num_names, @@ -240,7 +285,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) result = msrpc_methods.sequence_number(domain, seq); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.sequence_number(domain, seq); return result; @@ -255,7 +300,7 @@ static NTSTATUS lockout_policy(struct winbindd_domain *domain, result = msrpc_methods.lockout_policy(domain, mem_ctx, policy); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.lockout_policy(domain, mem_ctx, policy); return result; @@ -270,7 +315,7 @@ static NTSTATUS password_policy(struct winbindd_domain *domain, result = msrpc_methods.password_policy(domain, mem_ctx, policy); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.password_policy(domain, mem_ctx, policy); return result; @@ -285,7 +330,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, result = msrpc_methods.trusted_domains(domain, mem_ctx, trusts); - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) + if (reconnect_need_retry(result)) result = msrpc_methods.trusted_domains(domain, mem_ctx, trusts); -- 1.6.3.3 From 4995411a2451576338ab84b13d432dec130ba808 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:29:05 +0100 Subject: [PATCH 15/16] s3:rpc_client: remove unused code, we handle transport failures in the transport layer now metze (cherry picked from commit 13cf592bb8478453dccd4d78bdb4dabec7aeddc2) --- source3/rpc_client/ndr.c | 14 -------------- 1 files changed, 0 insertions(+), 14 deletions(-) diff --git a/source3/rpc_client/ndr.c b/source3/rpc_client/ndr.c index 4e8634d..5675878 100644 --- a/source3/rpc_client/ndr.c +++ b/source3/rpc_client/ndr.c @@ -183,20 +183,6 @@ NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli, status = cli_do_rpc_ndr_recv(req, mem_ctx); - /* - * 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; -- 1.6.3.3 From 4777ffb004e30b562a88bc3112988ed0641ed5b4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:54:29 +0100 Subject: [PATCH 16/16] s3:rpc_client: remove more unused code metze (cherry picked from commit cac9981b1a88a37c703a76a951b0691fa4ba7b4b) --- source3/include/proto.h | 4 --- source3/rpc_client/rpc_transport_np.c | 12 ---------- source3/rpc_client/rpc_transport_smbd.c | 10 -------- source3/rpc_client/rpc_transport_sock.c | 37 ------------------------------- 4 files changed, 0 insertions(+), 63 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 3da0ff8..28b7f7c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5386,7 +5386,6 @@ 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 */ @@ -5423,9 +5422,6 @@ struct cli_state *rpc_pipe_smbd_smb_conn(struct rpc_pipe_client *p); 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_samr.c */ diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index 11cfc85..9d73581 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -513,15 +513,3 @@ 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 690314c..57fac68 100644 --- a/source3/rpc_client/rpc_transport_smbd.c +++ b/source3/rpc_client/rpc_transport_smbd.c @@ -765,13 +765,3 @@ 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 1c49412..b7bb7d7 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -265,40 +265,3 @@ 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; -} -- 1.6.3.3