summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2007-02-23 11:00:20 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:48:48 -0500
commit1b17d9a587bf3600d449c2481fe1191793479e32 (patch)
tree56b754f86be6e0facbabc8e41f6fdf1c8232fac9
parentdeea9258536b15d5212db4a72b07fe747442b8f1 (diff)
downloadsamba-1b17d9a587bf3600d449c2481fe1191793479e32.tar.gz
samba-1b17d9a587bf3600d449c2481fe1191793479e32.tar.bz2
samba-1b17d9a587bf3600d449c2481fe1191793479e32.zip
r21515: add some more PFC_FLAGS from the DCERPC spec, and fix some names
also make it possible to pass and get the assoc_group_id for a pipe. also make it possible to pass the DCERPC_PFC_FLAG_CONC_MPX flag in bind requests. From the spec it triggers support for concurrent multiplexing on a single connection. w2k3 uses the assoc_group_id feature when it becomes a domain controller of an existing domain. Know the ugly part, with this it's possible to use a policy handle from one connection on a different one... typically the DsBind() call is on the 1st connection while DsGetNCChanges() call using the first connections bind handle are on the 2nd connection. The second connection also has the DCERPC_PFC_FLAG_CONC_MPX flag attached, but that doesn't seem to be related to the cross connection handle usage Can anyone think of a nice way to implement the assoc_group_id stuff in our server? metze (This used to be commit 2d8c85397d9027485ed6dbdcca87cc1ec84c7b76)
-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;
}