*/
#include "includes.h"
-#include "lib/util/dlinklist.h"
+#include "../lib/util/dlinklist.h"
#include "lib/events/events.h"
#include "librpc/rpc/dcerpc.h"
#include "librpc/rpc/dcerpc_proto.h"
#include "auth/gensec/gensec.h"
#include "param/param.h"
-_PUBLIC_ NTSTATUS dcerpc_init(void)
+_PUBLIC_ NTSTATUS dcerpc_init(struct loadparm_context *lp_ctx)
{
- return gensec_init(global_loadparm);
+ return gensec_init(lp_ctx);
}
static void dcerpc_connection_dead(struct dcerpc_connection *conn, NTSTATUS status);
the event context is optional
*/
static struct dcerpc_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
+ struct tevent_context *ev,
struct smb_iconv_convenience *ic)
{
struct dcerpc_connection *c;
c->iconv_convenience = talloc_reference(c, ic);
- c->event_ctx = talloc_reference(c, ev);
+ c->event_ctx = ev;
if (c->event_ctx == NULL) {
talloc_free(c);
}
/* initialise a dcerpc pipe. */
-_PUBLIC_ struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx, struct event_context *ev,
+_PUBLIC_ struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
struct smb_iconv_convenience *ic)
{
struct dcerpc_pipe *p;
ZERO_STRUCT(p->syntax);
ZERO_STRUCT(p->transfer_syntax);
+ if (DEBUGLVL(100)) {
+ p->conn->flags |= DCERPC_DEBUG_PRINT_BOTH;
+ }
+
return p;
}
/*
handle timeouts of individual dcerpc requests
*/
-static void dcerpc_timeout_handler(struct event_context *ev, struct timed_event *te,
- struct timeval t, void *private)
+static void dcerpc_timeout_handler(struct tevent_context *ev, struct tevent_timer *te,
+ struct timeval t, void *private_data)
{
- struct rpc_request *req = talloc_get_type(private, struct rpc_request);
+ struct rpc_request *req = talloc_get_type(private_data, struct rpc_request);
if (req->ignore_timeout) {
dcerpc_req_dequeue(req);
if (req->object) {
pkt.u.request.object.object = *req->object;
pkt.pfc_flags |= DCERPC_PFC_FLAG_OBJECT_UUID;
- chunk_size -= ndr_size_GUID(req->object,0);
+ chunk_size -= ndr_size_GUID(req->object,NULL,0);
}
/* we send a series of pdus without waiting for a reply */
while (remaining > 0 || first_packet) {
uint32_t chunk = MIN(chunk_size, remaining);
bool last_frag = false;
+ bool do_trans = false;
first_packet = false;
pkt.pfc_flags &= ~(DCERPC_PFC_FLAG_FIRST |DCERPC_PFC_FLAG_LAST);
DLIST_REMOVE(p->conn->pending, req);
return;
}
-
- req->status = p->conn->transport.send_request(p->conn, &blob, last_frag);
+
+ if (last_frag && !req->async_call) {
+ do_trans = true;
+ }
+
+ req->status = p->conn->transport.send_request(p->conn, &blob, do_trans);
if (!NT_STATUS_IS_OK(req->status)) {
req->state = RPC_REQUEST_DONE;
DLIST_REMOVE(p->conn->pending, req);
return;
}
+ if (last_frag && !do_trans) {
+ req->status = p->conn->transport.send_read(p->conn);
+ if (!NT_STATUS_IS_OK(req->status)) {
+ req->state = RPC_REQUEST_DONE;
+ DLIST_REMOVE(p->conn->pending, req);
+ return;
+ }
+ }
+
remaining -= chunk;
}
}
return the event context for a dcerpc pipe
used by callers who wish to operate asynchronously
*/
-_PUBLIC_ struct event_context *dcerpc_event_context(struct dcerpc_pipe *p)
+_PUBLIC_ struct tevent_context *dcerpc_event_context(struct dcerpc_pipe *p)
{
return p->conn->event_ctx;
}
NTSTATUS status;
while (req->state != RPC_REQUEST_DONE) {
- struct event_context *ctx = dcerpc_event_context(req->p);
+ struct tevent_context *ctx = dcerpc_event_context(req->p);
if (event_loop_once(ctx) != 0) {
return NT_STATUS_CONNECTION_DISCONNECTED;
}
if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
req->p->last_fault_code = req->fault_code;
}
- talloc_free(req);
+ talloc_unlink(talloc_parent(req), req);
return status;
}
NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
struct GUID *object,
uint16_t opnum,
- bool async,
TALLOC_CTX *mem_ctx,
DATA_BLOB *stub_data_in,
DATA_BLOB *stub_data_out)
{
struct rpc_request *req;
- req = dcerpc_request_send(p, object, opnum, async, stub_data_in);
+ req = dcerpc_request_send(p, object, opnum, false, stub_data_in);
if (req == NULL) {
return NT_STATUS_NO_MEMORY;
}
send a rpc request given a dcerpc_call structure
*/
struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
- const struct GUID *object,
- const struct ndr_interface_table *table,
- uint32_t opnum,
- TALLOC_CTX *mem_ctx,
- void *r)
+ const struct GUID *object,
+ const struct ndr_interface_table *table,
+ uint32_t opnum,
+ bool async,
+ TALLOC_CTX *mem_ctx,
+ void *r)
{
const struct ndr_interface_call *call;
struct ndr_push *push;
dump_data(10, request.data, request.length);
/* make the actual dcerpc request */
- req = dcerpc_request_send(p, object, opnum, table->calls[opnum].async,
- &request);
+ req = dcerpc_request_send(p, object, opnum, async, &request);
if (req != NULL) {
req->ndr.table = table;
ndr_err = call->ndr_pull(pull, NDR_OUT, r);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
- dcerpc_log_packet(table, opnum, NDR_OUT,
- &response);
+ dcerpc_log_packet(p->conn->packet_log_dir,
+ table, opnum, NDR_OUT,
+ &response);
return status;
}
call->ndr_push, call->ndr_pull,
call->ndr_print);
if (!NT_STATUS_IS_OK(status)) {
- dcerpc_log_packet(table, opnum, NDR_OUT,
+ dcerpc_log_packet(p->conn->packet_log_dir,
+ table, opnum, NDR_OUT,
&response);
return status;
}
{
struct rpc_request *req;
- req = dcerpc_ndr_request_send(p, object, table, opnum, mem_ctx, r);
+ req = dcerpc_ndr_request_send(p, object, table, opnum, false, mem_ctx, r);
if (req == NULL) {
return NT_STATUS_NO_MEMORY;
}