From b3573ce76eb053bf262b4ddea5a0fedf416d1ede Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 6 Aug 2008 21:34:00 +0200 Subject: librpc/rpc: pass struct dcerpc_pipe to dcerpc_auth3() metze (This used to be commit 60b3523da485d845b1d930d990688d8434d39ef3) --- source4/librpc/rpc/dcerpc.c | 13 ++++++++----- source4/librpc/rpc/dcerpc_auth.c | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'source4/librpc') diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 4758189d3b..33a8ed569a 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -790,30 +790,33 @@ NTSTATUS dcerpc_bind_recv(struct composite_context *ctx) /* perform a continued bind (and auth3) */ -NTSTATUS dcerpc_auth3(struct dcerpc_connection *c, +NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { struct ncacn_packet pkt; NTSTATUS status; DATA_BLOB blob; - init_ncacn_hdr(c, &pkt); + init_ncacn_hdr(p->conn, &pkt); pkt.ptype = DCERPC_PKT_AUTH3; pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - pkt.call_id = next_call_id(c); + pkt.call_id = next_call_id(p->conn); pkt.auth_length = 0; pkt.u.auth3._pad = 0; pkt.u.auth3.auth_info = data_blob(NULL, 0); /* construct the NDR form of the packet */ - status = ncacn_push_auth(&blob, mem_ctx, c->iconv_convenience, &pkt, c->security_state.auth_info); + status = ncacn_push_auth(&blob, mem_ctx, + p->conn->iconv_convenience, + &pkt, + p->conn->security_state.auth_info); if (!NT_STATUS_IS_OK(status)) { return status; } /* send it on its way */ - status = c->transport.send_request(c, &blob, false); + status = p->conn->transport.send_request(p->conn, &blob, false); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index f990029f1d..661cd13c5a 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -146,7 +146,7 @@ static void bind_auth_next_step(struct composite_context *c) if (!more_processing) { /* NO reply expected, so just send it */ - c->status = dcerpc_auth3(state->pipe->conn, state); + c->status = dcerpc_auth3(state->pipe, state); if (!composite_is_ok(c)) return; composite_done(c); -- cgit From 50f82609b5833b2f242bc7d5adddeb56480fa2bb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 6 Aug 2008 21:35:07 +0200 Subject: librpc/rpc: add support DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN You can trigger it like this: ncacn_ip_tcp:172.31.9.234[sign,hdrsign] or ncacn_ip_tcp:172.31.9.234[seal,hdrsign] metze (This used to be commit 54f1fca582b1474693b5ee11b7b847086d27f75f) --- source4/librpc/rpc/binding.c | 3 ++- source4/librpc/rpc/dcerpc.c | 26 ++++++++++++++++++++++++++ source4/librpc/rpc/dcerpc.h | 3 +++ source4/librpc/rpc/dcerpc_auth.c | 4 ++++ 4 files changed, 35 insertions(+), 1 deletion(-) (limited to 'source4/librpc') diff --git a/source4/librpc/rpc/binding.c b/source4/librpc/rpc/binding.c index ae88dce1be..bfe62c4054 100644 --- a/source4/librpc/rpc/binding.c +++ b/source4/librpc/rpc/binding.c @@ -83,7 +83,8 @@ static const struct { {"print", DCERPC_DEBUG_PRINT_BOTH}, {"padcheck", DCERPC_DEBUG_PAD_CHECK}, {"bigendian", DCERPC_PUSH_BIGENDIAN}, - {"smb2", DCERPC_SMB2} + {"smb2", DCERPC_SMB2}, + {"hdrsign", DCERPC_HEADER_SIGNING} }; const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 33a8ed569a..a6c7e0020d 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -658,6 +658,16 @@ static void dcerpc_bind_recv_handler(struct rpc_request *req, conn->srv_max_xmit_frag = pkt->u.bind_ack.max_xmit_frag; conn->srv_max_recv_frag = pkt->u.bind_ack.max_recv_frag; + if ((req->p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) && + (pkt->pfc_flags & DCERPC_PFC_FLAG_CONC_MPX)) { + conn->flags |= DCERPC_CONCURRENT_MULTIPLEX; + } + + if ((req->p->binding->flags & DCERPC_HEADER_SIGNING) && + (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)) { + conn->flags |= DCERPC_HEADER_SIGNING; + } + /* the bind_ack might contain a reply set of credentials */ if (conn->security_state.auth_info && pkt->u.bind_ack.auth_info.length) { @@ -731,6 +741,10 @@ struct composite_context *dcerpc_bind_send(struct dcerpc_pipe *p, pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX; } + if (p->binding->flags & DCERPC_HEADER_SIGNING) { + pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; + } + pkt.u.bind.max_xmit_frag = 5840; pkt.u.bind.max_recv_frag = 5840; pkt.u.bind.assoc_group_id = p->binding->assoc_group_id; @@ -806,6 +820,14 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p, pkt.u.auth3._pad = 0; pkt.u.auth3.auth_info = data_blob(NULL, 0); + if (p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) { + pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX; + } + + if (p->binding->flags & DCERPC_HEADER_SIGNING) { + pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; + } + /* construct the NDR form of the packet */ status = ncacn_push_auth(&blob, mem_ctx, p->conn->iconv_convenience, @@ -1630,6 +1652,10 @@ struct composite_context *dcerpc_alter_context_send(struct dcerpc_pipe *p, pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX; } + if (p->binding->flags & DCERPC_HEADER_SIGNING) { + pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; + } + pkt.u.alter.max_xmit_frag = 5840; pkt.u.alter.max_recv_frag = 5840; pkt.u.alter.assoc_group_id = p->binding->assoc_group_id; diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 487f9f2eda..1fd56cb052 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -163,6 +163,9 @@ struct dcerpc_pipe { /* this triggers the DCERPC_PFC_FLAG_CONC_MPX flag in the bind request */ #define DCERPC_CONCURRENT_MULTIPLEX (1<<19) +/* this triggers the DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN flag in the bind request */ +#define DCERPC_HEADER_SIGNING (1<<20) + /* this describes a binding to a particular transport/pipe */ struct dcerpc_binding { enum dcerpc_transport_t transport; diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 661cd13c5a..49fc3d9294 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -137,6 +137,10 @@ static void bind_auth_next_step(struct composite_context *c) if (!composite_is_ok(c)) return; + if (state->pipe->conn->flags & DCERPC_HEADER_SIGNING) { + gensec_want_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER); + } + if (state->credentials.length == 0) { composite_done(c); return; -- cgit From 8a01bdc99a3d26cb5d26ccfdb60e0224f295472d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 7 Aug 2008 16:15:26 +0000 Subject: drsuapi.idl: directly use mszip in level 2 This fixes the push because the switch_level doesn't work otherwise because the pointer is the same as for the outer switch_level. metze (This used to be commit a4c81ee68c91b2d7a9abe668e8b23246c5c9b00d) --- source4/librpc/idl/drsuapi.idl | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'source4/librpc') diff --git a/source4/librpc/idl/drsuapi.idl b/source4/librpc/idl/drsuapi.idl index c19da4fa19..88d2126d0b 100644 --- a/source4/librpc/idl/drsuapi.idl +++ b/source4/librpc/idl/drsuapi.idl @@ -662,13 +662,7 @@ interface drsuapi } drsuapi_DsGetNCChangesCompressedCtr; typedef struct { - /* - * this is a bit ugly, as the compression depends on the flags - * in the DsBind(), but only w2k uses DsGetNCChangesReq5 - * and will get DsGetNCChangesCtr2 replies, and w2k only knowns - * about MSZIP and level 1 replies - */ - [switch_is(1|(DRSUAPI_COMPRESSION_TYPE_MSZIP<<16))] drsuapi_DsGetNCChangesCompressedCtr ctr; + drsuapi_DsGetNCChangesMSZIPCtr1 mszip1; } drsuapi_DsGetNCChangesCtr2; typedef struct { -- cgit From 802b4596feabb454a3d573ac9db34a72bc3ca0f9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 11 Aug 2008 17:59:38 +0200 Subject: dcerpc.idl: add DCERPC_AUTH_TRAILER_LENGTH metze (This used to be commit ce36448d74b0c6cdf8928e10c088bf0248a95cf7) --- source4/librpc/idl/dcerpc.idl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/librpc') diff --git a/source4/librpc/idl/dcerpc.idl b/source4/librpc/idl/dcerpc.idl index e54bc2c29f..0fb94e9672 100644 --- a/source4/librpc/idl/dcerpc.idl +++ b/source4/librpc/idl/dcerpc.idl @@ -154,6 +154,8 @@ interface dcerpc [flag(NDR_REMAINING)] DATA_BLOB credentials; } dcerpc_auth; + const uint8 DCERPC_AUTH_TRAILER_LENGTH = 8; + typedef [public] struct { uint32 _pad; [flag(NDR_REMAINING)] DATA_BLOB auth_info; -- cgit From eb81a62d142883f3cef3da4ba29675b70b515883 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 11 Aug 2008 18:00:11 +0200 Subject: librpc/rpc: correct the chunk_size depending on the signature size metze (This used to be commit 50eb0e726405580dc5ca3a8a3b15f3bd674f722a) --- source4/librpc/rpc/dcerpc.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'source4/librpc') diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index a6c7e0020d..28b5cd65a9 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -334,6 +334,7 @@ static NTSTATUS ncacn_pull_request_auth(struct dcerpc_connection *c, TALLOC_CTX */ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, DATA_BLOB *blob, TALLOC_CTX *mem_ctx, + size_t sig_size, struct ncacn_packet *pkt) { NTSTATUS status; @@ -384,8 +385,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, * GENSEC mech does AEAD signing of the packet * headers */ c->security_state.auth_info->credentials - = data_blob_talloc(mem_ctx, NULL, gensec_sig_size(c->security_state.generic_state, - payload_length)); + = data_blob_talloc(mem_ctx, NULL, sig_size); data_blob_clear(&c->security_state.auth_info->credentials); break; @@ -1042,6 +1042,7 @@ static void dcerpc_ship_next_request(struct dcerpc_connection *c) DATA_BLOB blob; uint32_t remaining, chunk_size; bool first_packet = true; + size_t sig_size = 0; req = c->request_queue; if (req == NULL) { @@ -1065,7 +1066,15 @@ static void dcerpc_ship_next_request(struct dcerpc_connection *c) /* we can write a full max_recv_frag size, minus the dcerpc request header size */ - chunk_size = p->conn->srv_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_REQUEST_LENGTH); + chunk_size = p->conn->srv_max_recv_frag; + chunk_size -= DCERPC_REQUEST_LENGTH; + if (c->security_state.generic_state) { + chunk_size -= DCERPC_AUTH_TRAILER_LENGTH; + sig_size = gensec_sig_size(c->security_state.generic_state, + p->conn->srv_max_recv_frag); + chunk_size -= sig_size; + chunk_size -= (chunk_size % 16); + } pkt.ptype = DCERPC_PKT_REQUEST; pkt.call_id = req->call_id; @@ -1101,7 +1110,7 @@ static void dcerpc_ship_next_request(struct dcerpc_connection *c) (stub_data->length - remaining); pkt.u.request.stub_and_verifier.length = chunk; - req->status = ncacn_push_request_sign(p->conn, &blob, req, &pkt); + req->status = ncacn_push_request_sign(p->conn, &blob, req, sig_size, &pkt); if (!NT_STATUS_IS_OK(req->status)) { req->state = RPC_REQUEST_DONE; DLIST_REMOVE(p->conn->pending, req); -- cgit From 0965b22ec561588201a3a79f1f1e316834c8ce0b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 11 Aug 2008 18:14:51 +0200 Subject: dcerpc.idl: remove used DCERPC_MAX_SIGN_SIZE metze (This used to be commit 54b873e49ff363609632fa2862208bf6b4c1b6ed) --- source4/librpc/idl/dcerpc.idl | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/librpc') diff --git a/source4/librpc/idl/dcerpc.idl b/source4/librpc/idl/dcerpc.idl index 0fb94e9672..1c6574b11b 100644 --- a/source4/librpc/idl/dcerpc.idl +++ b/source4/librpc/idl/dcerpc.idl @@ -30,7 +30,6 @@ interface dcerpc } dcerpc_bind; const uint8 DCERPC_REQUEST_LENGTH = 24; - const uint8 DCERPC_MAX_SIGN_SIZE = 64; typedef struct { } dcerpc_empty; -- cgit