summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2010-04-06 14:26:29 +0200
committerKarolin Seeger <kseeger@samba.org>2010-05-06 14:08:36 +0200
commit8ff54339230d4cf6862e5c3dac59adff7178a869 (patch)
tree6ed97546927db74a554a0e652d0798823d9b0d42
parentfc37e8163e89975e01c623c19107a6f3caf9573f (diff)
downloadsamba-8ff54339230d4cf6862e5c3dac59adff7178a869.tar.gz
s3:rpc_client: add rpccli_is_connected()
metze (cherry picked from commit 4f41b53487ac9bc96c7960e8edab464558656373) (similar to commit 958b49323968740e2cbf69dc2a0a5dd57d5bcf87) Signed-off-by: Stefan Metzmacher <metze@samba.org> (cherry picked from commit a8a1a6c77a2148a729f6b285f3f945ffd5501256)
-rw-r--r--source3/include/client.h3
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/rpc_client/cli_pipe.c13
-rw-r--r--source3/rpc_client/rpc_transport_np.c78
-rw-r--r--source3/rpc_client/rpc_transport_smbd.c82
-rw-r--r--source3/rpc_client/rpc_transport_sock.c34
6 files changed, 193 insertions, 18 deletions
diff --git a/source3/include/client.h b/source3/include/client.h
index 19142109fd0..bdc6aeb863f 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -110,6 +110,9 @@ struct rpc_cli_transport {
*/
NTSTATUS (*trans_recv)(struct async_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 0b846949dfc..b22c530f08f 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -5275,6 +5275,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 cc0c66c2171..94e714d3b81 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -2961,6 +2961,19 @@ unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
return cli_set_timeout(cli, timeout);
}
+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 5d3ee2bbb27..90c73abe1fa 100644
--- a/source3/rpc_client/rpc_transport_np.c
+++ b/source3/rpc_client/rpc_transport_np.c
@@ -28,11 +28,30 @@ 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)
{
bool ret;
- 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;
}
@@ -51,6 +70,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;
};
@@ -66,13 +86,26 @@ static struct async_req *rpc_np_write_send(TALLOC_CTX *mem_ctx,
priv, struct rpc_transport_np_state);
struct async_req *result, *subreq;
struct rpc_np_write_state *state;
+ bool ok;
if (!async_req_setup(mem_ctx, &result, &state,
struct rpc_np_write_state)) {
return NULL;
}
+
+ ok = rpc_np_is_connected(np_transport);
+ if (!ok) {
+ ok = async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID);
+ if (!ok) {
+ goto fail;
+ }
+ return result;
+ }
+
+ 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. */
@@ -99,6 +132,7 @@ static void rpc_np_write_done(struct async_req *subreq)
status = cli_write_andx_recv(subreq, &state->written);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
+ state->np_transport->cli = NULL;
async_req_nterror(req, status);
return;
}
@@ -119,6 +153,7 @@ static NTSTATUS rpc_np_write_recv(struct async_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;
@@ -135,11 +170,23 @@ static struct async_req *rpc_np_read_send(TALLOC_CTX *mem_ctx,
priv, struct rpc_transport_np_state);
struct async_req *result, *subreq;
struct rpc_np_read_state *state;
+ bool ok;
if (!async_req_setup(mem_ctx, &result, &state,
struct rpc_np_read_state)) {
return NULL;
}
+
+ ok = rpc_np_is_connected(np_transport);
+ if (!ok) {
+ ok = async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID);
+ if (!ok) {
+ goto fail;
+ }
+ return result;
+ }
+
+ state->np_transport = np_transport;
state->data = data;
state->size = size;
@@ -178,18 +225,21 @@ static void rpc_np_read_done(struct async_req *subreq)
}
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(subreq);
+ state->np_transport->cli = NULL;
async_req_nterror(req, status);
return;
}
if (state->received > state->size) {
TALLOC_FREE(subreq);
+ state->np_transport->cli = NULL;
async_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
}
if (state->received == 0) {
TALLOC_FREE(subreq);
+ state->np_transport->cli = NULL;
async_req_nterror(req, NT_STATUS_PIPE_BROKEN);
return;
}
@@ -213,6 +263,7 @@ static NTSTATUS rpc_np_read_recv(struct async_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;
@@ -231,12 +282,23 @@ static struct async_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx,
priv, struct rpc_transport_np_state);
struct async_req *result, *subreq;
struct rpc_np_trans_state *state;
+ bool ok;
if (!async_req_setup(mem_ctx, &result, &state,
struct rpc_np_trans_state)) {
return NULL;
}
+ ok = rpc_np_is_connected(np_transport);
+ if (!ok) {
+ ok = async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID);
+ if (!ok) {
+ goto fail;
+ }
+ return result;
+ }
+
+ state->np_transport = np_transport;
state->max_rdata_len = max_rdata_len;
SSVAL(state->setup+0, 0, TRANSACT_DCERPCCMD);
@@ -273,16 +335,19 @@ static void rpc_np_trans_done(struct async_req *subreq)
status = NT_STATUS_OK;
}
if (!NT_STATUS_IS_OK(status)) {
+ state->np_transport->cli = NULL;
async_req_nterror(req, status);
return;
}
if (state->rdata_len > state->max_rdata_len) {
+ state->np_transport->cli = NULL;
async_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
}
if (state->rdata_len == 0) {
+ state->np_transport->cli = NULL;
async_req_nterror(req, NT_STATUS_PIPE_BROKEN);
return;
}
@@ -319,12 +384,22 @@ struct async_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
{
struct async_req *result, *subreq;
struct rpc_transport_np_init_state *state;
+ bool ok;
if (!async_req_setup(mem_ctx, &result, &state,
struct rpc_transport_np_init_state)) {
return NULL;
}
+ ok = cli_state_is_connected(cli);
+ if (!ok) {
+ ok = async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID);
+ if (!ok) {
+ goto fail;
+ }
+ return result;
+ }
+
state->transport = talloc(state, struct rpc_cli_transport);
if (state->transport == NULL) {
goto fail;
@@ -394,6 +469,7 @@ NTSTATUS rpc_transport_np_init_recv(struct async_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 823f216c128..262caf9ee39 100644
--- a/source3/rpc_client/rpc_transport_smbd.c
+++ b/source3/rpc_client/rpc_transport_smbd.c
@@ -429,8 +429,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;
};
@@ -445,12 +490,23 @@ static struct async_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx,
priv, struct rpc_transport_smbd_state);
struct async_req *result, *subreq;
struct rpc_smbd_write_state *state;
+ bool ok;
if (!async_req_setup(mem_ctx, &result, &state,
struct rpc_smbd_write_state)) {
return NULL;
}
- state->sub_transp = transp->sub_transp;
+
+ ok = rpc_smbd_is_connected(transp);
+ if (!ok) {
+ ok = async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID);
+ if (!ok) {
+ goto fail;
+ }
+ return result;
+ }
+
+ state->transp = transp;
subreq = transp->sub_transp->write_send(state, ev, data, size,
transp->sub_transp->priv);
@@ -480,9 +536,10 @@ static void rpc_smbd_write_done(struct async_req *subreq)
req->private_data, 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);
async_req_nterror(req, status);
return;
}
@@ -503,7 +560,7 @@ static NTSTATUS rpc_smbd_write_recv(struct async_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;
};
@@ -518,12 +575,23 @@ static struct async_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx,
priv, struct rpc_transport_smbd_state);
struct async_req *result, *subreq;
struct rpc_smbd_read_state *state;
+ bool ok;
if (!async_req_setup(mem_ctx, &result, &state,
struct rpc_smbd_read_state)) {
return NULL;
}
- state->sub_transp = transp->sub_transp;
+
+ ok = rpc_smbd_is_connected(transp);
+ if (!ok) {
+ ok = async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID);
+ if (!ok) {
+ goto fail;
+ }
+ return result;
+ }
+
+ state->transp = transp;
subreq = transp->sub_transp->read_send(state, ev, data, size,
transp->sub_transp->priv);
@@ -553,9 +621,10 @@ static void rpc_smbd_read_done(struct async_req *subreq)
req->private_data, 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);
async_req_nterror(req, status);
return;
}
@@ -663,6 +732,7 @@ NTSTATUS rpc_transport_smbd_init_recv(struct async_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 2cc66946902..95e16c381f1 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;
@@ -59,7 +76,7 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
struct rpc_sock_read_state)) {
return NULL;
}
- if (sock_transp->fd == -1) {
+ if (!rpc_sock_is_connected(sock_transp)) {
if (!async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID)) {
goto fail;
}
@@ -97,11 +114,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);
async_req_nterror(req, map_nt_error_from_unix(err));
return;
}
@@ -145,7 +159,7 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,
struct rpc_sock_write_state)) {
return NULL;
}
- if (sock_transp->fd == -1) {
+ if (!rpc_sock_is_connected(sock_transp)) {
if (!async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID)) {
goto fail;
}
@@ -183,11 +197,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);
async_req_nterror(req, map_nt_error_from_unix(err));
return;
}
@@ -235,6 +246,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;