From 7ddd2e2be46fc0c478b74323ea32db7836e0bc7d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 13:20:56 +0100 Subject: [PATCH 01/11] s3:libsmb: add cli_state_is_connected() function metze --- 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 dca58cc..0593363 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2316,6 +2316,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 bd5198f5e01f09986fc31dff2373f11f7ad0f65d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 14:08:42 +0100 Subject: [PATCH 02/11] s3:rpc_transport_np: use cli_state_is_connected() helper metze --- 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 de734fe..5b6a2d6 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 a8d0ada283e20bb15b2b2723981d473c59f403ba Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 14:10:25 +0100 Subject: [PATCH 03/11] s3:rpc_transport_np: add comment about bad usage in a destructor metze --- 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 5b6a2d6..96a8988 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 8d7d4d8c336c1e4198e04129f0ec88fee08049ef Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:00:38 +0100 Subject: [PATCH 04/11] s3:rpc_client: add rpccli_is_connected() metze --- source3/include/client.h | 3 + source3/include/proto.h | 1 + source3/rpc_client/cli_pipe.c | 13 +++++ source3/rpc_client/rpc_transport_np.c | 65 ++++++++++++++++++++++++++- source3/rpc_client/rpc_transport_smbd.c | 76 ++++++++++++++++++++++++++++--- source3/rpc_client/rpc_transport_sock.c | 34 +++++++++----- 6 files changed, 174 insertions(+), 18 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index 72cea4a..c8b9063 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 0593363..15b5874 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5288,6 +5288,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 af1ebd6..fd31317 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3093,6 +3093,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 96a8988..055ac81 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -28,9 +28,27 @@ 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 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 +67,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 +83,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 +122,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 +143,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 +160,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 +211,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 +249,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 +268,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 +317,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 +366,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 +374,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 +445,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 ac06fd605d324863c78320f81d961828d1a553b1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:14:02 +0100 Subject: [PATCH 05/11] s3:winbindd_cm: use cli_state_is_connected() helper function metze --- 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 6bdeac1..d9b431a 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -1607,21 +1607,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 c7d82d7db708c7485d456c3e1b72ea648616089d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:15:57 +0100 Subject: [PATCH 06/11] s3:winbindd_cm: use rpccli_is_connected() helper function metze --- 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 d9b431a..24e5556 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2018,7 +2018,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; } @@ -2203,7 +2203,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; } @@ -2245,7 +2245,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; } @@ -2376,7 +2376,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 7753d9d8a8ee90f532063677e426f389cad66e02 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:17:07 +0100 Subject: [PATCH 07/11] s3:winbindd: consistently use TALLOC_FREE(conn->foo_pipe) is we create a new connection metze --- 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 24e5556..c5f9372 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2022,6 +2022,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 @@ -2249,6 +2250,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')) { @@ -2381,6 +2384,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 6205d3f944f0d743f486f591a7ea99573d6736c5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:25:47 +0100 Subject: [PATCH 08/11] s3:winbindd_cm: invalidate connection if cm_connect_netlogon() fails metze --- 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 c5f9372..0f0d5f8 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2464,8 +2464,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 0da15aa00849b5e810b46023c006dcded28ed6b3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:29:05 +0100 Subject: [PATCH 09/11] s3:rpc_client: remove unused code, we handle transport failures in the transport layer now metze --- 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 7d2c33f5441bd6e5896065ab3ed0d1be9758a80c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:51:51 +0100 Subject: [PATCH 10/11] s3:rpc_client: add set_timeout hook to rpc_cli_transport metze --- 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 c8b9063..457c02a 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 fd31317..04549ad 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3067,30 +3067,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 055ac81..b303963 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -46,6 +46,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)) { @@ -446,6 +464,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 22e4b5b9d2eac5f4ebf88ee14368548596118a3a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Mar 2010 15:54:29 +0100 Subject: [PATCH 11/11] s3:rpc_client: remove unused code metze --- source3/include/proto.h | 4 --- source3/rpc_client/rpc_transport_np.c | 12 ---------- source3/rpc_client/rpc_transport_sock.c | 37 ------------------------------- 3 files changed, 0 insertions(+), 53 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 15b5874..d97cb11 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5382,7 +5382,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 */ @@ -5419,9 +5418,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 b303963..ea3d12a 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -512,15 +512,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_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