diff options
-rw-r--r-- | source4/lib/stream/packet.c | 18 | ||||
-rw-r--r-- | source4/lib/stream/packet.h | 1 | ||||
-rw-r--r-- | source4/libcli/raw/clitransport.c | 11 |
3 files changed, 19 insertions, 11 deletions
diff --git a/source4/lib/stream/packet.c b/source4/lib/stream/packet.c index 7a453add53..a272b28c0c 100644 --- a/source4/lib/stream/packet.c +++ b/source4/lib/stream/packet.c @@ -45,6 +45,7 @@ struct packet_context { BOOL serialise; BOOL processing; BOOL recv_disable; + BOOL nofree; struct send_element { struct send_element *next, *prev; @@ -144,6 +145,14 @@ void packet_set_initial_read(struct packet_context *pc, uint32_t initial_read) pc->initial_read = initial_read; } +/* + tell the packet system not to steal/free blobs given to packet_send() +*/ +void packet_set_nofree(struct packet_context *pc) +{ + pc->nofree = True; +} + /* tell the caller we have an error @@ -427,7 +436,14 @@ NTSTATUS packet_send(struct packet_context *pc, DATA_BLOB blob) DLIST_ADD_END(pc->send_queue, el, struct send_element *); el->blob = blob; el->nsent = 0; - talloc_steal(el, blob.data); + + /* if we aren't going to free the packet then we must reference it + to ensure it doesn't disappear before going out */ + if (pc->nofree) { + talloc_reference(el, blob.data); + } else { + talloc_steal(el, blob.data); + } EVENT_FD_WRITEABLE(pc->fde); diff --git a/source4/lib/stream/packet.h b/source4/lib/stream/packet.h index a8db89853c..4a8c26a809 100644 --- a/source4/lib/stream/packet.h +++ b/source4/lib/stream/packet.h @@ -40,6 +40,7 @@ void packet_set_socket(struct packet_context *pc, struct socket_context *sock); void packet_set_event_context(struct packet_context *pc, struct event_context *ev); void packet_set_serialise(struct packet_context *pc, struct fd_event *fde); void packet_set_initial_read(struct packet_context *pc, uint32_t initial_read); +void packet_set_nofree(struct packet_context *pc); void packet_recv(struct packet_context *pc); void packet_recv_disable(struct packet_context *pc); void packet_recv_enable(struct packet_context *pc); diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 6bf79ecfb0..1cd706f11e 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -105,6 +105,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, packet_set_full_request(transport->packet, packet_full_request_nbt); packet_set_error_handler(transport->packet, smbcli_transport_error); packet_set_event_context(transport->packet, transport->socket->event.ctx); + packet_set_nofree(transport->packet); smbcli_init_signing(transport); @@ -559,16 +560,6 @@ void smbcli_transport_send(struct smbcli_request *req) return; } - /* put it on the socket queue - * - as the buffer is a part of the smbcli_request struct - * we need to reference it here, because packet_queue_run() - * will call talloc_free() on it - */ - if (!talloc_reference(req, req->out.buffer)) { - req->state = SMBCLI_REQUEST_ERROR; - req->status = NT_STATUS_NO_MEMORY; - return; - } blob = data_blob_const(req->out.buffer, req->out.size); status = packet_send(req->transport->packet, blob); if (!NT_STATUS_IS_OK(status)) { |