diff options
-rw-r--r-- | source4/librpc/idl/dcerpc.idl | 11 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 19 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc.h | 6 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_util.c | 5 | ||||
-rw-r--r-- | source4/rpc_server/dcerpc_server.c | 2 |
5 files changed, 32 insertions, 11 deletions
diff --git a/source4/librpc/idl/dcerpc.idl b/source4/librpc/idl/dcerpc.idl index c2818afb4c..75fd051ef1 100644 --- a/source4/librpc/idl/dcerpc.idl +++ b/source4/librpc/idl/dcerpc.idl @@ -245,10 +245,13 @@ interface dcerpc } dcerpc_payload; /* pfc_flags values */ - const uint8 DCERPC_PFC_FLAG_FIRST = 0x01; - const uint8 DCERPC_PFC_FLAG_LAST = 0x02; - const uint8 DCERPC_PFC_FLAG_NOCALL = 0x20; - const uint8 DCERPC_PFC_FLAG_ORPC = 0x80; + const uint8 DCERPC_PFC_FLAG_FIRST = 0x01; /* First fragment */ + const uint8 DCERPC_PFC_FLAG_LAST = 0x02; /* Last fragment */ + const uint8 DCERPC_PFC_FLAG_PENDING_CANCEL = 0x04; /* Cancel was pending at sender */ + const uint8 DCERPC_PFC_FLAG_CONC_MPX = 0x10; /* supports concurrent multiplexing of a single connection. */ + const uint8 DCERPC_PFC_FLAG_DID_NOT_EXECUTE = 0x20; /* on a fault it means the server hasn't done anything */ + const uint8 DCERPC_PFC_FLAG_MAYBE = 0x40; /* `maybe' call semantics requested */ + const uint8 DCERPC_PFC_FLAG_OBJECT_UUID = 0x80; /* on valid guid is in the optional object field */ /* these offsets are needed by the signing code */ const uint8 DCERPC_DREP_OFFSET = 4; diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 288f65e027..0a7417a13f 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -346,7 +346,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } - if (pkt->pfc_flags & DCERPC_PFC_FLAG_ORPC) { + if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; } @@ -625,6 +625,8 @@ static void dcerpc_bind_recv_handler(struct rpc_request *req, if (!composite_is_ok(c)) return; } + req->p->assoc_group_id = pkt->u.bind_ack.assoc_group_id; + composite_done(c); } @@ -648,7 +650,6 @@ static void dcerpc_timeout_handler(struct event_context *ev, struct timed_event } } - /* send a async dcerpc bind request */ @@ -677,9 +678,13 @@ struct composite_context *dcerpc_bind_send(struct dcerpc_pipe *p, pkt.call_id = p->conn->call_id; pkt.auth_length = 0; + if (p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) { + pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX; + } + pkt.u.bind.max_xmit_frag = 5840; pkt.u.bind.max_recv_frag = 5840; - pkt.u.bind.assoc_group_id = 0; + pkt.u.bind.assoc_group_id = p->binding->assoc_group_id; pkt.u.bind.num_contexts = 1; pkt.u.bind.ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1); if (composite_nomem(pkt.u.bind.ctx_list, c)) return c; @@ -1004,7 +1009,7 @@ static void dcerpc_ship_next_request(struct dcerpc_connection *c) if (req->object) { pkt.u.request.object.object = *req->object; - pkt.pfc_flags |= DCERPC_PFC_FLAG_ORPC; + pkt.pfc_flags |= DCERPC_PFC_FLAG_OBJECT_UUID; chunk_size -= ndr_size_GUID(req->object,0); } @@ -1547,9 +1552,13 @@ struct composite_context *dcerpc_alter_context_send(struct dcerpc_pipe *p, pkt.call_id = p->conn->call_id; pkt.auth_length = 0; + if (p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) { + pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX; + } + pkt.u.alter.max_xmit_frag = 5840; pkt.u.alter.max_recv_frag = 5840; - pkt.u.alter.assoc_group_id = 0; + pkt.u.alter.assoc_group_id = p->binding->assoc_group_id; pkt.u.alter.num_contexts = 1; pkt.u.alter.ctx_list = talloc_array(c, struct dcerpc_ctx_list, 1); if (composite_nomem(pkt.u.alter.ctx_list, c)) return c; diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 6bde842371..b9d0f395ee 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -94,6 +94,8 @@ struct dcerpc_connection { struct dcerpc_pipe { uint32_t context_id; + uint32_t assoc_group_id; + struct dcerpc_syntax_id syntax; struct dcerpc_syntax_id transfer_syntax; @@ -151,6 +153,9 @@ struct dcerpc_pipe { /* select NTLM auth */ #define DCERPC_AUTH_NTLM (1<<18) +/* this triggers the DCERPC_PFC_FLAG_CONC_MPX flag in the bind request */ +#define DCERPC_CONCURRENT_MULTIPLEX (1<<19) + /* this is used to find pointers to calls */ @@ -197,6 +202,7 @@ struct dcerpc_binding { const char *endpoint; const char **options; uint32_t flags; + uint32_t assoc_group_id; }; diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 74981d6dce..12760b3ba0 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -65,7 +65,7 @@ NTSTATUS ncacn_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } - if (pkt->pfc_flags & DCERPC_PFC_FLAG_ORPC) { + if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; } @@ -366,6 +366,7 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_ b->options = NULL; b->flags = 0; + b->assoc_group_id = 0; b->endpoint = NULL; if (!options) { @@ -650,6 +651,7 @@ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, binding->host = NULL; binding->target_hostname = NULL; binding->flags = 0; + binding->assoc_group_id = 0; binding->transport = dcerpc_transport_by_tower(tower); @@ -950,6 +952,7 @@ struct composite_context *dcerpc_epm_map_binding_send(TALLOC_CTX *mem_ctx, epmapper_binding->target_hostname = epmapper_binding->host; epmapper_binding->options = NULL; epmapper_binding->flags = 0; + epmapper_binding->assoc_group_id = 0; epmapper_binding->endpoint = NULL; /* initiate rpc pipe connection */ diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 6af4be9cc1..5d718369e4 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -779,7 +779,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) call->context = context; call->ndr_pull = pull; - if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_ORPC) { + if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { pull->flags |= LIBNDR_FLAG_OBJECT_PRESENT; } |