struct smb_private {
DATA_BLOB session_key;
- struct tstream_context *stream;
- struct tevent_queue *write_queue;
- struct tevent_req *read_subreq;
- uint32_t pending_reads;
-
/*
* these are needed to open a secondary connection
*/
/*
- tell the dcerpc layer that the transport is dead
+ Tell the dcerpc layer that the transport is dead.
+ This function is declared here because it is going to be private.
*/
-static void pipe_dead(struct dcecli_connection *c, NTSTATUS status)
-{
- struct smb_private *smb = talloc_get_type_abort(
- c->transport.private_data, struct smb_private);
-
- if (smb->stream == NULL) {
- return;
- }
-
- tevent_queue_stop(smb->write_queue);
- TALLOC_FREE(smb->read_subreq);
- TALLOC_FREE(smb->stream);
-
- if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) {
- status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
- }
-
- if (NT_STATUS_EQUAL(NT_STATUS_OK, status)) {
- status = NT_STATUS_END_OF_FILE;
- }
-
- if (c->transport.recv_data) {
- c->transport.recv_data(c, NULL, status);
- }
-}
+void dcerpc_transport_dead(struct dcecli_connection *c, NTSTATUS status);
struct smb_send_read_state {
struct dcecli_connection *p;
static int smb_send_read_state_destructor(struct smb_send_read_state *state)
{
struct dcecli_connection *p = state->p;
- struct smb_private *sock = talloc_get_type_abort(
- p->transport.private_data, struct smb_private);
- sock->read_subreq = NULL;
+ p->transport.read_subreq = NULL;
return 0;
}
p->transport.private_data, struct smb_private);
struct smb_send_read_state *state;
- if (sock->read_subreq != NULL) {
- sock->pending_reads++;
+ if (p->transport.read_subreq != NULL) {
+ p->transport.pending_reads++;
return NT_STATUS_OK;
}
talloc_set_destructor(state, smb_send_read_state_destructor);
- sock->read_subreq = dcerpc_read_ncacn_packet_send(state,
+ p->transport.read_subreq = dcerpc_read_ncacn_packet_send(state,
p->event_ctx,
- sock->stream);
- if (sock->read_subreq == NULL) {
+ p->transport.stream);
+ if (p->transport.read_subreq == NULL) {
return NT_STATUS_NO_MEMORY;
}
- tevent_req_set_callback(sock->read_subreq, smb_send_read_done, state);
+ tevent_req_set_callback(p->transport.read_subreq, smb_send_read_done, state);
return NT_STATUS_OK;
}
tevent_req_callback_data(subreq,
struct smb_send_read_state);
struct dcecli_connection *p = state->p;
- struct smb_private *sock = talloc_get_type_abort(
- p->transport.private_data, struct smb_private);
NTSTATUS status;
struct ncacn_packet *pkt;
DATA_BLOB blob;
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(state);
- pipe_dead(p, status);
+ dcerpc_transport_dead(p, status);
return;
}
talloc_steal(p, blob.data);
TALLOC_FREE(state);
- if (sock->pending_reads > 0) {
- sock->pending_reads--;
+ if (p->transport.pending_reads > 0) {
+ p->transport.pending_reads--;
status = smb_send_read(p);
if (!NT_STATUS_IS_OK(status)) {
- pipe_dead(p, status);
+ dcerpc_transport_dead(p, status);
return;
}
}
static int smb_send_request_state_destructor(struct smb_send_request_state *state)
{
- struct dcecli_connection *p = state->p;
- struct smb_private *sock = talloc_get_type_abort(
- p->transport.private_data, struct smb_private);
-
- sock->read_subreq = NULL;
+ state->p->transport.read_subreq = NULL;
return 0;
}
struct tevent_req *subreq;
bool use_trans = trigger_read;
- if (sock->stream == NULL) {
+ if (p->transport.stream == NULL) {
return NT_STATUS_CONNECTION_DISCONNECTED;
}
state->iov.iov_base = (void *)state->blob.data;
state->iov.iov_len = state->blob.length;
- if (sock->read_subreq != NULL) {
+ if (p->transport.read_subreq != NULL) {
use_trans = false;
}
* we need to block reads until our write is
* the next in the write queue.
*/
- sock->read_subreq = tevent_queue_wait_send(state, p->event_ctx,
- sock->write_queue);
- if (sock->read_subreq == NULL) {
+ p->transport.read_subreq = tevent_queue_wait_send(state, p->event_ctx,
+ p->transport.write_queue);
+ if (p->transport.read_subreq == NULL) {
TALLOC_FREE(state);
return NT_STATUS_NO_MEMORY;
}
- tevent_req_set_callback(sock->read_subreq,
+ tevent_req_set_callback(p->transport.read_subreq,
smb_send_request_wait_done,
state);
}
subreq = tstream_writev_queue_send(state, p->event_ctx,
- sock->stream,
- sock->write_queue,
+ p->transport.stream,
+ p->transport.write_queue,
&state->iov, 1);
if (subreq == NULL) {
TALLOC_FREE(state);
tevent_req_callback_data(subreq,
struct smb_send_request_state);
struct dcecli_connection *p = state->p;
- struct smb_private *sock = talloc_get_type_abort(
- p->transport.private_data, struct smb_private);
NTSTATUS status;
bool ok;
- sock->read_subreq = NULL;
+ p->transport.read_subreq = NULL;
talloc_set_destructor(state, NULL);
ok = tevent_queue_wait_recv(subreq);
if (!ok) {
TALLOC_FREE(state);
- pipe_dead(p, NT_STATUS_NO_MEMORY);
+ dcerpc_transport_dead(p, NT_STATUS_NO_MEMORY);
return;
}
- if (tevent_queue_length(sock->write_queue) <= 2) {
- status = tstream_smbXcli_np_use_trans(sock->stream);
+ if (tevent_queue_length(p->transport.write_queue) <= 2) {
+ status = tstream_smbXcli_np_use_trans(p->transport.stream);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(state);
- pipe_dead(p, status);
+ dcerpc_transport_dead(p, status);
return;
}
}
NTSTATUS status = map_nt_error_from_unix_common(error);
TALLOC_FREE(state);
- pipe_dead(p, status);
+ dcerpc_transport_dead(p, status);
return;
}
struct smb_shutdown_pipe_state *state;
struct tevent_req *subreq;
- if (smb->stream == NULL) {
+ if (c->transport.stream == NULL) {
return NT_STATUS_OK;
}
state->c = c;
state->status = status;
- subreq = tstream_disconnect_send(state, c->event_ctx, smb->stream);
+ subreq = tstream_disconnect_send(state, c->event_ctx, c->transport.stream);
if (subreq == NULL) {
return NT_STATUS_NO_MEMORY;
}
TALLOC_FREE(state);
- pipe_dead(c, status);
+ dcerpc_transport_dead(c, status);
}
/*
ctx->status = tstream_smbXcli_np_open_recv(subreq,
state->smb,
- &state->smb->stream);
+ &state->c->transport.stream);
TALLOC_FREE(subreq);
if (!composite_is_ok(ctx)) return;
- state->smb->write_queue = tevent_queue_create(state->smb,
- "dcerpc_smb write queue");
- if (composite_nomem(state->smb->write_queue, ctx)) return;
+ state->c->transport.write_queue =
+ tevent_queue_create(state->c, "dcerpc_smb write queue");
+ if (composite_nomem(state->c->transport.write_queue, ctx)) return;
/*
fill in the transport methods
const char *path; /* For ncacn_unix_sock and ncalrpc */
struct socket_address *peer_addr;
-
- struct tstream_context *stream;
- struct tevent_queue *write_queue;
- struct tevent_req *read_subreq;
- uint32_t pending_reads;
};
/*
- mark the socket dead
+ Mark the socket dead.
+ This function is declared here because it is going to be private.
*/
-static void sock_dead(struct dcecli_connection *p, NTSTATUS status)
-{
- struct sock_private *sock = talloc_get_type_abort(
- p->transport.private_data, struct sock_private);
-
- if (!sock) return;
-
- tevent_queue_stop(sock->write_queue);
- TALLOC_FREE(sock->read_subreq);
- TALLOC_FREE(sock->stream);
-
- if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) {
- status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
- }
-
- if (NT_STATUS_EQUAL(NT_STATUS_OK, status)) {
- status = NT_STATUS_END_OF_FILE;
- }
-
- if (p->transport.recv_data) {
- p->transport.recv_data(p, NULL, status);
- }
-}
+void dcerpc_transport_dead(struct dcecli_connection *p, NTSTATUS status);
/*
initiate a read request - not needed for dcerpc sockets
static int sock_send_read_state_destructor(struct sock_send_read_state *state)
{
struct dcecli_connection *p = state->p;
- struct sock_private *sock = talloc_get_type_abort(
- p->transport.private_data, struct sock_private);
- sock->read_subreq = NULL;
+ p->transport.read_subreq = NULL;
return 0;
}
p->transport.private_data, struct sock_private);
struct sock_send_read_state *state;
- if (sock->read_subreq != NULL) {
- sock->pending_reads++;
+ if (p->transport.read_subreq != NULL) {
+ p->transport.pending_reads++;
return NT_STATUS_OK;
}
talloc_set_destructor(state, sock_send_read_state_destructor);
- sock->read_subreq = dcerpc_read_ncacn_packet_send(state,
+ p->transport.read_subreq = dcerpc_read_ncacn_packet_send(state,
p->event_ctx,
- sock->stream);
- if (sock->read_subreq == NULL) {
+ p->transport.stream);
+ if (p->transport.read_subreq == NULL) {
return NT_STATUS_NO_MEMORY;
}
- tevent_req_set_callback(sock->read_subreq, sock_send_read_done, state);
+ tevent_req_set_callback(p->transport.read_subreq, sock_send_read_done, state);
return NT_STATUS_OK;
}
tevent_req_callback_data(subreq,
struct sock_send_read_state);
struct dcecli_connection *p = state->p;
- struct sock_private *sock = talloc_get_type_abort(
- p->transport.private_data, struct sock_private);
NTSTATUS status;
struct ncacn_packet *pkt;
DATA_BLOB blob;
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(state);
- sock_dead(p, status);
+ dcerpc_transport_dead(p, status);
return;
}
talloc_steal(p, blob.data);
TALLOC_FREE(state);
- if (sock->pending_reads > 0) {
- sock->pending_reads--;
+ if (p->transport.pending_reads > 0) {
+ p->transport.pending_reads--;
status = sock_send_read(p);
if (!NT_STATUS_IS_OK(status)) {
- sock_dead(p, status);
+ dcerpc_transport_dead(p, status);
return;
}
}
struct sock_send_request_state *state;
struct tevent_req *subreq;
- if (sock->stream == NULL) {
+ if (p->transport.stream == NULL) {
return NT_STATUS_CONNECTION_DISCONNECTED;
}
state->iov.iov_len = state->blob.length;
subreq = tstream_writev_queue_send(state, p->event_ctx,
- sock->stream,
- sock->write_queue,
+ p->transport.stream,
+ p->transport.write_queue,
&state->iov, 1);
if (subreq == NULL) {
TALLOC_FREE(state);
NTSTATUS status = map_nt_error_from_unix_common(error);
TALLOC_FREE(state);
- sock_dead(p, status);
+ dcerpc_transport_dead(p, status);
return;
}
*/
static NTSTATUS sock_shutdown_pipe(struct dcecli_connection *p, NTSTATUS status)
{
- struct sock_private *sock = talloc_get_type_abort(
- p->transport.private_data, struct sock_private);
-
- if (sock && sock->stream) {
- sock_dead(p, status);
+ if (p->transport.stream == NULL) {
+ return NT_STATUS_OK;
}
+ dcerpc_transport_dead(p, status);
+
return status;
}
conn->srv_max_xmit_frag = 5840;
conn->srv_max_recv_frag = 5840;
- sock->pending_reads = 0;
+ conn->transport.pending_reads = 0;
conn->server_name = strupper_talloc(conn, s->target_hostname);
conn->transport.private_data = sock;
rc = tstream_bsd_existing_socket(sock, sock_fd,
- &sock->stream);
+ &conn->transport.stream);
if (rc < 0) {
talloc_free(sock);
composite_error(c, NT_STATUS_NO_MEMORY);
return;
}
- sock->write_queue = tevent_queue_create(sock,
- "dcerpc sock write queue");
- if (sock->write_queue == NULL) {
+ conn->transport.write_queue =
+ tevent_queue_create(conn, "dcerpc sock write queue");
+ if (conn->transport.write_queue == NULL) {
talloc_free(sock);
composite_error(c, NT_STATUS_NO_MEMORY);
return;