summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/idl/dcerpc.idl11
-rw-r--r--source4/librpc/rpc/dcerpc.c19
-rw-r--r--source4/librpc/rpc/dcerpc.h6
-rw-r--r--source4/librpc/rpc/dcerpc_util.c5
-rw-r--r--source4/rpc_server/dcerpc_server.c2
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;
}