From 877cb9b7b3ffe4142c80a59113e8458a7358bfba Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Oct 2018 16:44:11 +0100 Subject: [PATCH 001/103] librpc: add dcerpc_get_auth_length() helper function Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- librpc/rpc/dcerpc_util.c | 9 +++++++++ librpc/rpc/rpc_common.h | 1 + 2 files changed, 10 insertions(+) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index 0808131dd14..6cd3e38a75a 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -59,6 +59,15 @@ void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v) } } +uint16_t dcerpc_get_auth_length(const DATA_BLOB *blob) +{ + if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) { + return SVAL(blob->data, DCERPC_AUTH_LEN_OFFSET); + } else { + return RSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET); + } +} + uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob) { return blob->data[DCERPC_DREP_OFFSET]; diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index cdc9fe8ac88..d5b5d590bff 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -168,6 +168,7 @@ enum dcerpc_transport_t dcerpc_transport_by_tower(const struct epm_tower *tower) void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v); uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob); void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v); +uint16_t dcerpc_get_auth_length(const DATA_BLOB *blob); uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob); const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx, enum dcerpc_transport_t transport, -- 2.20.1.97.g81188d93c3-goog From a630b98e97a1d81215dd382a5b099edf9d6afb30 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Oct 2018 16:44:11 +0100 Subject: [PATCH 002/103] librpc: add dcerpc_get_auth_{type,level,context_id}() helper functions BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- librpc/rpc/dcerpc_util.c | 87 ++++++++++++++++++++++++++++++++++++++++ librpc/rpc/rpc_common.h | 3 ++ 2 files changed, 90 insertions(+) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index 6cd3e38a75a..e0479c2f36b 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -73,6 +73,93 @@ uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob) return blob->data[DCERPC_DREP_OFFSET]; } +static uint16_t dcerpc_get_auth_context_offset(const DATA_BLOB *blob) +{ + uint16_t frag_len = dcerpc_get_frag_length(blob); + uint16_t auth_len = dcerpc_get_auth_length(blob); + uint16_t min_offset; + uint16_t offset; + + if (auth_len == 0) { + return 0; + } + + if (frag_len > blob->length) { + return 0; + } + + if (auth_len > frag_len) { + return 0; + } + + min_offset = DCERPC_NCACN_PAYLOAD_OFFSET + DCERPC_AUTH_TRAILER_LENGTH; + offset = frag_len - auth_len; + if (offset < min_offset) { + return 0; + } + offset -= DCERPC_AUTH_TRAILER_LENGTH; + + return offset; +} + +uint8_t dcerpc_get_auth_type(const DATA_BLOB *blob) +{ + uint16_t offset; + + offset = dcerpc_get_auth_context_offset(blob); + if (offset == 0) { + return 0; + } + + /* + * auth_typw is in the 1st byte + * of the auth trailer + */ + offset += 0; + + return blob->data[offset]; +} + +uint8_t dcerpc_get_auth_level(const DATA_BLOB *blob) +{ + uint16_t offset; + + offset = dcerpc_get_auth_context_offset(blob); + if (offset == 0) { + return 0; + } + + /* + * auth_level is in 2nd byte + * of the auth trailer + */ + offset += 1; + + return blob->data[offset]; +} + +uint32_t dcerpc_get_auth_context_id(const DATA_BLOB *blob) +{ + uint16_t offset; + + offset = dcerpc_get_auth_context_offset(blob); + if (offset == 0) { + return 0; + } + + /* + * auth_context_id is in the last 4 byte + * of the auth trailer + */ + offset += 4; + + if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) { + return IVAL(blob->data, offset); + } else { + return RIVAL(blob->data, offset); + } +} + /** * @brief Decodes a ncacn_packet * diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index d5b5d590bff..f1535d74220 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -170,6 +170,9 @@ uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob); void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v); uint16_t dcerpc_get_auth_length(const DATA_BLOB *blob); uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob); +uint8_t dcerpc_get_auth_type(const DATA_BLOB *blob); +uint8_t dcerpc_get_auth_level(const DATA_BLOB *blob); +uint32_t dcerpc_get_auth_context_id(const DATA_BLOB *blob); const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx, enum dcerpc_transport_t transport, const struct ndr_interface_table *table); -- 2.20.1.97.g81188d93c3-goog From 33464a9c8b19186a075f4cab8eec2d619a649789 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 24 Dec 2018 11:21:38 +0100 Subject: [PATCH 003/103] librpc: add SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET) protection A lot of functions rely on having the 16 bytes dcerpc header to operate on. This makes it more obvious and makes sure they can't be misused in future. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- librpc/rpc/dcerpc_util.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index e0479c2f36b..6bc97f7e7d8 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -34,6 +34,8 @@ decode */ void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v) { + SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET); + if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) { SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v); } else { @@ -43,6 +45,8 @@ void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v) uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob) { + SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET); + if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) { return SVAL(blob->data, DCERPC_FRAG_LEN_OFFSET); } else { @@ -52,6 +56,8 @@ uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob) void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v) { + SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET); + if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) { SSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v); } else { @@ -61,6 +67,8 @@ void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v) uint16_t dcerpc_get_auth_length(const DATA_BLOB *blob) { + SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET); + if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) { return SVAL(blob->data, DCERPC_AUTH_LEN_OFFSET); } else { @@ -70,6 +78,8 @@ uint16_t dcerpc_get_auth_length(const DATA_BLOB *blob) uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob) { + SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET); + return blob->data[DCERPC_DREP_OFFSET]; } -- 2.20.1.97.g81188d93c3-goog From 888c0e94ec4f848626ac1796fa9aab8ecead7564 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 26 Nov 2018 11:06:44 +0100 Subject: [PATCH 004/103] s4:torture: make test_GetUserName() more strict BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/torture/rpc/lsa.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 988d534bed3..bc1e9553039 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -4837,7 +4837,6 @@ static bool test_GetUserName(struct dcerpc_binding_handle *b, struct torture_context *tctx) { struct lsa_GetUserName r; - bool ret = true; struct lsa_String *authority_name_p = NULL; struct lsa_String *account_name_p = NULL; @@ -4850,11 +4849,11 @@ static bool test_GetUserName(struct dcerpc_binding_handle *b, torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r), "GetUserName failed"); - - if (!NT_STATUS_IS_OK(r.out.result)) { - torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result)); - ret = false; - } + torture_assert_ntstatus_ok(tctx, r.out.result, + "GetUserName result failed"); + torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name"); + torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name"); + torture_assert(tctx, r.out.authority_name == NULL, "r.out.authority_name"); account_name_p = NULL; r.in.account_name = &account_name_p; @@ -4863,13 +4862,14 @@ static bool test_GetUserName(struct dcerpc_binding_handle *b, torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r), "GetUserName failed"); + torture_assert_ntstatus_ok(tctx, r.out.result, + "GetUserName result failed"); + torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name"); + torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name"); + torture_assert_not_null(tctx, r.out.authority_name, "r.out.authority_name"); + torture_assert_not_null(tctx, *r.out.authority_name, "*r.out.authority_name"); - if (!NT_STATUS_IS_OK(r.out.result)) { - torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result)); - ret = false; - } - - return ret; + return true; } static bool test_GetUserName_fail(struct dcerpc_binding_handle *b, -- 2.20.1.97.g81188d93c3-goog From cd0c583f548a950fb05c7db111a3e81a6d85adf8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 16 Nov 2018 16:11:50 +0100 Subject: [PATCH 005/103] s4:rpc_server/samr: Fix the O3 developer build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Different gcc versions complain at different places. I recently got these: ../source4/rpc_server/samr/dcesrv_samr.c: In function ‘dcesrv_samr_QueryDisplayInfo2’: ../source4/rpc_server/samr/dcesrv_samr.c:4117:2: error: ‘q.out.result.v’ may be used uninitialized in this function [-Werror=maybe-uninitialized] return result; ^ ../source4/rpc_server/samr/dcesrv_samr.c: In function ‘dcesrv_samr_QueryDisplayInfo3’: ../source4/rpc_server/samr/dcesrv_samr.c:4151:2: error: ‘q.out.result.v’ may be used uninitialized in this function [-Werror=maybe-uninitialized] return result; ^ cc1: all warnings being treated as errors ../source4/rpc_server/samr/dcesrv_samr.c: In function ‘dcesrv_samr_QueryDisplayInfo3’: ../source4/rpc_server/samr/dcesrv_samr.c:4151:2: error: ‘q.out.result.v’ may be used uninitialized in this function [-Werror=maybe-uninitialized] return result; ^ In file included from ../source4/rpc_server/samr/dcesrv_samr.c:4447:0: default/librpc/gen_ndr/ndr_samr_s.c: In function ‘samr__op_dispatch’: default/librpc/gen_ndr/ndr_samr_s.c:597:18: error: ‘q.out.result.v’ may be used uninitialized in this function [-Werror=maybe-uninitialized] r2->out.result = dcesrv_samr_QueryDisplayInfo2(dce_call, mem_ctx, r2); ^ cc1: all warnings being treated as errors BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/samr/dcesrv_samr.c | 92 ++++++++++++++++----------- 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 0a0ab84533b..d7d2fa46684 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -4530,10 +4530,11 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo2(struct dcesrv_call_state *dce_call, struct samr_QueryDomainInfo r1; NTSTATUS status; - ZERO_STRUCT(r1.out); - r1.in.domain_handle = r->in.domain_handle; - r1.in.level = r->in.level; - r1.out.info = r->out.info; + r1 = (struct samr_QueryDomainInfo) { + .in.domain_handle = r->in.domain_handle, + .in.level = r->in.level, + .out.info = r->out.info, + }; status = dcesrv_samr_QueryDomainInfo(dce_call, mem_ctx, &r1); @@ -4573,14 +4574,16 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo2(struct dcesrv_call_state *dce_call struct samr_QueryDisplayInfo q; NTSTATUS result; - q.in.domain_handle = r->in.domain_handle; - q.in.level = r->in.level; - q.in.start_idx = r->in.start_idx; - q.in.max_entries = r->in.max_entries; - q.in.buf_size = r->in.buf_size; - q.out.total_size = r->out.total_size; - q.out.returned_size = r->out.returned_size; - q.out.info = r->out.info; + q = (struct samr_QueryDisplayInfo) { + .in.domain_handle = r->in.domain_handle, + .in.level = r->in.level, + .in.start_idx = r->in.start_idx, + .in.max_entries = r->in.max_entries, + .in.buf_size = r->in.buf_size, + .out.total_size = r->out.total_size, + .out.returned_size = r->out.returned_size, + .out.info = r->out.info, + }; result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q); @@ -4607,14 +4610,16 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo3(struct dcesrv_call_state *dce_call struct samr_QueryDisplayInfo q; NTSTATUS result; - q.in.domain_handle = r->in.domain_handle; - q.in.level = r->in.level; - q.in.start_idx = r->in.start_idx; - q.in.max_entries = r->in.max_entries; - q.in.buf_size = r->in.buf_size; - q.out.total_size = r->out.total_size; - q.out.returned_size = r->out.returned_size; - q.out.info = r->out.info; + q = (struct samr_QueryDisplayInfo) { + .in.domain_handle = r->in.domain_handle, + .in.level = r->in.level, + .in.start_idx = r->in.start_idx, + .in.max_entries = r->in.max_entries, + .in.buf_size = r->in.buf_size, + .out.total_size = r->out.total_size, + .out.returned_size = r->out.returned_size, + .out.info = r->out.info, + }; result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q); @@ -4705,9 +4710,11 @@ static NTSTATUS dcesrv_samr_Connect2(struct dcesrv_call_state *dce_call, TALLOC_ { struct samr_Connect c; - c.in.system_name = NULL; - c.in.access_mask = r->in.access_mask; - c.out.connect_handle = r->out.connect_handle; + c = (struct samr_Connect) { + .in.system_name = NULL, + .in.access_mask = r->in.access_mask, + .out.connect_handle = r->out.connect_handle, + }; return dcesrv_samr_Connect(dce_call, mem_ctx, &c); } @@ -4723,9 +4730,11 @@ static NTSTATUS dcesrv_samr_SetUserInfo2(struct dcesrv_call_state *dce_call, TAL { struct samr_SetUserInfo r2; - r2.in.user_handle = r->in.user_handle; - r2.in.level = r->in.level; - r2.in.info = r->in.info; + r2 = (struct samr_SetUserInfo) { + .in.user_handle = r->in.user_handle, + .in.level = r->in.level, + .in.info = r->in.info, + }; return dcesrv_samr_SetUserInfo(dce_call, mem_ctx, &r2); } @@ -4760,9 +4769,11 @@ static NTSTATUS dcesrv_samr_Connect3(struct dcesrv_call_state *dce_call, TALLOC_ { struct samr_Connect c; - c.in.system_name = NULL; - c.in.access_mask = r->in.access_mask; - c.out.connect_handle = r->out.connect_handle; + c = (struct samr_Connect) { + .in.system_name = NULL, + .in.access_mask = r->in.access_mask, + .out.connect_handle = r->out.connect_handle, + }; return dcesrv_samr_Connect(dce_call, mem_ctx, &c); } @@ -4776,9 +4787,11 @@ static NTSTATUS dcesrv_samr_Connect4(struct dcesrv_call_state *dce_call, TALLOC_ { struct samr_Connect c; - c.in.system_name = NULL; - c.in.access_mask = r->in.access_mask; - c.out.connect_handle = r->out.connect_handle; + c = (struct samr_Connect) { + .in.system_name = NULL, + .in.access_mask = r->in.access_mask, + .out.connect_handle = r->out.connect_handle, + }; return dcesrv_samr_Connect(dce_call, mem_ctx, &c); } @@ -4793,9 +4806,11 @@ static NTSTATUS dcesrv_samr_Connect5(struct dcesrv_call_state *dce_call, TALLOC_ struct samr_Connect c; NTSTATUS status; - c.in.system_name = NULL; - c.in.access_mask = r->in.access_mask; - c.out.connect_handle = r->out.connect_handle; + c = (struct samr_Connect) { + .in.system_name = NULL, + .in.access_mask = r->in.access_mask, + .out.connect_handle = r->out.connect_handle, + }; status = dcesrv_samr_Connect(dce_call, mem_ctx, &c); @@ -4868,8 +4883,11 @@ static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, (*r->out.rep) = talloc_zero(mem_ctx, union samr_ValidatePasswordRep); - r2.in.domain_name = NULL; - r2.out.info = &pwInfo; + r2 = (struct samr_GetDomPwInfo) { + .in.domain_name = NULL, + .out.info = &pwInfo, + }; + status = dcesrv_samr_GetDomPwInfo(dce_call, mem_ctx, &r2); if (!NT_STATUS_IS_OK(status)) { return status; -- 2.20.1.97.g81188d93c3-goog From c236417bc9c1b638b772d2daea5b4272ec2c667f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2018 16:47:58 +0100 Subject: [PATCH 006/103] s4:rpc_server: remove dcerpc_remote dependency from dcerpc_server dcerpc_remote is just an implementation and does not belong to the core dcerpc server. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/wscript_build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build index 14b68c7ce0f..aee880f0224 100644 --- a/source4/rpc_server/wscript_build +++ b/source4/rpc_server/wscript_build @@ -24,7 +24,7 @@ bld.SAMBA_SUBSYSTEM('DCERPC_COMMON', bld.SAMBA_LIBRARY('dcerpc_server', source='dcerpc_server.c dcesrv_mgmt.c handles.c', pc_files='dcerpc_server.pc', - deps='LIBCLI_AUTH ndr samba_server_gensec dcerpc_remote service auth', + deps='LIBCLI_AUTH ndr samba_server_gensec service auth', public_deps='dcerpc', autoproto='dcerpc_server_proto.h', public_headers='dcerpc_server.h', -- 2.20.1.97.g81188d93c3-goog From fd401ba4087174b2785e9873ff62188953417d1e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2018 16:48:42 +0100 Subject: [PATCH 007/103] s4:rpc_server: let test_rpc_dns_server_dnsutils depend on dcerpc_server The core dcerpc server is required here, which also implies DCERPC_COMMON. This is required to move common/reply.c dcesrv_auth.c from DCERPC_COMMON to dcerpc_server in the next commit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/wscript_build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build index aee880f0224..57fd5c45a49 100644 --- a/source4/rpc_server/wscript_build +++ b/source4/rpc_server/wscript_build @@ -182,7 +182,7 @@ if bld.CONFIG_GET('ENABLE_SELFTEST'): source='tests/rpc_dns_server_dnsutils_test.c', deps=''' dnsserver_common - DCERPC_COMMON + dcerpc_server cmocka talloc ''', -- 2.20.1.97.g81188d93c3-goog From dc591aec6337bcdedc3ae8dc0ac55655cd10d87d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 13 Nov 2018 09:42:17 +0100 Subject: [PATCH 008/103] s4:rpc_server: move dcesrv_auth.c and common/reply.c to dcerpc_server They belong to the core dcerpc server. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/wscript_build | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build index 57fd5c45a49..510335a6498 100644 --- a/source4/rpc_server/wscript_build +++ b/source4/rpc_server/wscript_build @@ -15,14 +15,14 @@ bld.SAMBA_SUBSYSTEM('DCERPC_SID_HELPER', ) bld.SAMBA_SUBSYSTEM('DCERPC_COMMON', - source='common/server_info.c common/forward.c common/reply.c dcesrv_auth.c common/loadparm.c', + source='common/server_info.c common/forward.c common/loadparm.c', autoproto='common/proto.h', - deps='ldb DCERPC_SHARE DCERPC_SID_HELPER samba_server_gensec', + deps='ldb DCERPC_SHARE DCERPC_SID_HELPER', enabled=bld.AD_DC_BUILD_IS_ENABLED() ) bld.SAMBA_LIBRARY('dcerpc_server', - source='dcerpc_server.c dcesrv_mgmt.c handles.c', + source='dcerpc_server.c dcesrv_auth.c dcesrv_mgmt.c handles.c common/reply.c', pc_files='dcerpc_server.pc', deps='LIBCLI_AUTH ndr samba_server_gensec service auth', public_deps='dcerpc', -- 2.20.1.97.g81188d93c3-goog From 7efb8ca8ea1e5482965b2a30a03d5b4b46488a5e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 09:41:51 +0100 Subject: [PATCH 009/103] s4:rpc_server: remove unused dcesrv_connection->transport_session_key BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index eeb980f6969..90b5699ea4f 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -268,9 +268,6 @@ struct dcesrv_connection { /* the server_id that will be used for this connection */ struct server_id server_id; - /* the transport level session key */ - DATA_BLOB transport_session_key; - /* is this connection pending termination? If so, why? */ const char *terminate; -- 2.20.1.97.g81188d93c3-goog From cb06493026df3c37529f9e9fe0ad21c8f38dcafe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2018 01:18:59 +0100 Subject: [PATCH 010/103] s4:rpc_server: add dcesrv_call_session_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 8 ++++++++ source4/rpc_server/dcerpc_server.h | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 7949c66323a..aafb9a26133 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -3165,3 +3165,11 @@ _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call { return dce_call->context->conn->auth_state.session_info->info->account_name; } + +/** + * retrieve session_info from a dce_call + */ +_PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call) +{ + return dce_call->context->conn->auth_state.session_info; +} diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 90b5699ea4f..84a34742168 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -508,6 +508,11 @@ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call); */ _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call); +/** + * retrieve session_info from a dce_call + */ +_PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call); + _PUBLIC_ NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface); _PUBLIC_ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, -- 2.20.1.97.g81188d93c3-goog From 7d897c65fc5a14f2967bd32d8af9a30307068144 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2018 01:19:51 +0100 Subject: [PATCH 011/103] s4:rpc_server/backupkey: make use dcesrv_call_session_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/backupkey/dcesrv_backupkey.c | 14 ++++++++++---- .../backupkey/dcesrv_backupkey_heimdal.c | 14 ++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c index fd9c101eb8b..10caf248db4 100644 --- a/source4/rpc_server/backupkey/dcesrv_backupkey.c +++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c @@ -524,6 +524,8 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call, struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct bkrp_client_side_wrapped uncrypt_request; DATA_BLOB blob; enum ndr_err_code ndr_err; @@ -659,7 +661,7 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call, uncrypted_secretv2.payload_key, uncrypt_request.access_check, uncrypt_request.access_check_len, - dce_call->conn->auth_state.session_info); + session_info); if (!W_ERROR_IS_OK(werr)) { return werr; } @@ -702,7 +704,7 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call, uncrypted_secretv3.payload_key, uncrypt_request.access_check, uncrypt_request.access_check_len, - dce_call->conn->auth_state.session_info); + session_info); if (!W_ERROR_IS_OK(werr)) { return werr; } @@ -1387,6 +1389,8 @@ static WERROR bkrp_do_retrieve_default_server_wrap_key(TALLOC_CTX *mem_ctx, static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); WERROR werr; struct bkrp_server_side_wrapped decrypt_request; DATA_BLOB sid_blob, encrypted_blob; @@ -1524,7 +1528,7 @@ static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, return WERR_INVALID_ACCESS; } - caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; + caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; if (!dom_sid_equal(&rc4payload.sid, caller_sid)) { return WERR_INVALID_ACCESS; @@ -1577,6 +1581,8 @@ static WERROR bkrp_generic_decrypt_data(struct dcesrv_call_state *dce_call, TALL static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); DATA_BLOB sid_blob, encrypted_blob, server_wrapped_blob; WERROR werr; struct dom_sid *caller_sid; @@ -1625,7 +1631,7 @@ static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, } } - caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; + caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key)); diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c b/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c index 198a4088ef4..9cd912594c5 100644 --- a/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c +++ b/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c @@ -588,6 +588,8 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call, struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct bkrp_client_side_wrapped uncrypt_request; DATA_BLOB blob; enum ndr_err_code ndr_err; @@ -723,7 +725,7 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call, uncrypted_secretv2.payload_key, uncrypt_request.access_check, uncrypt_request.access_check_len, - dce_call->conn->auth_state.session_info); + session_info); if (!W_ERROR_IS_OK(werr)) { return werr; } @@ -767,7 +769,7 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call, uncrypted_secretv3.payload_key, uncrypt_request.access_check, uncrypt_request.access_check_len, - dce_call->conn->auth_state.session_info); + session_info); if (!W_ERROR_IS_OK(werr)) { return werr; } @@ -1497,6 +1499,8 @@ static WERROR bkrp_do_retrieve_default_server_wrap_key(TALLOC_CTX *mem_ctx, static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); WERROR werr; struct bkrp_server_side_wrapped decrypt_request; DATA_BLOB sid_blob, encrypted_blob, symkey_blob; @@ -1600,7 +1604,7 @@ static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, return WERR_INVALID_ACCESS; } - caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; + caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; if (!dom_sid_equal(&rc4payload.sid, caller_sid)) { return WERR_INVALID_ACCESS; @@ -1653,6 +1657,8 @@ static WERROR bkrp_generic_decrypt_data(struct dcesrv_call_state *dce_call, TALL static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); DATA_BLOB sid_blob, encrypted_blob, symkey_blob, server_wrapped_blob; WERROR werr; struct dom_sid *caller_sid; @@ -1699,7 +1705,7 @@ static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, } } - caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; + caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key)); -- 2.20.1.97.g81188d93c3-goog From 00bb325cdb480f65dead2cc20b7cf49a3b562b73 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2018 01:19:51 +0100 Subject: [PATCH 012/103] s4:rpc_server/dnsserver: make use dcesrv_call_session_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dnsserver/dcerpc_dnsserver.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c index ce01c9c258f..068305e5550 100644 --- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c +++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c @@ -103,6 +103,8 @@ static void dnsserver_reload_zones(struct dnsserver_state *dsstate) static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_call) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dnsserver_state *dsstate; struct dnsserver_zone *zones, *z, *znext; struct dnsserver_partition *partitions, *p; @@ -123,7 +125,7 @@ static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_c dsstate->samdb = samdb_connect(dsstate, dce_call->event_ctx, dsstate->lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (dsstate->samdb == NULL) { -- 2.20.1.97.g81188d93c3-goog From 927bc0e7769f13e85a1a1de2475c434f8e820095 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2018 01:19:51 +0100 Subject: [PATCH 013/103] s4:rpc_server/drsuapi: make use dcesrv_call_session_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 8 +++++--- source4/rpc_server/drsuapi/drsutil.c | 6 ++++-- source4/rpc_server/drsuapi/getncchanges.c | 12 +++++++----- source4/rpc_server/drsuapi/updaterefs.c | 10 ++++++---- source4/rpc_server/drsuapi/writespn.c | 4 +++- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index eac96a3aa12..9796da405f7 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -90,7 +90,7 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C auth_info = system_session(dce_call->conn->dce_ctx->lp_ctx); connected_as_system = true; } else { - auth_info = dce_call->conn->auth_state.session_info; + auth_info = dcesrv_call_session_info(dce_call); } /* @@ -1011,15 +1011,17 @@ static WERROR dcesrv_drsuapi_DsExecuteKCC(struct dcesrv_call_state *dce_call, TA static WERROR dcesrv_drsuapi_DsReplicaGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct drsuapi_DsReplicaGetInfo *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); enum security_user_level level; if (!lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "disable_sec_check", false)) { - level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL); + level = security_session_user_level(session_info, NULL); if (level < SECURITY_DOMAIN_CONTROLLER) { DEBUG(1,(__location__ ": Administrator access required for DsReplicaGetInfo\n")); security_token_debug(DBGC_DRS_REPL, 2, - dce_call->conn->auth_state.session_info->security_token); + session_info->security_token); return WERR_DS_DRA_ACCESS_DENIED; } } diff --git a/source4/rpc_server/drsuapi/drsutil.c b/source4/rpc_server/drsuapi/drsutil.c index 6fe254ac96c..7897c35d2e9 100644 --- a/source4/rpc_server/drsuapi/drsutil.c +++ b/source4/rpc_server/drsuapi/drsutil.c @@ -95,6 +95,8 @@ WERROR drs_security_level_check(struct dcesrv_call_state *dce_call, enum security_user_level minimum_level, const struct dom_sid *domain_sid) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); enum security_user_level level; if (lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, @@ -102,12 +104,12 @@ WERROR drs_security_level_check(struct dcesrv_call_state *dce_call, return WERR_OK; } - level = security_session_user_level(dce_call->conn->auth_state.session_info, domain_sid); + level = security_session_user_level(session_info, domain_sid); if (level < minimum_level) { if (call) { DEBUG(0,("%s refused for security token (level=%u)\n", call, (unsigned)level)); - security_token_debug(DBGC_DRS_REPL, 2, dce_call->conn->auth_state.session_info->security_token); + security_token_debug(DBGC_DRS_REPL, 2, session_info->security_token); } return WERR_DS_DRA_ACCESS_DENIED; } diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index b48e9c7234d..f3f819a410e 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -2698,6 +2698,8 @@ static struct getncchanges_repl_chunk * getncchanges_chunk_new(TALLOC_CTX *mem_c WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct drsuapi_DsGetNCChanges *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct drsuapi_DsReplicaObjectIdentifier *ncRoot; int ret; uint32_t i, k; @@ -2799,12 +2801,12 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ return WERR_DS_DRA_SOURCE_DISABLED; } - user_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; + user_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; /* all clients must have GUID_DRS_GET_CHANGES */ werr = drs_security_access_check_nc_root(sam_ctx, mem_ctx, - dce_call->conn->auth_state.session_info->security_token, + session_info->security_token, req10->naming_context, GUID_DRS_GET_CHANGES); if (!W_ERROR_IS_OK(werr)) { @@ -2846,7 +2848,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ if (is_gc_pas_request) { werr = drs_security_access_check_nc_root(sam_ctx, mem_ctx, - dce_call->conn->auth_state.session_info->security_token, + session_info->security_token, req10->naming_context, GUID_DRS_GET_FILTERED_ATTRIBUTES); if (W_ERROR_IS_OK(werr)) { @@ -2863,7 +2865,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ if (is_secret_request) { werr = drs_security_access_check_nc_root(sam_ctx, mem_ctx, - dce_call->conn->auth_state.session_info->security_token, + session_info->security_token, req10->naming_context, GUID_DRS_GET_ALL_CHANGES); if (!W_ERROR_IS_OK(werr)) { @@ -2879,7 +2881,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ allowed: /* for non-administrator replications, check that they have given the correct source_dsa_invocation_id */ - security_level = security_session_user_level(dce_call->conn->auth_state.session_info, + security_level = security_session_user_level(session_info, samdb_domain_sid(sam_ctx)); if (security_level == SECURITY_RO_DOMAIN_CONTROLLER) { if (req10->replica_flags & DRSUAPI_DRS_WRIT_REP) { diff --git a/source4/rpc_server/drsuapi/updaterefs.c b/source4/rpc_server/drsuapi/updaterefs.c index c92add744ec..0d3b47a9505 100644 --- a/source4/rpc_server/drsuapi/updaterefs.c +++ b/source4/rpc_server/drsuapi/updaterefs.c @@ -336,6 +336,8 @@ failed: WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct drsuapi_DsReplicaUpdateRefs *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h; struct drsuapi_bind_state *b_state; struct drsuapi_DsReplicaUpdateRefsRequest1 *req; @@ -353,7 +355,7 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA req = &r->in.req.req1; werr = drs_security_access_check(b_state->sam_ctx, mem_ctx, - dce_call->conn->auth_state.session_info->security_token, + session_info->security_token, req->naming_context, GUID_DRS_MANAGE_TOPOLOGY); @@ -361,16 +363,16 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA return werr; } - security_level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL); + security_level = security_session_user_level(session_info, NULL); if (security_level < SECURITY_ADMINISTRATOR) { /* check that they are using an DSA objectGUID that they own */ ret = dsdb_validate_dsa_guid(b_state->sam_ctx, &req->dest_dsa_guid, - &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]); + &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Refusing DsReplicaUpdateRefs for sid %s with GUID %s\n", dom_sid_string(mem_ctx, - &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]), + &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]), GUID_string(mem_ctx, &req->dest_dsa_guid))); return WERR_DS_DRA_ACCESS_DENIED; } diff --git a/source4/rpc_server/drsuapi/writespn.c b/source4/rpc_server/drsuapi/writespn.c index 991efccae38..9a289897f3e 100644 --- a/source4/rpc_server/drsuapi/writespn.c +++ b/source4/rpc_server/drsuapi/writespn.c @@ -53,6 +53,8 @@ static bool writespn_check_spn(struct drsuapi_bind_state *b_state, * 1) they are on the clients own account object * 2) they are of the form SERVICE/dnshostname */ + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dom_sid *user_sid, *sid; TALLOC_CTX *tmp_ctx = talloc_new(dce_call); struct ldb_result *res; @@ -82,7 +84,7 @@ static bool writespn_check_spn(struct drsuapi_bind_state *b_state, return false; } - user_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; + user_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; sid = samdb_result_dom_sid(tmp_ctx, res->msgs[0], "objectSid"); if (sid == NULL) { talloc_free(tmp_ctx); -- 2.20.1.97.g81188d93c3-goog From 123c888ac5ca30cc00bb5cbd61471695476d9989 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2018 01:19:51 +0100 Subject: [PATCH 014/103] s4:rpc_server/lsa: make use dcesrv_call_session_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/lsa/dcesrv_lsa.c | 33 +++++++++++++++++++---------- source4/rpc_server/lsa/lsa_init.c | 5 +++-- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index acf14f9146a..d6c4c72c4ca 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -241,6 +241,8 @@ static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_DeleteObject *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h; int ret; @@ -250,7 +252,7 @@ static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALL struct lsa_secret_state *secret_state = h->data; /* Ensure user is permitted to delete this... */ - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: @@ -397,6 +399,8 @@ static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_ static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_QuerySecurity *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h; const struct security_descriptor *sd = NULL; uint32_t access_granted = 0; @@ -406,7 +410,7 @@ static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TAL DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY); - sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; + sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) { struct lsa_policy_state *pstate = h->data; @@ -2871,6 +2875,8 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_ struct dom_sid *sid, const struct lsa_RightSet *rights) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); const char *sidstr, *sidndrstr; struct ldb_message *msg; struct ldb_message_element *el; @@ -2879,7 +2885,7 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_ struct lsa_EnumAccountRights r2; char *dnstr; - if (security_session_user_level(dce_call->conn->auth_state.session_info, NULL) < + if (security_session_user_level(session_info, NULL) < SECURITY_ADMINISTRATOR) { DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n")); return NT_STATUS_ACCESS_DENIED; @@ -3173,6 +3179,8 @@ static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_ static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_CreateSecret *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *policy_handle; struct lsa_policy_state *policy_state; struct lsa_secret_state *secret_state; @@ -3190,7 +3198,7 @@ static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALL DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); ZERO_STRUCTP(r->out.sec_handle); - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: @@ -3337,8 +3345,9 @@ static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALL static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_OpenSecret *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *policy_handle; - struct lsa_policy_state *policy_state; struct lsa_secret_state *secret_state; struct dcesrv_handle *handle; @@ -3347,9 +3356,7 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC const char *attrs[] = { NULL }; - const char *name; - int ret; DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); @@ -3360,7 +3367,7 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC return NT_STATUS_INVALID_PARAMETER; } - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: @@ -3622,6 +3629,8 @@ static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_ static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_QuerySecret *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h; struct lsa_secret_state *secret_state; struct ldb_message *msg; @@ -3642,7 +3651,7 @@ static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLO DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET); /* Ensure user is permitted to read this... */ - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: @@ -3958,6 +3967,8 @@ static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLO { enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); NTSTATUS status = NT_STATUS_OK; const char *account_name; const char *authority_name; @@ -3986,8 +3997,8 @@ static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLO return NT_STATUS_INVALID_PARAMETER; } - account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->info->account_name); - authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->info->domain_name); + account_name = talloc_reference(mem_ctx, session_info->info->account_name); + authority_name = talloc_reference(mem_ctx, session_info->info->domain_name); _account_name = talloc(mem_ctx, struct lsa_String); NT_STATUS_HAVE_NO_MEMORY(_account_name); diff --git a/source4/rpc_server/lsa/lsa_init.c b/source4/rpc_server/lsa/lsa_init.c index 560229494a5..7e493e3a313 100644 --- a/source4/rpc_server/lsa/lsa_init.c +++ b/source4/rpc_server/lsa/lsa_init.c @@ -50,7 +50,8 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, uint32_t access_desired, struct lsa_policy_state **_state) { - struct auth_session_info *session_info = dce_call->conn->auth_state.session_info; + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); enum security_user_level security_level; struct lsa_policy_state *state; struct ldb_result *dom_res; @@ -73,7 +74,7 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, state->sam_ldb = samdb_connect(state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (state->sam_ldb == NULL) { -- 2.20.1.97.g81188d93c3-goog From b8e1a26a8ff41c73781c36ec052baa482a8e19bf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2018 01:19:51 +0100 Subject: [PATCH 015/103] s4:rpc_server/netlogon: make use dcesrv_call_session_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index e96cd08ce2d..b7d174da65f 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -1572,6 +1572,8 @@ static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALL static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_GetDcName *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); const char * const attrs[] = { NULL }; struct ldb_context *sam_ctx; struct ldb_message **res; @@ -1601,7 +1603,7 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { @@ -1649,9 +1651,9 @@ static void dcesrv_netr_LogonControl_base_done(struct tevent_req *subreq); static WERROR dcesrv_netr_LogonControl_base_call(struct dcesrv_netr_LogonControl_base_state *state) { - struct dcesrv_connection *conn = state->dce_call->conn; struct loadparm_context *lp_ctx = state->dce_call->conn->dce_ctx->lp_ctx; - struct auth_session_info *session_info = conn->auth_state.session_info; + struct auth_session_info *session_info = + dcesrv_call_session_info(state->dce_call); enum security_user_level security_level; struct dcerpc_binding_handle *irpc_handle; struct tevent_req *subreq; @@ -2006,6 +2008,8 @@ static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx, static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_GetAnyDCName *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct netr_DomainTrustList *trusts; struct ldb_context *sam_ctx; struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; @@ -2022,7 +2026,7 @@ static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLO sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { @@ -2166,13 +2170,15 @@ static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_DsRGetSiteName *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct ldb_context *sam_ctx; struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { @@ -2903,6 +2909,8 @@ static void dcesrv_netr_DsRGetDCName_base_done(struct tevent_req *subreq); static WERROR dcesrv_netr_DsRGetDCName_base_call(struct dcesrv_netr_DsRGetDCName_base_state *state) { struct dcesrv_call_state *dce_call = state->dce_call; + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); TALLOC_CTX *mem_ctx = state->mem_ctx; struct netr_DsRGetDCNameEx2 *r = &state->r; struct ldb_context *sam_ctx; @@ -2926,7 +2934,7 @@ static WERROR dcesrv_netr_DsRGetDCName_base_call(struct dcesrv_netr_DsRGetDCName sam_ctx = samdb_connect(state, dce_call->event_ctx, lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { @@ -3383,6 +3391,8 @@ static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_DsRAddressToSitenamesExW *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct ldb_context *sam_ctx; struct netr_DsRAddressToSitenamesExWCtr *ctr; struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; @@ -3401,7 +3411,7 @@ static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { @@ -3515,6 +3525,8 @@ static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_c static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_DsrGetDcSiteCoverageW *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct ldb_context *sam_ctx; struct DcSitesCtr *ctr; struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; @@ -3522,7 +3534,7 @@ static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_ca sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { @@ -3650,6 +3662,8 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce TALLOC_CTX *mem_ctx, struct netr_DsrEnumerateDomainTrusts *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct netr_DomainTrustList *trusts; struct ldb_context *sam_ctx; int ret; @@ -3694,7 +3708,7 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { @@ -3807,8 +3821,8 @@ static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state struct netr_DsRGetForestTrustInformation *r) { struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; - struct dcesrv_connection *conn = dce_call->conn; - struct auth_session_info *session_info = conn->auth_state.session_info; + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); enum security_user_level security_level; struct ldb_context *sam_ctx = NULL; struct dcesrv_netr_DsRGetForestTrustInformation_state *state = NULL; @@ -3831,7 +3845,7 @@ static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { @@ -3960,6 +3974,8 @@ static NTSTATUS dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state * TALLOC_CTX *mem_ctx, struct netr_GetForestTrustInformation *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; struct netlogon_creds_CredentialState *creds = NULL; struct ldb_context *sam_ctx = NULL; @@ -3987,7 +4003,7 @@ static NTSTATUS dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state * sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { -- 2.20.1.97.g81188d93c3-goog From 51e6feb0ee94da1f3138ebc738f9036b54e80ce0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2018 01:19:51 +0100 Subject: [PATCH 016/103] s4:rpc_server/samr: make use dcesrv_call_session_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/samr/dcesrv_samr.c | 8 ++++++-- source4/rpc_server/samr/samr_password.c | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index d7d2fa46684..96f68104948 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -210,6 +210,8 @@ exit: static NTSTATUS dcesrv_samr_Connect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_Connect *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct samr_connect_state *c_state; struct dcesrv_handle *handle; @@ -224,7 +226,7 @@ static NTSTATUS dcesrv_samr_Connect(struct dcesrv_call_state *dce_call, TALLOC_C c_state->sam_ctx = samdb_connect(c_state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (c_state->sam_ctx == NULL) { @@ -4658,6 +4660,8 @@ static NTSTATUS dcesrv_samr_RemoveMultipleMembersFromAlias(struct dcesrv_call_st static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_GetDomPwInfo *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct ldb_message **msgs; int ret; const char * const attrs[] = {"minPwdLength", "pwdProperties", NULL }; @@ -4668,7 +4672,7 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index 4c656988879..08a499e83e7 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -98,6 +98,8 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_OemChangePasswordUser2 *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); NTSTATUS status = NT_STATUS_WRONG_PASSWORD; DATA_BLOB new_password, new_unicode_password; char *new_pass; @@ -220,7 +222,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { @@ -295,6 +297,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_ChangePasswordUser3 *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); NTSTATUS status = NT_STATUS_WRONG_PASSWORD; DATA_BLOB new_password; struct ldb_context *sam_ctx = NULL; @@ -423,7 +427,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, dce_call->conn->remote_address, 0); if (sam_ctx == NULL) { -- 2.20.1.97.g81188d93c3-goog From 7cdd4963e40c573929fdf109074f7f2f868a081c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2018 01:19:51 +0100 Subject: [PATCH 017/103] s4:rpc_server/srvsvc: make use dcesrv_call_session_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/srvsvc/dcesrv_srvsvc.c | 11 ++++++++--- source4/rpc_server/srvsvc/srvsvc_ntvfs.c | 4 +++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c index a6bee0d8ca0..09673f6345c 100644 --- a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c +++ b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c @@ -32,7 +32,8 @@ #include "param/param.h" #define SRVSVC_CHECK_ADMIN_ACCESS do { \ - struct security_token *t = dce_call->conn->auth_state.session_info->security_token; \ + struct auth_session_info *si = dcesrv_call_session_info(dce_call); \ + struct security_token *t = si->security_token; \ if (!security_token_has_builtin_administrators(t) && \ !security_token_has_sid(t, &global_sid_Builtin_Server_Operators)) { \ return WERR_ACCESS_DENIED; \ @@ -2045,6 +2046,8 @@ static WERROR dcesrv_srvsvc_NetShareDelCommit(struct dcesrv_call_state *dce_call static WERROR dcesrv_srvsvc_NetGetFileSecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct srvsvc_NetGetFileSecurity *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct sec_desc_buf *sd_buf; struct ntvfs_context *ntvfs_ctx = NULL; struct ntvfs_request *ntvfs_req; @@ -2055,7 +2058,7 @@ static WERROR dcesrv_srvsvc_NetGetFileSecurity(struct dcesrv_call_state *dce_cal if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status); ntvfs_req = ntvfs_request_create(ntvfs_ctx, mem_ctx, - dce_call->conn->auth_state.session_info, + session_info, 0, dce_call->time, NULL, NULL, 0); @@ -2087,6 +2090,8 @@ static WERROR dcesrv_srvsvc_NetGetFileSecurity(struct dcesrv_call_state *dce_cal static WERROR dcesrv_srvsvc_NetSetFileSecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct srvsvc_NetSetFileSecurity *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct ntvfs_context *ntvfs_ctx; struct ntvfs_request *ntvfs_req; union smb_setfileinfo *io; @@ -2096,7 +2101,7 @@ static WERROR dcesrv_srvsvc_NetSetFileSecurity(struct dcesrv_call_state *dce_cal if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status); ntvfs_req = ntvfs_request_create(ntvfs_ctx, mem_ctx, - dce_call->conn->auth_state.session_info, + session_info, 0, dce_call->time, NULL, NULL, 0); diff --git a/source4/rpc_server/srvsvc/srvsvc_ntvfs.c b/source4/rpc_server/srvsvc/srvsvc_ntvfs.c index 5d6fc92859a..fe97d60d999 100644 --- a/source4/rpc_server/srvsvc/srvsvc_ntvfs.c +++ b/source4/rpc_server/srvsvc/srvsvc_ntvfs.c @@ -39,6 +39,8 @@ NTSTATUS srvsvc_create_ntvfs_context(struct dcesrv_call_state *dce_call, const char *share, struct ntvfs_context **_ntvfs) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); NTSTATUS status; struct srvsvc_ntvfs_ctx *c; struct ntvfs_request *ntvfs_req; @@ -113,7 +115,7 @@ NTSTATUS srvsvc_create_ntvfs_context(struct dcesrv_call_state *dce_call, } ntvfs_req = ntvfs_request_create(c->ntvfs, mem_ctx, - dce_call->conn->auth_state.session_info, + session_info, 0, /* TODO: fill in PID */ dce_call->time, NULL, NULL, 0); -- 2.20.1.97.g81188d93c3-goog From e54f76a8b8f7fe919903ac2ebf581c28c579045e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2018 01:19:51 +0100 Subject: [PATCH 018/103] s4:rpc_server/winreq: make use dcesrv_call_session_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/winreg/rpc_winreg.c | 36 +++++++++++++++++++------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/source4/rpc_server/winreg/rpc_winreg.c b/source4/rpc_server/winreg/rpc_winreg.c index 6cbd1a321ab..48d191db960 100644 --- a/source4/rpc_server/winreg/rpc_winreg.c +++ b/source4/rpc_server/winreg/rpc_winreg.c @@ -32,12 +32,14 @@ enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY }; static NTSTATUS dcerpc_winreg_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct registry_context *ctx; WERROR err; err = reg_open_samba(dce_call->context, &ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - dce_call->conn->auth_state.session_info, + session_info, NULL); if (!W_ERROR_IS_OK(err)) { @@ -113,6 +115,8 @@ static WERROR dcesrv_winreg_CreateKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_CreateKey *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h, *newh; struct security_descriptor sd; struct registry_key *key; @@ -123,7 +127,7 @@ static WERROR dcesrv_winreg_CreateKey(struct dcesrv_call_state *dce_call, newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY); - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: @@ -179,6 +183,8 @@ static WERROR dcesrv_winreg_DeleteKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_DeleteKey *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h; struct registry_key *key; WERROR result; @@ -186,7 +192,7 @@ static WERROR dcesrv_winreg_DeleteKey(struct dcesrv_call_state *dce_call, DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: @@ -207,13 +213,15 @@ static WERROR dcesrv_winreg_DeleteValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_DeleteValue *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h; struct registry_key *key; DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: @@ -345,13 +353,15 @@ static WERROR dcesrv_winreg_FlushKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_FlushKey *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h; struct registry_key *key; DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: @@ -406,6 +416,8 @@ static WERROR dcesrv_winreg_OpenKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_OpenKey *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h, *newh; struct registry_key *key; WERROR result; @@ -413,7 +425,7 @@ static WERROR dcesrv_winreg_OpenKey(struct dcesrv_call_state *dce_call, DCESRV_PULL_HANDLE_FAULT(h, r->in.parent_handle, HTYPE_REGKEY); key = h->data; - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: @@ -446,6 +458,8 @@ static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_QueryInfoKey *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h; struct registry_key *key; const char *classname = NULL; @@ -454,7 +468,7 @@ static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call, DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: @@ -496,6 +510,8 @@ static WERROR dcesrv_winreg_QueryValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_QueryValue *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h; struct registry_key *key; uint32_t value_type; @@ -505,7 +521,7 @@ static WERROR dcesrv_winreg_QueryValue(struct dcesrv_call_state *dce_call, DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: @@ -605,6 +621,8 @@ static WERROR dcesrv_winreg_SetValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_SetValue *r) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); struct dcesrv_handle *h; struct registry_key *key; DATA_BLOB data; @@ -613,7 +631,7 @@ static WERROR dcesrv_winreg_SetValue(struct dcesrv_call_state *dce_call, DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; - switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) + switch (security_session_user_level(session_info, NULL)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: -- 2.20.1.97.g81188d93c3-goog From c752c558d39fb00a1df3165a0385a84e78e0ef04 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2018 01:19:51 +0100 Subject: [PATCH 019/103] s4:rpc_server/common: make use dcesrv_call_session_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/common/forward.c | 7 ++++--- source4/rpc_server/common/server_info.c | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/common/forward.c b/source4/rpc_server/common/forward.c index 45ce6dcac93..7d60bd76142 100644 --- a/source4/rpc_server/common/forward.c +++ b/source4/rpc_server/common/forward.c @@ -72,7 +72,8 @@ void dcesrv_irpc_forward_rpc_call(struct dcesrv_call_state *dce_call, TALLOC_CTX struct dcesrv_forward_state *st; struct dcerpc_binding_handle *binding_handle; struct tevent_req *subreq; - struct security_token *token; + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); st = talloc(mem_ctx, struct dcesrv_forward_state); if (st == NULL) { @@ -105,8 +106,8 @@ void dcesrv_irpc_forward_rpc_call(struct dcesrv_call_state *dce_call, TALLOC_CTX dcerpc_binding_handle_set_timeout(binding_handle, timeout); /* add security token to the handle*/ - token = dce_call->conn->auth_state.session_info->security_token; - irpc_binding_handle_add_security_token(binding_handle, token); + irpc_binding_handle_add_security_token(binding_handle, + session_info->security_token); /* forward the call */ subreq = dcerpc_binding_handle_call_send(st, dce_call->event_ctx, diff --git a/source4/rpc_server/common/server_info.c b/source4/rpc_server/common/server_info.c index 836e6d10f84..6e475bcc796 100644 --- a/source4/rpc_server/common/server_info.c +++ b/source4/rpc_server/common/server_info.c @@ -206,10 +206,12 @@ struct ldb_context *dcesrv_samdb_connect_as_system( dce_call->conn->remote_address, 0); if (samdb) { + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); ldb_set_opaque( samdb, DSDB_NETWORK_SESSION_INFO, - dce_call->conn->auth_state.session_info); + session_info); } return samdb; } -- 2.20.1.97.g81188d93c3-goog From 1b93feb01ed5f51418364f143aef39ac7cfa7a82 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 11:48:46 +0100 Subject: [PATCH 020/103] s4:rpc_server: add dcesrv_{auth,transport}_session_key() functions They take struct dcesrv_call_state as argument and will replace dcesrv_{inherited,fetch}_session_key() which take dcesrv_connection as argument. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 25 +++++++++++++++++++++++++ source4/rpc_server/dcerpc_server.h | 18 ++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index aafb9a26133..fca62290a70 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -469,6 +469,18 @@ NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p, return NT_STATUS_NO_USER_SESSION_KEY; } +/* + * Fetch the authentication session key if available. + * + * This is the key generated by a gensec authentication. + * + */ +_PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call, + DATA_BLOB *session_key) +{ + return dcesrv_inherited_session_key(call->conn, session_key); +} + /* fetch the user session key - may be default (above) or the SMB session key @@ -487,6 +499,19 @@ _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, return NT_STATUS_OK; } +/* + * Fetch the transport session key if available. + * Typically this is the SMB session key + * or a fixed key for local transports. + * + * The key is always truncated to 16 bytes. +*/ +_PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call, + DATA_BLOB *session_key) +{ + return dcesrv_fetch_session_key(call->conn, session_key); +} + /* connect to a dcerpc endpoint */ diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 84a34742168..689371f0a33 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -449,6 +449,24 @@ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, DATA_BLOB *session_key); +/* + * Fetch the authentication session key if available. + * + * This is the key generated by a gensec authentication. + */ +NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call, + DATA_BLOB *session_key); + +/* + * Fetch the transport session key if available. + * Typically this is the SMB session key + * or a fixed key for local transports. + * + * The key is always truncated to 16 bytes. +*/ +NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call, + DATA_BLOB *session_key); + /* a useful macro for generating a RPC fault in the backend code */ #define DCESRV_FAULT(code) do { \ dce_call->fault_code = code; \ -- 2.20.1.97.g81188d93c3-goog From 15b6b207c66283df5b3904237a21f9622ae48b94 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 11:52:29 +0100 Subject: [PATCH 021/103] s4:rpc_server/lsa: make use of dcesrv_transport_session_key() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/lsa/dcesrv_lsa.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index d6c4c72c4ca..f5f5b373ce1 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -859,7 +859,7 @@ static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call, enum ndr_err_code ndr_err; NTSTATUS nt_status; - nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); + nt_status = dcesrv_transport_session_key(dce_call, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } @@ -3494,7 +3494,7 @@ static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_ if (!msg->dn) { return NT_STATUS_NO_MEMORY; } - status = dcesrv_fetch_session_key(dce_call->conn, &session_key); + status = dcesrv_transport_session_key(dce_call, &session_key); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -3671,7 +3671,7 @@ static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLO } msg = res[0]; - nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); + nt_status = dcesrv_transport_session_key(dce_call, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } -- 2.20.1.97.g81188d93c3-goog From a61213b594d5eeb21340f4ed6b5f5333cabfeec5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 11:52:29 +0100 Subject: [PATCH 022/103] s4:rpc_server/samr: make use of dcesrv_transport_session_key() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/samr/samr_password.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index 08a499e83e7..a80ae56b962 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -545,7 +545,7 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, DATA_BLOB new_password; DATA_BLOB session_key = data_blob(NULL, 0); - nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); + nt_status = dcesrv_transport_session_key(dce_call, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("samr: failed to get session key: %s " "=> NT_STATUS_WRONG_PASSWORD\n", @@ -587,7 +587,7 @@ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call, DATA_BLOB session_key = data_blob(NULL, 0); MD5_CTX ctx; - nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); + nt_status = dcesrv_transport_session_key(dce_call, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("samr: failed to get session key: %s " "=> NT_STATUS_WRONG_PASSWORD\n", @@ -639,7 +639,7 @@ NTSTATUS samr_set_password_buffers(struct dcesrv_call_state *dce_call, DATA_BLOB in, out; NTSTATUS nt_status = NT_STATUS_OK; - nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); + nt_status = dcesrv_transport_session_key(dce_call, &session_key); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_USER_SESSION_KEY)) { DEBUG(3,("samr: failed to get session key: %s " "=> use a random session key\n", -- 2.20.1.97.g81188d93c3-goog From aab161d7a043a8ebe85576d305a4bd6334ba5d45 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 11:52:29 +0100 Subject: [PATCH 023/103] s4:rpc_server/drsuapi: make use of dcesrv_auth_session_key() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/drsuapi/getncchanges.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index f3f819a410e..9c6b9801d7f 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -3069,7 +3069,7 @@ allowed: ncRoot->guid = getnc_state->ncRoot_guid; /* we need the session key for encrypting password attributes */ - status = dcesrv_inherited_session_key(dce_call->conn, &session_key); + status = dcesrv_auth_session_key(dce_call, &session_key); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,(__location__ ": Failed to get session key\n")); return WERR_DS_DRA_INTERNAL_ERROR; -- 2.20.1.97.g81188d93c3-goog From b072fa8941c075227989a966d505dd51d30c73fb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 09:45:15 +0100 Subject: [PATCH 024/103] s4:rpc_server: allow a NULL function pointer in dcesrv_fetch_session_key() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index fca62290a70..b8255ba4dd8 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -489,7 +489,14 @@ _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call, _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, DATA_BLOB *session_key) { - NTSTATUS status = p->auth_state.session_key(p, session_key); + struct dcesrv_auth *auth = &p->auth_state; + NTSTATUS status; + + if (auth->session_key == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + status = auth->session_key(p, session_key); if (!NT_STATUS_IS_OK(status)) { return status; } -- 2.20.1.97.g81188d93c3-goog From b95adc6f9d90c4c7c7f91800b76272e97828b82c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 09:45:15 +0100 Subject: [PATCH 025/103] s4:rpc_server: split out a dcesrv_session_info_session_key() helper function BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b8255ba4dd8..398b2227988 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -459,14 +459,27 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, return NT_STATUS_OK; } +static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth, + DATA_BLOB *session_key) +{ + if (auth->session_info == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + if (auth->session_info->session_key.length == 0) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + *session_key = auth->session_info->session_key; + return NT_STATUS_OK; +} + NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p, DATA_BLOB *session_key) { - if (p->auth_state.session_info->session_key.length) { - *session_key = p->auth_state.session_info->session_key; - return NT_STATUS_OK; - } - return NT_STATUS_NO_USER_SESSION_KEY; + struct dcesrv_auth *auth = &p->auth_state; + + return dcesrv_session_info_session_key(auth, session_key); } /* @@ -478,7 +491,9 @@ NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p, _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call, DATA_BLOB *session_key) { - return dcesrv_inherited_session_key(call->conn, session_key); + struct dcesrv_auth *auth = &call->conn->auth_state; + + return dcesrv_session_info_session_key(auth, session_key); } /* -- 2.20.1.97.g81188d93c3-goog From e9f561d9459312e6906bed82ca281c712feaced1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 09:45:15 +0100 Subject: [PATCH 026/103] s4:rpc_server: only AUTH_TYPE_NONE should get a transport session key There's only a logic change for NCALRPC and NCACN_UNIX_STREAM. dcesrv_generic_session_key() already returned NT_STATUS_NO_USER_SESSION_KEY for all other cases. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 4 ++++ source4/rpc_server/dcesrv_auth.c | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 398b2227988..299469b601d 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -479,6 +479,10 @@ NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p, { struct dcesrv_auth *auth = &p->auth_state; + if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + return dcesrv_session_info_session_key(auth, session_key); } diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index d48d03eefdc..efc16e91339 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -285,9 +285,6 @@ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) dce_conn->auth_state.auth_finished = true; dce_conn->allow_request = true; - /* Now that we are authenticated, go back to the generic session key... */ - dce_conn->auth_state.session_key = dcesrv_generic_session_key; - if (call->pkt.ptype != DCERPC_PKT_AUTH3) { return NT_STATUS_OK; } -- 2.20.1.97.g81188d93c3-goog From 36593950147f9c8ed6d82e9a310702cbfdd14d07 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 11:14:41 +0100 Subject: [PATCH 027/103] s4:rpc_server: make dcesrv_endpoint_connect() static BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 2 +- source4/rpc_server/dcerpc_server.h | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 299469b601d..e0d222fe2aa 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -541,7 +541,7 @@ _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call, /* connect to a dcerpc endpoint */ -_PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, +static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, TALLOC_CTX *mem_ctx, const struct dcesrv_endpoint *ep, struct auth_session_info *session_info, diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 689371f0a33..f6f4954a804 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -425,15 +425,6 @@ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_serve NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char **endpoint_servers, struct dcesrv_context **_dce_ctx); -NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, - TALLOC_CTX *mem_ctx, - const struct dcesrv_endpoint *ep, - struct auth_session_info *session_info, - struct tevent_context *event_ctx, - struct imessaging_context *msg_ctx, - struct server_id server_id, - uint32_t state_flags, - struct dcesrv_connection **_p); NTSTATUS dcesrv_reply(struct dcesrv_call_state *call); struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_context *context, -- 2.20.1.97.g81188d93c3-goog From 242f42477678b6a7f1cf7432f4c01057d92d0bd8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 11:14:41 +0100 Subject: [PATCH 028/103] s4:rpc_server: only setup the auth_state.session_key fn in dcesrv_endpoint_connect() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e0d222fe2aa..5d7dfaf965e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -551,6 +551,8 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, uint32_t state_flags, struct dcesrv_connection **_p) { + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(ep->ep_description); struct dcesrv_connection *p; if (!session_info) { @@ -568,8 +570,6 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->dce_ctx = dce_ctx; p->endpoint = ep; p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx); - p->auth_state.session_info = session_info; - p->auth_state.session_key = dcesrv_generic_session_key; p->event_ctx = event_ctx; p->msg_ctx = msg_ctx; p->server_id = server_id; @@ -579,6 +579,23 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->max_xmit_frag = 5840; p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE; + p->auth_state.session_info = session_info; + switch (transport) { + case NCACN_NP: + p->auth_state.session_key = dcesrv_inherited_session_key; + break; + case NCALRPC: + case NCACN_UNIX_STREAM: + p->auth_state.session_key = dcesrv_generic_session_key; + break; + default: + /* + * All other's get a NULL pointer, which + * results in NT_STATUS_NO_USER_SESSION_KEY + */ + break; + } + /* * For now we only support NDR32. */ @@ -2712,7 +2729,6 @@ static void dcesrv_sock_accept(struct stream_connection *srv_conn) } if (transport == NCACN_NP) { - dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key; dcesrv_conn->stream = talloc_move(dcesrv_conn, &srv_conn->tstream); } else { -- 2.20.1.97.g81188d93c3-goog From b5a929ff9ad80dc274d727ae3abae9336be802e4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 11:14:41 +0100 Subject: [PATCH 029/103] s4:rpc_server: only pass dcesrv_auth to auth_state.session_key_fn() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/common/reply.c | 13 ------------- source4/rpc_server/dcerpc_server.c | 28 ++++++++++++++++++++-------- source4/rpc_server/dcerpc_server.h | 2 +- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index ef2906e0724..d0d81fe1027 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -272,16 +272,3 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) return NT_STATUS_OK; } - -NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *c, - DATA_BLOB *session_key) -{ - enum dcerpc_transport_t transport = - dcerpc_binding_get_transport(c->endpoint->ep_description); - - if (transport != NCALRPC && transport != NCACN_UNIX_STREAM) { - return NT_STATUS_NO_USER_SESSION_KEY; - } - - return dcerpc_generic_session_key(NULL, session_key); -} diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5d7dfaf965e..7ceaf03c673 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -474,11 +474,9 @@ static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth, return NT_STATUS_OK; } -NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p, - DATA_BLOB *session_key) +static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth, + DATA_BLOB *session_key) { - struct dcesrv_auth *auth = &p->auth_state; - if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) { return NT_STATUS_NO_USER_SESSION_KEY; } @@ -486,6 +484,20 @@ NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p, return dcesrv_session_info_session_key(auth, session_key); } +static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth, + DATA_BLOB *session_key) +{ + return dcerpc_generic_session_key(NULL, session_key); +} + +NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p, + DATA_BLOB *session_key) +{ + struct dcesrv_auth *auth = &p->auth_state; + + return dcesrv_remote_session_key(auth, session_key); +} + /* * Fetch the authentication session key if available. * @@ -511,11 +523,11 @@ _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, struct dcesrv_auth *auth = &p->auth_state; NTSTATUS status; - if (auth->session_key == NULL) { + if (auth->session_key_fn == NULL) { return NT_STATUS_NO_USER_SESSION_KEY; } - status = auth->session_key(p, session_key); + status = auth->session_key_fn(auth, session_key); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -582,11 +594,11 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->auth_state.session_info = session_info; switch (transport) { case NCACN_NP: - p->auth_state.session_key = dcesrv_inherited_session_key; + p->auth_state.session_key_fn = dcesrv_remote_session_key; break; case NCALRPC: case NCACN_UNIX_STREAM: - p->auth_state.session_key = dcesrv_generic_session_key; + p->auth_state.session_key_fn = dcesrv_local_fixed_session_key; break; default: /* diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index f6f4954a804..1d80a2fa26f 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -199,7 +199,7 @@ struct dcesrv_auth { uint32_t auth_context_id; struct gensec_security *gensec_security; struct auth_session_info *session_info; - NTSTATUS (*session_key)(struct dcesrv_connection *, DATA_BLOB *session_key); + NTSTATUS (*session_key_fn)(struct dcesrv_auth *, DATA_BLOB *session_key); bool client_hdr_signing; bool hdr_signing; bool auth_finished; -- 2.20.1.97.g81188d93c3-goog From 5d3994f182c1200cbdcdfb905a63354db020c9f7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 11:52:29 +0100 Subject: [PATCH 030/103] s4:rpc_server: remove unused dcesrv_inherited_session_key() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 7ceaf03c673..8e1f65935a0 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -490,14 +490,6 @@ static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth, return dcerpc_generic_session_key(NULL, session_key); } -NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p, - DATA_BLOB *session_key) -{ - struct dcesrv_auth *auth = &p->auth_state; - - return dcesrv_remote_session_key(auth, session_key); -} - /* * Fetch the authentication session key if available. * -- 2.20.1.97.g81188d93c3-goog From efc0f818a3d0d7d4510edb225e47b8e956ff95e6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 11:52:29 +0100 Subject: [PATCH 031/103] s4:rpc_server: merge dcesrv_fetch_session_key() into dcesrv_transport_session_key() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 27 ++++++++------------------- source4/rpc_server/dcerpc_server.h | 2 -- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 8e1f65935a0..828a936c0b8 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -505,14 +505,16 @@ _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call, } /* - fetch the user session key - may be default (above) or the SMB session key - - The key is always truncated to 16 bytes + * Fetch the transport session key if available. + * Typically this is the SMB session key + * or a fixed key for local transports. + * + * The key is always truncated to 16 bytes. */ -_PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, - DATA_BLOB *session_key) +_PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call, + DATA_BLOB *session_key) { - struct dcesrv_auth *auth = &p->auth_state; + struct dcesrv_auth *auth = &call->conn->auth_state; NTSTATUS status; if (auth->session_key_fn == NULL) { @@ -529,19 +531,6 @@ _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, return NT_STATUS_OK; } -/* - * Fetch the transport session key if available. - * Typically this is the SMB session key - * or a fixed key for local transports. - * - * The key is always truncated to 16 bytes. -*/ -_PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call, - DATA_BLOB *session_key) -{ - return dcesrv_fetch_session_key(call->conn, session_key); -} - /* connect to a dcerpc endpoint */ diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 1d80a2fa26f..bba8b42534c 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -438,8 +438,6 @@ struct dcesrv_handle *dcesrv_handle_fetch( const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn); const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn); -NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, DATA_BLOB *session_key); - /* * Fetch the authentication session key if available. * -- 2.20.1.97.g81188d93c3-goog From 1166ad21faa77818b7a9603f088f486b94856e1c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:14:05 +0100 Subject: [PATCH 032/103] s4:rpc_server: add some const to dcesrv_handle_fetch() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.h | 2 +- source4/rpc_server/handles.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index bba8b42534c..39492f6acff 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -432,7 +432,7 @@ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_context *contex struct dcesrv_handle *dcesrv_handle_fetch( struct dcesrv_connection_context *context, - struct policy_handle *p, + const struct policy_handle *p, uint8_t handle_type); const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn); diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index af49f4caf1c..b2b9962a4f5 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -79,7 +79,7 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_contex */ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_fetch( struct dcesrv_connection_context *context, - struct policy_handle *p, + const struct policy_handle *p, uint8_t handle_type) { struct dcesrv_handle *h; -- 2.20.1.97.g81188d93c3-goog From 61f91a650a5dbbf86bb702fb2aec836d5e129415 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 11:48:46 +0100 Subject: [PATCH 033/103] s4:rpc_server: add dcesrv_handle_{create,lookup}() functions They take struct dcesrv_call_state as argument and will replace dcesrv_handle_{new,fetch}() which take dcesrv_connection_context as argument. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.h | 5 +++++ source4/rpc_server/handles.c | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 39492f6acff..8cf7ed8cf04 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -429,11 +429,16 @@ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, NTSTATUS dcesrv_reply(struct dcesrv_call_state *call); struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_context *context, uint8_t handle_type); +struct dcesrv_handle *dcesrv_handle_create(struct dcesrv_call_state *call, + uint8_t handle_type); struct dcesrv_handle *dcesrv_handle_fetch( struct dcesrv_connection_context *context, const struct policy_handle *p, uint8_t handle_type); +struct dcesrv_handle *dcesrv_handle_lookup(struct dcesrv_call_state *call, + const struct policy_handle *p, + uint8_t handle_type); const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn); const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn); diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index b2b9962a4f5..043870fa663 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -73,6 +73,13 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_contex return h; } +_PUBLIC_ +struct dcesrv_handle *dcesrv_handle_create(struct dcesrv_call_state *call, + uint8_t handle_type) +{ + return dcesrv_handle_new(call->context, handle_type); +} + /** find an internal handle given a wire handle. If the wire handle is NULL then allocate a new handle @@ -122,3 +129,11 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_fetch( return NULL; } + +_PUBLIC_ +struct dcesrv_handle *dcesrv_handle_lookup(struct dcesrv_call_state *call, + const struct policy_handle *p, + uint8_t handle_type) +{ + return dcesrv_handle_fetch(call->context, p, handle_type); +} -- 2.20.1.97.g81188d93c3-goog From 4469a73467b6411224be41f8aa7e5bd4be8320c0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:20:44 +0100 Subject: [PATCH 034/103] s4:rpc_server/drsuapi: make use of dcesrv_handle_create() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index 9796da405f7..415e8db084e 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -293,7 +293,7 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C /* * allocate a bind handle */ - handle = dcesrv_handle_new(dce_call->context, DRSUAPI_BIND_HANDLE); + handle = dcesrv_handle_create(dce_call, DRSUAPI_BIND_HANDLE); W_ERROR_HAVE_NO_MEMORY(handle); handle->data = talloc_steal(handle, b_state); -- 2.20.1.97.g81188d93c3-goog From 60a6f733aebd49a4aa304067126e4c8badee8575 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:20:44 +0100 Subject: [PATCH 035/103] s4:rpc_server/eventlog: make use of dcesrv_handle_create() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/eventlog/dcesrv_eventlog6.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/eventlog/dcesrv_eventlog6.c b/source4/rpc_server/eventlog/dcesrv_eventlog6.c index 9a649986652..49629847b28 100644 --- a/source4/rpc_server/eventlog/dcesrv_eventlog6.c +++ b/source4/rpc_server/eventlog/dcesrv_eventlog6.c @@ -83,12 +83,12 @@ static WERROR dcesrv_eventlog6_EvtRpcRegisterLogQuery(struct dcesrv_call_state * { struct dcesrv_handle *handle; - handle = dcesrv_handle_new(dce_call->context, 0); + handle = dcesrv_handle_create(dce_call, 0); W_ERROR_HAVE_NO_MEMORY(handle); r->out.handle = &handle->wire_handle; - handle = dcesrv_handle_new(dce_call->context, 0); + handle = dcesrv_handle_create(dce_call, 0); W_ERROR_HAVE_NO_MEMORY(handle); r->out.opControl = &handle->wire_handle; -- 2.20.1.97.g81188d93c3-goog From 21730b9bd2df3268a1acd8f4d2998e42be7229d5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:20:44 +0100 Subject: [PATCH 036/103] s4:rpc_server/lsa: make use of dcesrv_handle_create() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/lsa/dcesrv_lsa.c | 12 ++++++------ source4/rpc_server/lsa/lsa_init.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index f5f5b373ce1..8575db6b204 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -778,7 +778,7 @@ static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TAL (unsigned)r->in.access_mask, (unsigned)astate->access_mask)); - ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT); + ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT); if (!ah) { talloc_free(astate); return NT_STATUS_NO_MEMORY; @@ -1339,7 +1339,7 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc } TALLOC_FREE(server_ids); - handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN); + handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN); if (!handle) { return NT_STATUS_NO_MEMORY; } @@ -1471,7 +1471,7 @@ static NTSTATUS dcesrv_lsa_OpenTrustedDomain_common( } } - handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN); + handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN); if (!handle) { return NT_STATUS_NO_MEMORY; } @@ -2719,7 +2719,7 @@ static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLO (unsigned)r->in.access_mask, (unsigned)astate->access_mask)); - ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT); + ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT); if (!ah) { talloc_free(astate); return NT_STATUS_NO_MEMORY; @@ -3324,7 +3324,7 @@ static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALL return NT_STATUS_ACCESS_DENIED; } - handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET); + handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET); NT_STATUS_HAVE_NO_MEMORY(handle); handle->data = talloc_steal(handle, secret_state); @@ -3446,7 +3446,7 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn); - handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET); + handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET); if (!handle) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/rpc_server/lsa/lsa_init.c b/source4/rpc_server/lsa/lsa_init.c index 7e493e3a313..f33b61c4035 100644 --- a/source4/rpc_server/lsa/lsa_init.c +++ b/source4/rpc_server/lsa/lsa_init.c @@ -255,7 +255,7 @@ NTSTATUS dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX * return status; } - handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY); + handle = dcesrv_handle_create(dce_call, LSA_HANDLE_POLICY); if (!handle) { return NT_STATUS_NO_MEMORY; } -- 2.20.1.97.g81188d93c3-goog From e61366eb902940705d3c673448e8da6ead6a0dff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:20:44 +0100 Subject: [PATCH 037/103] s4:rpc_server/samr: make use of dcesrv_handle_create() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/samr/dcesrv_samr.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 96f68104948..b823d9cdae5 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -235,7 +235,7 @@ static NTSTATUS dcesrv_samr_Connect(struct dcesrv_call_state *dce_call, TALLOC_C } - handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_CONNECT); + handle = dcesrv_handle_create(dce_call, SAMR_HANDLE_CONNECT); if (!handle) { talloc_free(c_state); return NT_STATUS_NO_MEMORY; @@ -497,7 +497,7 @@ static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLO initialize_guid_cache(&d_state->guid_caches[i]); } - h_domain = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_DOMAIN); + h_domain = dcesrv_handle_create(dce_call, SAMR_HANDLE_DOMAIN); if (!h_domain) { talloc_free(d_state); return NT_STATUS_NO_MEMORY; @@ -1105,7 +1105,7 @@ static NTSTATUS dcesrv_samr_CreateDomainGroup(struct dcesrv_call_state *dce_call a_state->account_name = talloc_steal(a_state, groupname); /* create the policy handle */ - g_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_GROUP); + g_handle = dcesrv_handle_create(dce_call, SAMR_HANDLE_GROUP); if (!g_handle) { return NT_STATUS_NO_MEMORY; } @@ -1461,7 +1461,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL } /* create the policy handle */ - u_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_USER); + u_handle = dcesrv_handle_create(dce_call, SAMR_HANDLE_USER); if (!u_handle) { return NT_STATUS_NO_MEMORY; } @@ -1771,7 +1771,7 @@ static NTSTATUS dcesrv_samr_CreateDomAlias(struct dcesrv_call_state *dce_call, T a_state->account_name = talloc_steal(a_state, alias_name); /* create the policy handle */ - a_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_ALIAS); + a_handle = dcesrv_handle_create(dce_call, SAMR_HANDLE_ALIAS); if (a_handle == NULL) return NT_STATUS_NO_MEMORY; @@ -2162,7 +2162,7 @@ static NTSTATUS dcesrv_samr_OpenGroup(struct dcesrv_call_state *dce_call, TALLOC } /* create the policy handle */ - g_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_GROUP); + g_handle = dcesrv_handle_create(dce_call, SAMR_HANDLE_GROUP); if (!g_handle) { return NT_STATUS_NO_MEMORY; } @@ -2622,7 +2622,7 @@ static NTSTATUS dcesrv_samr_OpenAlias(struct dcesrv_call_state *dce_call, TALLOC } /* create the policy handle */ - g_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_ALIAS); + g_handle = dcesrv_handle_create(dce_call, SAMR_HANDLE_ALIAS); if (!g_handle) { return NT_STATUS_NO_MEMORY; } @@ -3005,7 +3005,7 @@ static NTSTATUS dcesrv_samr_OpenUser(struct dcesrv_call_state *dce_call, TALLOC_ } /* create the policy handle */ - u_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_USER); + u_handle = dcesrv_handle_create(dce_call, SAMR_HANDLE_USER); if (!u_handle) { return NT_STATUS_NO_MEMORY; } -- 2.20.1.97.g81188d93c3-goog From 5d406b9dde4622c50491db453e720a228046d202 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:20:44 +0100 Subject: [PATCH 038/103] s4:rpc_server/winreg: make use of dcesrv_handle_create() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/winreg/rpc_winreg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/winreg/rpc_winreg.c b/source4/rpc_server/winreg/rpc_winreg.c index 48d191db960..d7ae5ac694a 100644 --- a/source4/rpc_server/winreg/rpc_winreg.c +++ b/source4/rpc_server/winreg/rpc_winreg.c @@ -62,7 +62,7 @@ static WERROR dcesrv_winreg_openhive(struct dcesrv_call_state *dce_call, struct dcesrv_handle *h; WERROR result; - h = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY); + h = dcesrv_handle_create(dce_call, HTYPE_REGKEY); W_ERROR_HAVE_NO_MEMORY(h); result = reg_get_predefined_key(ctx, hkey, @@ -125,7 +125,7 @@ static WERROR dcesrv_winreg_CreateKey(struct dcesrv_call_state *dce_call, DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; - newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY); + newh = dcesrv_handle_create(dce_call, HTYPE_REGKEY); switch (security_session_user_level(session_info, NULL)) { @@ -434,7 +434,7 @@ static WERROR dcesrv_winreg_OpenKey(struct dcesrv_call_state *dce_call, newh = talloc_reference(dce_call->context, h); result = WERR_OK; } else { - newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY); + newh = dcesrv_handle_create(dce_call, HTYPE_REGKEY); result = reg_open_key(newh, key, r->in.keyname.name, (struct registry_key **)&newh->data); } -- 2.20.1.97.g81188d93c3-goog From ec14b205a52dd3f4f0dd77aa52909a029cd3a572 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:20:44 +0100 Subject: [PATCH 039/103] s4:rpc_server: only use the new dcesrv_handle_{create,lookup}() api BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 8cf7ed8cf04..ba14ab8f824 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -161,20 +161,20 @@ struct dcesrv_call_state { * created and fetch using the dcesrv_handle_* functions. * * Use -* dcesrv_handle_new(struct dcesrv_connection \*, uint8 handle_type) +* dcesrv_handle_create(struct dcesrv_call_state \*, uint8 handle_type) * to obtain a new handle of the specified type. Handle types are * unique within each pipe. * * The handle can later be fetched again using: * -* struct dcesrv_handle *dcesrv_handle_fetch( -* struct dcesrv_connection *dce_conn, +* struct dcesrv_handle *dcesrv_handle_lookup( +* struct dcesrv_call_state *dce_call, * struct policy_handle *p, * uint8 handle_type) * * and destroyed by: * -* dcesrv_handle_destroy(struct dcesrv_handle *). +* TALLOC_FREE(struct dcesrv_handle *). * * User data should be stored in the 'data' member of the dcesrv_handle * struct. @@ -481,7 +481,7 @@ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call, invalid handle or retval if the handle is of the wrong type */ #define DCESRV_PULL_HANDLE_RETVAL(h, inhandle, t, retval) do { \ - (h) = dcesrv_handle_fetch(dce_call->context, (inhandle), DCESRV_HANDLE_ANY); \ + (h) = dcesrv_handle_lookup(dce_call, (inhandle), DCESRV_HANDLE_ANY); \ DCESRV_CHECK_HANDLE(h); \ if ((t) != DCESRV_HANDLE_ANY && (h)->wire_handle.handle_type != (t)) { \ return retval; \ @@ -491,7 +491,7 @@ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call, /* this checks for a valid policy handle and gives a dcerpc fault if its the wrong type of handle */ #define DCESRV_PULL_HANDLE_FAULT(h, inhandle, t) do { \ - (h) = dcesrv_handle_fetch(dce_call->context, (inhandle), t); \ + (h) = dcesrv_handle_lookup(dce_call, (inhandle), t); \ DCESRV_CHECK_HANDLE(h); \ } while (0) -- 2.20.1.97.g81188d93c3-goog From 3d097889423a5eb6edabcd014e3792d9ec7f11f8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:20:44 +0100 Subject: [PATCH 040/103] s4:rpc_server: remove the old dcesrv_handle_{new,fetch}() api BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.h | 6 ------ source4/rpc_server/handles.c | 33 ++++++++++-------------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index ba14ab8f824..7923d3bd234 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -427,15 +427,9 @@ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_servers, struct dcesrv_context **_dce_ctx); NTSTATUS dcesrv_reply(struct dcesrv_call_state *call); -struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_context *context, - uint8_t handle_type); struct dcesrv_handle *dcesrv_handle_create(struct dcesrv_call_state *call, uint8_t handle_type); -struct dcesrv_handle *dcesrv_handle_fetch( - struct dcesrv_connection_context *context, - const struct policy_handle *p, - uint8_t handle_type); struct dcesrv_handle *dcesrv_handle_lookup(struct dcesrv_call_state *call, const struct policy_handle *p, uint8_t handle_type); diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index 043870fa663..2362a89dbd6 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -38,9 +38,11 @@ static int dcesrv_handle_destructor(struct dcesrv_handle *h) /* allocate a new rpc handle */ -_PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_context *context, - uint8_t handle_type) +_PUBLIC_ +struct dcesrv_handle *dcesrv_handle_create(struct dcesrv_call_state *call, + uint8_t handle_type) { + struct dcesrv_connection_context *context = call->context; struct dcesrv_handle *h; struct dom_sid *sid; @@ -73,22 +75,17 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_contex return h; } -_PUBLIC_ -struct dcesrv_handle *dcesrv_handle_create(struct dcesrv_call_state *call, - uint8_t handle_type) -{ - return dcesrv_handle_new(call->context, handle_type); -} - /** find an internal handle given a wire handle. If the wire handle is NULL then allocate a new handle */ -_PUBLIC_ struct dcesrv_handle *dcesrv_handle_fetch( - struct dcesrv_connection_context *context, - const struct policy_handle *p, - uint8_t handle_type) + +_PUBLIC_ +struct dcesrv_handle *dcesrv_handle_lookup(struct dcesrv_call_state *call, + const struct policy_handle *p, + uint8_t handle_type) { + struct dcesrv_connection_context *context = call->context; struct dcesrv_handle *h; struct dom_sid *sid; @@ -101,7 +98,7 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_fetch( if (ndr_policy_handle_empty(p)) { /* TODO: we should probably return a NULL handle here */ - return dcesrv_handle_new(context, handle_type); + return dcesrv_handle_create(call, handle_type); } for (h=context->conn->assoc_group->handles; h; h=h->next) { @@ -129,11 +126,3 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_fetch( return NULL; } - -_PUBLIC_ -struct dcesrv_handle *dcesrv_handle_lookup(struct dcesrv_call_state *call, - const struct policy_handle *p, - uint8_t handle_type) -{ - return dcesrv_handle_fetch(call->context, p, handle_type); -} -- 2.20.1.97.g81188d93c3-goog From 44683b523c2491eaacce2b3072e0120cd6b29dec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Nov 2018 01:19:51 +0100 Subject: [PATCH 041/103] s4:rpc_server/handles: make use dcesrv_call_session_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/handles.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index 2362a89dbd6..b0cef1c27f7 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -43,6 +43,8 @@ struct dcesrv_handle *dcesrv_handle_create(struct dcesrv_call_state *call, uint8_t handle_type) { struct dcesrv_connection_context *context = call->context; + struct auth_session_info *session_info = + dcesrv_call_session_info(call); struct dcesrv_handle *h; struct dom_sid *sid; @@ -51,7 +53,7 @@ struct dcesrv_handle *dcesrv_handle_create(struct dcesrv_call_state *call, */ SMB_ASSERT((context->iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) == 0); - sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; + sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; h = talloc_zero(context->conn->assoc_group, struct dcesrv_handle); if (!h) { @@ -86,6 +88,8 @@ struct dcesrv_handle *dcesrv_handle_lookup(struct dcesrv_call_state *call, uint8_t handle_type) { struct dcesrv_connection_context *context = call->context; + struct auth_session_info *session_info = + dcesrv_call_session_info(call); struct dcesrv_handle *h; struct dom_sid *sid; @@ -94,7 +98,7 @@ struct dcesrv_handle *dcesrv_handle_lookup(struct dcesrv_call_state *call, */ SMB_ASSERT((context->iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) == 0); - sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; + sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; if (ndr_policy_handle_empty(p)) { /* TODO: we should probably return a NULL handle here */ -- 2.20.1.97.g81188d93c3-goog From 8d61b32bf9462291781569c701b93d7090db19ab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:44:30 +0100 Subject: [PATCH 042/103] s4:rpc_server: add dcesrv_call_auth_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 17 +++++++++++++++++ source4/rpc_server/dcerpc_server.h | 7 +++++++ 2 files changed, 24 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 828a936c0b8..8f48814366b 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -3233,3 +3233,20 @@ _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_s { return dce_call->context->conn->auth_state.session_info; } + +/** + * retrieve auth type/level from a dce_call + */ +_PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call, + enum dcerpc_AuthType *auth_type, + enum dcerpc_AuthLevel *auth_level) +{ + struct dcesrv_auth *auth = &dce_call->conn->auth_state; + + if (auth_type != NULL) { + *auth_type = auth->auth_type; + } + if (auth_level != NULL) { + *auth_level = auth->auth_level; + } +} diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 7923d3bd234..1ba676fecfa 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -519,6 +519,13 @@ _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call */ _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call); +/** + * retrieve auth type/level from a dce_call + */ +_PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call, + enum dcerpc_AuthType *auth_type, + enum dcerpc_AuthLevel *auth_level); + _PUBLIC_ NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface); _PUBLIC_ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, -- 2.20.1.97.g81188d93c3-goog From 1fcceb2044f222037541c655d9dd53a88372681e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:44:30 +0100 Subject: [PATCH 043/103] s4:rpc_server/samr: make use of dcesrv_call_auth_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/samr/dcesrv_samr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index b823d9cdae5..921d2965d7c 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -4876,12 +4876,14 @@ static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, NTSTATUS status; enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; if (transport != NCACN_IP_TCP && transport != NCALRPC) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } - if (dce_call->conn->auth_state.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { + dcesrv_call_auth_info(dce_call, NULL, &auth_level); + if (auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } -- 2.20.1.97.g81188d93c3-goog From 91d698d8fe309d36b253958cafd6729bcd7618c2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:44:30 +0100 Subject: [PATCH 044/103] s4:rpc_server/lsa: make use of dcesrv_call_auth_info() It's enough to check the auth_type for DCERPC_AUTH_TYPE_SCHANNEL, there's no need to also check the auth_level for integrity or privacy. The gensec layer already required at least DCERPC_AUTH_LEVEL_INTEGRITY, see schannel_update_internal(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/lsa/lsa_lookup.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/source4/rpc_server/lsa/lsa_lookup.c b/source4/rpc_server/lsa/lsa_lookup.c index 7e28791336b..a2723dc6849 100644 --- a/source4/rpc_server/lsa/lsa_lookup.c +++ b/source4/rpc_server/lsa/lsa_lookup.c @@ -676,7 +676,7 @@ NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call, { enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); - const struct dcesrv_auth *auth = &dce_call->conn->auth_state; + enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; struct dcesrv_lsa_LookupSids_base_state *state = NULL; NTSTATUS status; @@ -687,9 +687,12 @@ NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call, /* * We don't have policy handles on this call. So this must be restricted * to crypto connections only. + * + * NB. gensec requires schannel connections to + * have at least DCERPC_AUTH_LEVEL_INTEGRITY. */ - if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || - auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + dcesrv_call_auth_info(dce_call, &auth_type, NULL); + if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } @@ -1295,7 +1298,7 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX { enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); - const struct dcesrv_auth *auth = &dce_call->conn->auth_state; + enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; struct dcesrv_lsa_LookupNames_base_state *state = NULL; NTSTATUS status; @@ -1307,8 +1310,8 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX * We don't have policy handles on this call. So this must be restricted * to crypto connections only. */ - if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || - auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + dcesrv_call_auth_info(dce_call, &auth_type, NULL); + if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } -- 2.20.1.97.g81188d93c3-goog From aba7aca84a34b856095728bdca00ec48d9e964cc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 13:05:25 +0100 Subject: [PATCH 045/103] s4:rpc_server/netlogon: simplify logic of dcesrv_netr_creds_server_step_check() It's enough to check the auth_type for DCERPC_AUTH_TYPE_SCHANNEL, there's no need to also check the auth_level for integrity or privacy. The gensec layer already required at least DCERPC_AUTH_LEVEL_INTEGRITY, see schannel_update_internal(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 41 ++----------------- 1 file changed, 4 insertions(+), 37 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index b7d174da65f..72b50327c50 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -620,38 +620,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_ca * The reason we keep 2 copies is that they use different structures to * represent the auth_info and the decrpc pipes. */ - -/* - * If schannel is required for this call test that it actually is available. - */ -static NTSTATUS schannel_check_required(const struct dcesrv_auth *auth_info, - const char *computer_name, - bool integrity, bool privacy) -{ - - if (auth_info && auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { - if (!privacy && !integrity) { - return NT_STATUS_OK; - } - - if ((!privacy && integrity) && - auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) { - return NT_STATUS_OK; - } - - if ((privacy || integrity) && - auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { - return NT_STATUS_OK; - } - } - - /* test didn't pass */ - DEBUG(0, ("schannel_check_required: [%s] is not using schannel\n", - computer_name)); - - return NT_STATUS_ACCESS_DENIED; -} - static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, const char *computer_name, @@ -664,11 +632,10 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc bool schannel_global_required = (schannel == true); if (schannel_global_required) { - nt_status = schannel_check_required(&dce_call->conn->auth_state, - computer_name, - true, false); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; + if (dce_call->conn->auth_state.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { + DBG_ERR("[%s] is not using schannel\n", + computer_name); + return NT_STATUS_ACCESS_DENIED; } } -- 2.20.1.97.g81188d93c3-goog From 5037c94d6e1526419ea60e7f81496dff375b1fde Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 12:44:30 +0100 Subject: [PATCH 046/103] s4:rpc_server/netlogon: make use of dcesrv_call_auth_info() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 72b50327c50..c1237933e68 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -632,7 +632,11 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc bool schannel_global_required = (schannel == true); if (schannel_global_required) { - if (dce_call->conn->auth_state.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { + enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; + + dcesrv_call_auth_info(dce_call, &auth_type, NULL); + + if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { DBG_ERR("[%s] is not using schannel\n", computer_name); return NT_STATUS_ACCESS_DENIED; @@ -834,6 +838,8 @@ static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TAL static NTSTATUS dcesrv_netr_LogonSamLogon_check(struct dcesrv_call_state *dce_call, const struct netr_LogonSamLogonEx *r) { + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; + switch (r->in.logon_level) { case NetlogonInteractiveInformation: case NetlogonServiceInformation: @@ -888,9 +894,11 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_check(struct dcesrv_call_state *dce_ca return NT_STATUS_INVALID_PARAMETER; } + dcesrv_call_auth_info(dce_call, NULL, &auth_level); + switch (r->in.validation_level) { case NetlogonValidationSamInfo4: /* 6 */ - if (dce_call->conn->auth_state.auth_level < DCERPC_AUTH_LEVEL_PRIVACY) { + if (auth_level < DCERPC_AUTH_LEVEL_PRIVACY) { return NT_STATUS_INVALID_PARAMETER; } break; @@ -1278,6 +1286,7 @@ static void dcesrv_netr_LogonSamLogon_base_reply( static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_LogonSamLogonEx *r) { + enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; struct dcesrv_netr_LogonSamLogon_base_state *state; NTSTATUS nt_status; @@ -1315,7 +1324,9 @@ static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, return nt_status; } - if (dce_call->conn->auth_state.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { + dcesrv_call_auth_info(dce_call, &auth_type, NULL); + + if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { return NT_STATUS_ACCESS_DENIED; } -- 2.20.1.97.g81188d93c3-goog From bea417e8ca15643678e569748b9f5ab2f420930e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 13:08:19 +0100 Subject: [PATCH 047/103] s4:rpc_server/remote: make use of dcesrv_call_credentials() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/remote/dcesrv_remote.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index b32fe9bb8d9..86d165bd6e2 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -47,7 +47,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct const char *binding = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "binding"); const char *user, *pass, *domain; struct cli_credentials *credentials; - bool must_free_credentials = true; + bool must_free_credentials = false; bool machine_account; struct dcerpc_binding *b; struct composite_context *pipe_conn_req; @@ -78,12 +78,15 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct return NT_STATUS_NET_WRITE_FAULT; } + credentials = dcesrv_call_credentials(dce_call); + if (user && pass) { DEBUG(5, ("dcerpc_remote: RPC Proxy: Using specified account\n")); credentials = cli_credentials_init(priv); if (!credentials) { return NT_STATUS_NO_MEMORY; } + must_free_credentials = true; cli_credentials_set_conf(credentials, dce_call->conn->dce_ctx->lp_ctx); cli_credentials_set_username(credentials, user, CRED_SPECIFIED); if (domain) { @@ -93,6 +96,10 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct } else if (machine_account) { DEBUG(5, ("dcerpc_remote: RPC Proxy: Using machine account\n")); credentials = cli_credentials_init(priv); + if (!credentials) { + return NT_STATUS_NO_MEMORY; + } + must_free_credentials = true; cli_credentials_set_conf(credentials, dce_call->conn->dce_ctx->lp_ctx); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); @@ -101,10 +108,8 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct if (!NT_STATUS_IS_OK(status)) { return status; } - } else if (dce_call->conn->auth_state.session_info->credentials) { + } else if (credentials != NULL) { DEBUG(5, ("dcerpc_remote: RPC Proxy: Using delegated credentials\n")); - credentials = dce_call->conn->auth_state.session_info->credentials; - must_free_credentials = false; } else { DEBUG(1,("dcerpc_remote: RPC Proxy: You must supply binding, user and password or have delegated credentials\n")); return NT_STATUS_INVALID_PARAMETER; -- 2.20.1.97.g81188d93c3-goog From 58d3b49516d518d89ec25179508e1cefe3a03a0b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Oct 2018 17:12:02 +0100 Subject: [PATCH 048/103] s4:rpc_server: use helper variables to access 'struct dcesrv_auth' in dcesrv_auth.c BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcesrv_auth.c | 87 +++++++++++++++++--------------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index efc16e91339..bd05accc6c4 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -70,7 +70,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) "DCE/RPC", auth_type, transport_protection, - call->conn->auth_state.session_info); + auth->session_info); return true; } @@ -244,6 +244,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) { struct dcesrv_connection *dce_conn = call->conn; + struct dcesrv_auth *auth = &call->conn->auth_state; const char *pdu = ""; switch (call->pkt.ptype) { @@ -274,15 +275,15 @@ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) return status; } - status = gensec_session_info(dce_conn->auth_state.gensec_security, - dce_conn, - &dce_conn->auth_state.session_info); + status = gensec_session_info(auth->gensec_security, + dce_conn, // TODO + &auth->session_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return status; } - dce_conn->auth_state.auth_finished = true; + auth->auth_finished = true; dce_conn->allow_request = true; if (call->pkt.ptype != DCERPC_PKT_AUTH3) { @@ -305,29 +306,30 @@ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) NTSTATUS dcesrv_auth_prepare_bind_ack(struct dcesrv_call_state *call, struct ncacn_packet *pkt) { struct dcesrv_connection *dce_conn = call->conn; + struct dcesrv_auth *auth = &call->conn->auth_state; dce_conn->allow_alter = true; dce_conn->allow_auth3 = true; if (call->pkt.auth_length == 0) { - dce_conn->auth_state.auth_finished = true; + auth->auth_finished = true; dce_conn->allow_request = true; return NT_STATUS_OK; } /* We can't work without an existing gensec state */ - if (!call->conn->auth_state.gensec_security) { + if (auth->gensec_security == NULL) { return NT_STATUS_INTERNAL_ERROR; } - if (dce_conn->auth_state.hdr_signing) { + if (auth->hdr_signing) { pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; } call->_out_auth_info = (struct dcerpc_auth) { - .auth_type = dce_conn->auth_state.auth_type, - .auth_level = dce_conn->auth_state.auth_level, - .auth_context_id = dce_conn->auth_state.auth_context_id, + .auth_type = auth->auth_type, + .auth_level = auth->auth_level, + .auth_context_id = auth->auth_context_id, }; call->out_auth_info = &call->_out_auth_info; @@ -340,19 +342,19 @@ NTSTATUS dcesrv_auth_prepare_bind_ack(struct dcesrv_call_state *call, struct nca bool dcesrv_auth_prepare_auth3(struct dcesrv_call_state *call) { struct ncacn_packet *pkt = &call->pkt; - struct dcesrv_connection *dce_conn = call->conn; + struct dcesrv_auth *auth = &call->conn->auth_state; NTSTATUS status; if (pkt->auth_length == 0) { return false; } - if (dce_conn->auth_state.auth_finished) { + if (auth->auth_finished) { return false; } /* We can't work without an existing gensec state */ - if (!dce_conn->auth_state.gensec_security) { + if (auth->gensec_security == NULL) { return false; } @@ -367,22 +369,22 @@ bool dcesrv_auth_prepare_auth3(struct dcesrv_call_state *call) return false; } - if (call->in_auth_info.auth_type != dce_conn->auth_state.auth_type) { + if (call->in_auth_info.auth_type != auth->auth_type) { return false; } - if (call->in_auth_info.auth_level != dce_conn->auth_state.auth_level) { + if (call->in_auth_info.auth_level != auth->auth_level) { return false; } - if (call->in_auth_info.auth_context_id != dce_conn->auth_state.auth_context_id) { + if (call->in_auth_info.auth_context_id != auth->auth_context_id) { return false; } call->_out_auth_info = (struct dcerpc_auth) { - .auth_type = dce_conn->auth_state.auth_type, - .auth_level = dce_conn->auth_state.auth_level, - .auth_context_id = dce_conn->auth_state.auth_context_id, + .auth_type = auth->auth_type, + .auth_level = auth->auth_level, + .auth_context_id = auth->auth_context_id, }; call->out_auth_info = &call->_out_auth_info; @@ -397,24 +399,24 @@ bool dcesrv_auth_prepare_auth3(struct dcesrv_call_state *call) bool dcesrv_auth_alter(struct dcesrv_call_state *call) { struct ncacn_packet *pkt = &call->pkt; - struct dcesrv_connection *dce_conn = call->conn; + struct dcesrv_auth *auth = &call->conn->auth_state; NTSTATUS status; /* on a pure interface change there is no auth blob */ if (pkt->auth_length == 0) { - if (!dce_conn->auth_state.auth_finished) { + if (!auth->auth_finished) { return false; } return true; } - if (dce_conn->auth_state.auth_finished) { + if (auth->auth_finished) { call->fault_code = DCERPC_FAULT_ACCESS_DENIED; return false; } /* We can't work without an existing gensec state */ - if (!dce_conn->auth_state.gensec_security) { + if (auth->gensec_security == NULL) { return false; } @@ -430,15 +432,15 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) return false; } - if (call->in_auth_info.auth_type != dce_conn->auth_state.auth_type) { + if (call->in_auth_info.auth_type != auth->auth_type) { return false; } - if (call->in_auth_info.auth_level != dce_conn->auth_state.auth_level) { + if (call->in_auth_info.auth_level != auth->auth_level) { return false; } - if (call->in_auth_info.auth_context_id != dce_conn->auth_state.auth_context_id) { + if (call->in_auth_info.auth_context_id != auth->auth_context_id) { return false; } @@ -451,7 +453,7 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) */ NTSTATUS dcesrv_auth_prepare_alter_ack(struct dcesrv_call_state *call, struct ncacn_packet *pkt) { - struct dcesrv_connection *dce_conn = call->conn; + struct dcesrv_auth *auth = &call->conn->auth_state; /* on a pure interface change there is no auth_info structure setup */ @@ -459,14 +461,14 @@ NTSTATUS dcesrv_auth_prepare_alter_ack(struct dcesrv_call_state *call, struct nc return NT_STATUS_OK; } - if (!call->conn->auth_state.gensec_security) { + if (auth->gensec_security == NULL) { return NT_STATUS_INTERNAL_ERROR; } call->_out_auth_info = (struct dcerpc_auth) { - .auth_type = dce_conn->auth_state.auth_type, - .auth_level = dce_conn->auth_state.auth_level, - .auth_context_id = dce_conn->auth_state.auth_context_id, + .auth_type = auth->auth_type, + .auth_level = auth->auth_level, + .auth_context_id = auth->auth_context_id, }; call->out_auth_info = &call->_out_auth_info; @@ -485,10 +487,11 @@ bool dcesrv_auth_pkt_pull(struct dcesrv_call_state *call, { struct ncacn_packet *pkt = &call->pkt; struct dcesrv_connection *dce_conn = call->conn; + struct dcesrv_auth *auth = &call->conn->auth_state; const struct dcerpc_auth tmp_auth = { - .auth_type = dce_conn->auth_state.auth_type, - .auth_level = dce_conn->auth_state.auth_level, - .auth_context_id = dce_conn->auth_state.auth_context_id, + .auth_type = auth->auth_type, + .auth_level = auth->auth_level, + .auth_context_id = auth->auth_context_id, }; NTSTATUS status; @@ -497,12 +500,12 @@ bool dcesrv_auth_pkt_pull(struct dcesrv_call_state *call, return false; } - if (dce_conn->auth_state.auth_invalid) { + if (auth->auth_invalid) { return false; } status = dcerpc_ncacn_pull_pkt_auth(&tmp_auth, - dce_conn->auth_state.gensec_security, + auth->gensec_security, call, pkt->ptype, required_flags, @@ -543,16 +546,16 @@ bool dcesrv_auth_pkt_push(struct dcesrv_call_state *call, const DATA_BLOB *payload, const struct ncacn_packet *pkt) { - struct dcesrv_connection *dce_conn = call->conn; + struct dcesrv_auth *auth = &call->conn->auth_state; const struct dcerpc_auth tmp_auth = { - .auth_type = dce_conn->auth_state.auth_type, - .auth_level = dce_conn->auth_state.auth_level, - .auth_context_id = dce_conn->auth_state.auth_context_id, + .auth_type = auth->auth_type, + .auth_level = auth->auth_level, + .auth_context_id = auth->auth_context_id, }; NTSTATUS status; status = dcerpc_ncacn_push_pkt_auth(&tmp_auth, - dce_conn->auth_state.gensec_security, + auth->gensec_security, call, blob, sig_size, payload_offset, payload, -- 2.20.1.97.g81188d93c3-goog From 9cf27c6f0f29bfce0e995c8e139249bcad800c41 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Oct 2018 17:12:02 +0100 Subject: [PATCH 049/103] s4:rpc_server: use helper variables to access 'struct dcesrv_auth' in common/reply.c BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/common/reply.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index d0d81fe1027..7e474e08279 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -159,6 +159,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) DATA_BLOB stub; uint32_t total_length, chunk_size; struct dcesrv_connection_context *context = call->context; + struct dcesrv_auth *auth = &call->conn->auth_state; size_t sig_size = 0; /* call the reply function */ @@ -193,14 +194,13 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) request header size */ chunk_size = call->conn->max_xmit_frag; chunk_size -= DCERPC_REQUEST_LENGTH; - if (call->conn->auth_state.auth_finished && - call->conn->auth_state.gensec_security) { + if (auth->auth_finished && auth->gensec_security != NULL) { size_t max_payload = chunk_size; max_payload -= DCERPC_AUTH_TRAILER_LENGTH; max_payload -= (max_payload % DCERPC_AUTH_PAD_ALIGNMENT); - sig_size = gensec_sig_size(call->conn->auth_state.gensec_security, + sig_size = gensec_sig_size(auth->gensec_security, max_payload); if (sig_size) { chunk_size -= DCERPC_AUTH_TRAILER_LENGTH; -- 2.20.1.97.g81188d93c3-goog From b9bf111c7d467435f59b3f3eb9b19f37a106cff5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Oct 2018 17:12:02 +0100 Subject: [PATCH 050/103] s4:rpc_server: use helper variables to access 'struct dcesrv_auth' in dcerpc_server.c BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 43 +++++++++++++++++------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 8f48814366b..fea3fb305ae 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1278,7 +1278,7 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); } - if (call->conn->auth_state.auth_finished) { + if (auth->auth_finished) { return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); } @@ -1307,7 +1307,7 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) * In anycase we mark the connection as * invalid. */ - call->conn->auth_state.auth_invalid = true; + auth->auth_invalid = true; if (call->fault_code != 0) { return dcesrv_fault_disconnect(call, call->fault_code); } @@ -1332,6 +1332,7 @@ static void dcesrv_auth3_done(struct tevent_req *subreq) tevent_req_callback_data(subreq, struct dcesrv_call_state); struct dcesrv_connection *conn = call->conn; + struct dcesrv_auth *auth = &call->conn->auth_state; NTSTATUS status; status = gensec_update_recv(subreq, call, @@ -1347,7 +1348,7 @@ static void dcesrv_auth3_done(struct tevent_req *subreq) * In anycase we mark the connection as * invalid. */ - call->conn->auth_state.auth_invalid = true; + auth->auth_invalid = true; if (call->fault_code != 0) { status = dcesrv_fault_disconnect(call, call->fault_code); dcesrv_conn_auth_wait_finished(conn, status); @@ -1690,9 +1691,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) /* handle any authentication that is being requested */ if (!auth_ok) { - if (call->in_auth_info.auth_type != - call->conn->auth_state.auth_type) - { + if (call->in_auth_info.auth_type != auth->auth_type) { return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR); } @@ -1783,7 +1782,8 @@ static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why) static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call) { TALLOC_CTX *frame = talloc_stackframe(); - const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ? + const struct dcesrv_auth *auth = &call->conn->auth_state; + const uint32_t bitmask1 = auth->client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0; const struct dcerpc_sec_vt_pcontext pcontext = { .abstract_syntax = call->context->iface->syntax_id, @@ -1822,6 +1822,7 @@ done: static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) { const struct dcesrv_endpoint *endpoint = call->conn->endpoint; + struct dcesrv_auth *auth = &call->conn->auth_state; enum dcerpc_transport_t transport = dcerpc_binding_get_transport(endpoint->ep_description); struct ndr_pull *pull; @@ -1832,8 +1833,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } /* if authenticated, and the mech we use can't do async replies, don't use them... */ - if (call->conn->auth_state.gensec_security && - !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) { + if (auth->gensec_security != NULL && + !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) { call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC; } @@ -1842,7 +1843,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) DCERPC_PFC_FLAG_DID_NOT_EXECUTE); } - switch (call->conn->auth_state.auth_level) { + switch (auth->auth_level) { case DCERPC_AUTH_LEVEL_NONE: case DCERPC_AUTH_LEVEL_PACKET: case DCERPC_AUTH_LEVEL_INTEGRITY: @@ -1859,8 +1860,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) "to [%s] with auth[type=0x%x,level=0x%x] " "on [%s] from [%s]\n", __func__, call->context->iface->name, - call->conn->auth_state.auth_type, - call->conn->auth_state.auth_level, + auth->auth_type, + auth->auth_level, derpc_transport_string_by_transport(transport), addr)); return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); @@ -1868,7 +1869,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) break; } - if (call->conn->auth_state.auth_level < call->context->min_auth_level) { + if (auth->auth_level < call->context->min_auth_level) { char *addr; addr = tsocket_address_string(call->conn->remote_address, call); @@ -1879,8 +1880,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) __func__, call->context->min_auth_level, call->context->iface->name, - call->conn->auth_state.auth_type, - call->conn->auth_state.auth_level, + auth->auth_type, + auth->auth_level, derpc_transport_string_by_transport(transport), addr)); return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); @@ -3205,7 +3206,8 @@ NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx, */ _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call) { - return dce_call->conn->auth_state.session_info->credentials; + struct dcesrv_auth *auth = &dce_call->conn->auth_state; + return auth->session_info->credentials; } /** @@ -3213,8 +3215,9 @@ _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_stat */ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call) { + struct dcesrv_auth *auth = &dce_call->conn->auth_state; enum security_user_level level; - level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL); + level = security_session_user_level(auth->session_info, NULL); return level >= SECURITY_USER; } @@ -3223,7 +3226,8 @@ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call) */ _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call) { - return dce_call->context->conn->auth_state.session_info->info->account_name; + struct dcesrv_auth *auth = &dce_call->conn->auth_state; + return auth->session_info->info->account_name; } /** @@ -3231,7 +3235,8 @@ _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call */ _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call) { - return dce_call->context->conn->auth_state.session_info; + struct dcesrv_auth *auth = &dce_call->conn->auth_state; + return auth->session_info; } /** -- 2.20.1.97.g81188d93c3-goog From 0f277be2de3f9544a5cada3ae90bb7f46ba0eb14 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Oct 2018 14:44:33 +0100 Subject: [PATCH 051/103] s4:rpc_server: introduce dcesrv_call_state->auth_state BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 2 ++ source4/rpc_server/dcerpc_server.h | 1 + 2 files changed, 3 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index fea3fb305ae..651f5369ef9 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -2000,6 +2000,8 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, talloc_steal(call, blob.data); call->pkt = *pkt; + call->auth_state = &dce_conn->auth_state; + talloc_set_destructor(call, dcesrv_call_dequeue); if (call->conn->allow_bind) { diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 1ba676fecfa..41613cb0899 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -88,6 +88,7 @@ struct data_blob_list_item { /* the state of an ongoing dcerpc call */ struct dcesrv_call_state { struct dcesrv_call_state *next, *prev; + struct dcesrv_auth *auth_state; struct dcesrv_connection *conn; struct dcesrv_connection_context *context; struct ncacn_packet pkt; -- 2.20.1.97.g81188d93c3-goog From 1e09953ed634b6bd1438936e811db07c0b3ef899 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Oct 2018 14:44:33 +0100 Subject: [PATCH 052/103] s4:rpc_server: make use of dcesrv_call_state->auth_state in dcesrv_auth.c BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcesrv_auth.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index bd05accc6c4..a32bbea9a03 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -42,7 +42,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) struct cli_credentials *server_credentials = NULL; struct ncacn_packet *pkt = &call->pkt; struct dcesrv_connection *dce_conn = call->conn; - struct dcesrv_auth *auth = &dce_conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; bool want_header_signing = false; NTSTATUS status; @@ -244,7 +244,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) { struct dcesrv_connection *dce_conn = call->conn; - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; const char *pdu = ""; switch (call->pkt.ptype) { @@ -276,7 +276,7 @@ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) } status = gensec_session_info(auth->gensec_security, - dce_conn, // TODO + dce_conn, &auth->session_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to establish session_info: %s\n", @@ -306,7 +306,7 @@ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) NTSTATUS dcesrv_auth_prepare_bind_ack(struct dcesrv_call_state *call, struct ncacn_packet *pkt) { struct dcesrv_connection *dce_conn = call->conn; - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; dce_conn->allow_alter = true; dce_conn->allow_auth3 = true; @@ -342,7 +342,7 @@ NTSTATUS dcesrv_auth_prepare_bind_ack(struct dcesrv_call_state *call, struct nca bool dcesrv_auth_prepare_auth3(struct dcesrv_call_state *call) { struct ncacn_packet *pkt = &call->pkt; - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; NTSTATUS status; if (pkt->auth_length == 0) { @@ -399,7 +399,7 @@ bool dcesrv_auth_prepare_auth3(struct dcesrv_call_state *call) bool dcesrv_auth_alter(struct dcesrv_call_state *call) { struct ncacn_packet *pkt = &call->pkt; - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; NTSTATUS status; /* on a pure interface change there is no auth blob */ @@ -453,7 +453,7 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) */ NTSTATUS dcesrv_auth_prepare_alter_ack(struct dcesrv_call_state *call, struct ncacn_packet *pkt) { - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; /* on a pure interface change there is no auth_info structure setup */ @@ -487,7 +487,7 @@ bool dcesrv_auth_pkt_pull(struct dcesrv_call_state *call, { struct ncacn_packet *pkt = &call->pkt; struct dcesrv_connection *dce_conn = call->conn; - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; const struct dcerpc_auth tmp_auth = { .auth_type = auth->auth_type, .auth_level = auth->auth_level, @@ -546,7 +546,7 @@ bool dcesrv_auth_pkt_push(struct dcesrv_call_state *call, const DATA_BLOB *payload, const struct ncacn_packet *pkt) { - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; const struct dcerpc_auth tmp_auth = { .auth_type = auth->auth_type, .auth_level = auth->auth_level, -- 2.20.1.97.g81188d93c3-goog From 643e1f93ad4b53f89da601ebb87093f50dcd9a38 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Oct 2018 14:44:33 +0100 Subject: [PATCH 053/103] s4:rpc_server: make use of dcesrv_call_state->auth_state in common/reply.c BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/common/reply.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 7e474e08279..68def745fd1 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -159,7 +159,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) DATA_BLOB stub; uint32_t total_length, chunk_size; struct dcesrv_connection_context *context = call->context; - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; size_t sig_size = 0; /* call the reply function */ -- 2.20.1.97.g81188d93c3-goog From 0e41a2f705447ce623877980d9477c6bfdda6d80 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Oct 2018 14:44:33 +0100 Subject: [PATCH 054/103] s4:rpc_server: make use of dcesrv_call_state->auth_state in dcerpc_server.c BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 651f5369ef9..5211619c09f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -499,7 +499,7 @@ static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth, _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call, DATA_BLOB *session_key) { - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; return dcesrv_session_info_session_key(auth, session_key); } @@ -514,7 +514,7 @@ _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call, _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call, DATA_BLOB *session_key) { - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; NTSTATUS status; if (auth->session_key_fn == NULL) { @@ -948,7 +948,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint16_t max_rep = 0; const char *ep_prefix = ""; const char *endpoint = NULL; - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; struct dcerpc_ack_ctx *ack_ctx_list = NULL; struct dcerpc_ack_ctx *ack_features = NULL; struct tevent_req *subreq = NULL; @@ -1270,7 +1270,7 @@ static void dcesrv_auth3_done(struct tevent_req *subreq); static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) { struct dcesrv_connection *conn = call->conn; - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; struct tevent_req *subreq = NULL; NTSTATUS status; @@ -1332,7 +1332,7 @@ static void dcesrv_auth3_done(struct tevent_req *subreq) tevent_req_callback_data(subreq, struct dcesrv_call_state); struct dcesrv_connection *conn = call->conn; - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; NTSTATUS status; status = gensec_update_recv(subreq, call, @@ -1608,7 +1608,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) bool auth_ok = false; struct ncacn_packet *pkt = &call->ack_pkt; uint32_t extra_flags = 0; - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; struct dcerpc_ack_ctx *ack_ctx_list = NULL; struct tevent_req *subreq = NULL; size_t i; @@ -1782,7 +1782,7 @@ static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why) static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call) { TALLOC_CTX *frame = talloc_stackframe(); - const struct dcesrv_auth *auth = &call->conn->auth_state; + const struct dcesrv_auth *auth = call->auth_state; const uint32_t bitmask1 = auth->client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0; const struct dcerpc_sec_vt_pcontext pcontext = { @@ -1822,7 +1822,7 @@ done: static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) { const struct dcesrv_endpoint *endpoint = call->conn->endpoint; - struct dcesrv_auth *auth = &call->conn->auth_state; + struct dcesrv_auth *auth = call->auth_state; enum dcerpc_transport_t transport = dcerpc_binding_get_transport(endpoint->ep_description); struct ndr_pull *pull; @@ -3208,7 +3208,7 @@ NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx, */ _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call) { - struct dcesrv_auth *auth = &dce_call->conn->auth_state; + struct dcesrv_auth *auth = dce_call->auth_state; return auth->session_info->credentials; } @@ -3217,7 +3217,7 @@ _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_stat */ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call) { - struct dcesrv_auth *auth = &dce_call->conn->auth_state; + struct dcesrv_auth *auth = dce_call->auth_state; enum security_user_level level; level = security_session_user_level(auth->session_info, NULL); return level >= SECURITY_USER; @@ -3228,7 +3228,7 @@ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call) */ _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call) { - struct dcesrv_auth *auth = &dce_call->conn->auth_state; + struct dcesrv_auth *auth = dce_call->auth_state; return auth->session_info->info->account_name; } @@ -3237,7 +3237,7 @@ _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call */ _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call) { - struct dcesrv_auth *auth = &dce_call->conn->auth_state; + struct dcesrv_auth *auth = dce_call->auth_state; return auth->session_info; } @@ -3248,7 +3248,7 @@ _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call, enum dcerpc_AuthType *auth_type, enum dcerpc_AuthLevel *auth_level) { - struct dcesrv_auth *auth = &dce_call->conn->auth_state; + struct dcesrv_auth *auth = dce_call->auth_state; if (auth_type != NULL) { *auth_type = auth->auth_type; -- 2.20.1.97.g81188d93c3-goog From f87be4c9e4813834e23147a5eaae1b7c18431df9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 13:28:07 +0100 Subject: [PATCH 055/103] s4:rpc_server: allocate struct dcesrv_auth with talloc BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 68 ++++++++++++++++++++---------- source4/rpc_server/dcerpc_server.h | 2 +- source4/rpc_server/dcesrv_auth.c | 7 +-- 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5211619c09f..ee53a7fbacc 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -531,6 +531,37 @@ _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call, return NT_STATUS_OK; } +static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn) +{ + const struct dcesrv_endpoint *ep = conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(ep->ep_description); + struct dcesrv_auth *auth = NULL; + + auth = talloc_zero(conn, struct dcesrv_auth); + if (auth == NULL) { + return NULL; + } + + switch (transport) { + case NCACN_NP: + auth->session_key_fn = dcesrv_remote_session_key; + break; + case NCALRPC: + case NCACN_UNIX_STREAM: + auth->session_key_fn = dcesrv_local_fixed_session_key; + break; + default: + /* + * All other's get a NULL pointer, which + * results in NT_STATUS_NO_USER_SESSION_KEY + */ + break; + } + + return auth; +} + /* connect to a dcerpc endpoint */ @@ -544,8 +575,7 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, uint32_t state_flags, struct dcesrv_connection **_p) { - enum dcerpc_transport_t transport = - dcerpc_binding_get_transport(ep->ep_description); + struct dcesrv_auth *auth = NULL; struct dcesrv_connection *p; if (!session_info) { @@ -555,11 +585,6 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p = talloc_zero(mem_ctx, struct dcesrv_connection); NT_STATUS_HAVE_NO_MEMORY(p); - if (!talloc_reference(p, session_info)) { - talloc_free(p); - return NT_STATUS_NO_MEMORY; - } - p->dce_ctx = dce_ctx; p->endpoint = ep; p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx); @@ -572,23 +597,20 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->max_xmit_frag = 5840; p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE; - p->auth_state.session_info = session_info; - switch (transport) { - case NCACN_NP: - p->auth_state.session_key_fn = dcesrv_remote_session_key; - break; - case NCALRPC: - case NCACN_UNIX_STREAM: - p->auth_state.session_key_fn = dcesrv_local_fixed_session_key; - break; - default: - /* - * All other's get a NULL pointer, which - * results in NT_STATUS_NO_USER_SESSION_KEY - */ - break; + auth = dcesrv_auth_create(p); + if (auth == NULL) { + talloc_free(p); + return NT_STATUS_NO_MEMORY; } + auth->session_info = talloc_reference(auth, session_info); + if (auth->session_info == NULL) { + talloc_free(p); + return NT_STATUS_NO_MEMORY; + } + + p->default_auth_state = auth; + /* * For now we only support NDR32. */ @@ -2000,7 +2022,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, talloc_steal(call, blob.data); call->pkt = *pkt; - call->auth_state = &dce_conn->auth_state; + call->auth_state = dce_conn->default_auth_state; talloc_set_destructor(call, dcesrv_call_dequeue); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 41613cb0899..d3c0a080b27 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -289,7 +289,7 @@ struct dcesrv_connection { const struct tsocket_address *remote_address; /* the current authentication state */ - struct dcesrv_auth auth_state; + struct dcesrv_auth *default_auth_state; /* * remember which pdu types are allowed diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index a32bbea9a03..23f3332ae4c 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -122,7 +122,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) auth->auth_context_id = call->in_auth_info.auth_context_id; server_credentials - = cli_credentials_init(call); + = cli_credentials_init(auth); if (!server_credentials) { DEBUG(1, ("Failed to init server credentials\n")); return false; @@ -136,7 +136,8 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) return false; } - status = samba_server_gensec_start(dce_conn, call->event_ctx, + status = samba_server_gensec_start(auth, + call->event_ctx, call->msg_ctx, call->conn->dce_ctx->lp_ctx, server_credentials, @@ -276,7 +277,7 @@ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) } status = gensec_session_info(auth->gensec_security, - dce_conn, + auth, &auth->session_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to establish session_info: %s\n", -- 2.20.1.97.g81188d93c3-goog From fd853c7b9ef0f08ff3ef0df4faeaf33fb8a8463d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 16:36:13 +0100 Subject: [PATCH 056/103] s4:rpc_server: split out dcesrv_auth_prepare_gensec() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcesrv_auth.c | 116 +++++++++++++++++-------------- 1 file changed, 62 insertions(+), 54 deletions(-) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 23f3332ae4c..c58314b13f9 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -32,67 +32,14 @@ #include "param/param.h" #include "librpc/rpc/rpc_common.h" -/* - parse any auth information from a dcerpc bind request - return false if we can't handle the auth request for some - reason (in which case we send a bind_nak) -*/ -bool dcesrv_auth_bind(struct dcesrv_call_state *call) +static bool dcesrv_auth_prepare_gensec(struct dcesrv_call_state *call) { struct cli_credentials *server_credentials = NULL; - struct ncacn_packet *pkt = &call->pkt; struct dcesrv_connection *dce_conn = call->conn; struct dcesrv_auth *auth = call->auth_state; bool want_header_signing = false; NTSTATUS status; - if (pkt->auth_length == 0) { - enum dcerpc_transport_t transport = - dcerpc_binding_get_transport(call->conn->endpoint->ep_description); - const char *auth_type = derpc_transport_string_by_transport(transport); - const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE; - if (transport == NCACN_NP) { - transport_protection = AUTHZ_TRANSPORT_PROTECTION_SMB; - } - auth->auth_type = DCERPC_AUTH_TYPE_NONE; - auth->auth_level = DCERPC_AUTH_LEVEL_NONE; - auth->auth_context_id = 0; - - /* - * Log the authorization to this RPC interface. This - * covered ncacn_np pass-through auth, and anonymous - * DCE/RPC (eg epmapper, netlogon etc) - */ - log_successful_authz_event(call->conn->msg_ctx, - call->conn->dce_ctx->lp_ctx, - call->conn->remote_address, - call->conn->local_address, - "DCE/RPC", - auth_type, - transport_protection, - auth->session_info); - - return true; - } - - status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info, - &call->in_auth_info, - NULL, true); - if (!NT_STATUS_IS_OK(status)) { - /* - * Setting DCERPC_AUTH_LEVEL_NONE, - * gives the caller the reject_reason - * as auth_context_id. - * - * Note: DCERPC_AUTH_LEVEL_NONE == 1 - */ - auth->auth_type = DCERPC_AUTH_TYPE_NONE; - auth->auth_level = DCERPC_AUTH_LEVEL_NONE; - auth->auth_context_id = - DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED; - return false; - } - switch (call->in_auth_info.auth_level) { case DCERPC_AUTH_LEVEL_CONNECT: case DCERPC_AUTH_LEVEL_CALL: @@ -242,6 +189,67 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) return true; } +/* + parse any auth information from a dcerpc bind request + return false if we can't handle the auth request for some + reason (in which case we send a bind_nak) +*/ +bool dcesrv_auth_bind(struct dcesrv_call_state *call) +{ + struct ncacn_packet *pkt = &call->pkt; + struct dcesrv_auth *auth = call->auth_state; + NTSTATUS status; + + if (pkt->auth_length == 0) { + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(call->conn->endpoint->ep_description); + const char *auth_type = derpc_transport_string_by_transport(transport); + const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE; + if (transport == NCACN_NP) { + transport_protection = AUTHZ_TRANSPORT_PROTECTION_SMB; + } + auth->auth_type = DCERPC_AUTH_TYPE_NONE; + auth->auth_level = DCERPC_AUTH_LEVEL_NONE; + auth->auth_context_id = 0; + + /* + * Log the authorization to this RPC interface. This + * covered ncacn_np pass-through auth, and anonymous + * DCE/RPC (eg epmapper, netlogon etc) + */ + log_successful_authz_event(call->conn->msg_ctx, + call->conn->dce_ctx->lp_ctx, + call->conn->remote_address, + call->conn->local_address, + "DCE/RPC", + auth_type, + transport_protection, + auth->session_info); + + return true; + } + + status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info, + &call->in_auth_info, + NULL, true); + if (!NT_STATUS_IS_OK(status)) { + /* + * Setting DCERPC_AUTH_LEVEL_NONE, + * gives the caller the reject_reason + * as auth_context_id. + * + * Note: DCERPC_AUTH_LEVEL_NONE == 1 + */ + auth->auth_type = DCERPC_AUTH_TYPE_NONE; + auth->auth_level = DCERPC_AUTH_LEVEL_NONE; + auth->auth_context_id = + DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED; + return false; + } + + return dcesrv_auth_prepare_gensec(call); +} + NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) { struct dcesrv_connection *dce_conn = call->conn; -- 2.20.1.97.g81188d93c3-goog From 18ded46317d5f39fbe01ceb41a80837dc26ff2e2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 16:36:52 +0100 Subject: [PATCH 057/103] s4:rpc_server: add some protection checks to dcesrv_auth_prepare_gensec() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcesrv_auth.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index c58314b13f9..60bebe39cbd 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -40,6 +40,18 @@ static bool dcesrv_auth_prepare_gensec(struct dcesrv_call_state *call) bool want_header_signing = false; NTSTATUS status; + if (auth->auth_invalid) { + return false; + } + + if (auth->auth_finished) { + return false; + } + + if (auth->gensec_security != NULL) { + return false; + } + switch (call->in_auth_info.auth_level) { case DCERPC_AUTH_LEVEL_CONNECT: case DCERPC_AUTH_LEVEL_CALL: -- 2.20.1.97.g81188d93c3-goog From 269c2e96c62e1f044eb5f2c88866ec4a85cfe394 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Nov 2018 13:26:21 +0100 Subject: [PATCH 058/103] s4:rpc_server: split out log_successful_dcesrv_authz_event() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcesrv_auth.c | 48 +++++++++++++++++++------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 60bebe39cbd..c64aa20bcfc 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -201,6 +201,33 @@ static bool dcesrv_auth_prepare_gensec(struct dcesrv_call_state *call) return true; } +static void log_successful_dcesrv_authz_event(struct dcesrv_call_state *call) +{ + struct dcesrv_auth *auth = call->auth_state; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(call->conn->endpoint->ep_description); + const char *auth_type = derpc_transport_string_by_transport(transport); + const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE; + + if (transport == NCACN_NP) { + transport_protection = AUTHZ_TRANSPORT_PROTECTION_SMB; + } + + /* + * Log the authorization to this RPC interface. This + * covered ncacn_np pass-through auth, and anonymous + * DCE/RPC (eg epmapper, netlogon etc) + */ + log_successful_authz_event(call->conn->msg_ctx, + call->conn->dce_ctx->lp_ctx, + call->conn->remote_address, + call->conn->local_address, + "DCE/RPC", + auth_type, + transport_protection, + auth->session_info); +} + /* parse any auth information from a dcerpc bind request return false if we can't handle the auth request for some @@ -213,30 +240,11 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) NTSTATUS status; if (pkt->auth_length == 0) { - enum dcerpc_transport_t transport = - dcerpc_binding_get_transport(call->conn->endpoint->ep_description); - const char *auth_type = derpc_transport_string_by_transport(transport); - const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE; - if (transport == NCACN_NP) { - transport_protection = AUTHZ_TRANSPORT_PROTECTION_SMB; - } auth->auth_type = DCERPC_AUTH_TYPE_NONE; auth->auth_level = DCERPC_AUTH_LEVEL_NONE; auth->auth_context_id = 0; - /* - * Log the authorization to this RPC interface. This - * covered ncacn_np pass-through auth, and anonymous - * DCE/RPC (eg epmapper, netlogon etc) - */ - log_successful_authz_event(call->conn->msg_ctx, - call->conn->dce_ctx->lp_ctx, - call->conn->remote_address, - call->conn->local_address, - "DCE/RPC", - auth_type, - transport_protection, - auth->session_info); + log_successful_dcesrv_authz_event(call); return true; } -- 2.20.1.97.g81188d93c3-goog From df9ac011b4023b7e7fe806507d32299d899c19b5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Dec 2018 17:03:25 +0100 Subject: [PATCH 059/103] s4:rpc_server: set auth_invalid = true on disconnect BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index ee53a7fbacc..7cb8e11eeea 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -669,6 +669,8 @@ static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, call->conn->allow_auth3 = false; call->conn->allow_request = false; + call->conn->default_auth_state->auth_invalid = true; + call->terminate_reason = talloc_strdup(call, reason); if (call->terminate_reason == NULL) { call->terminate_reason = __location__; @@ -2478,6 +2480,8 @@ static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, cons dce_conn->allow_alter = false; dce_conn->allow_request = false; + dce_conn->default_auth_state->auth_invalid = true; + if (dce_conn->pending_call_list == NULL) { char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason); -- 2.20.1.97.g81188d93c3-goog From 75f38993253e1151ae2be1c0287609d4d8e8f241 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Nov 2018 10:30:47 +0100 Subject: [PATCH 060/103] s4:rpc_server: replace dce_conn->allow_auth3 with auth->auth_started auth3 is allowed if auth_started is true and auth_finished is false. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 4 +--- source4/rpc_server/dcerpc_server.h | 2 +- source4/rpc_server/dcesrv_auth.c | 8 +++++++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 7cb8e11eeea..54ab2d0ec1d 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -666,7 +666,6 @@ static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, call->conn->allow_bind = false; call->conn->allow_alter = false; - call->conn->allow_auth3 = false; call->conn->allow_request = false; call->conn->default_auth_state->auth_invalid = true; @@ -1298,7 +1297,7 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) struct tevent_req *subreq = NULL; NTSTATUS status; - if (!call->conn->allow_auth3) { + if (!auth->auth_started) { return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); } @@ -2476,7 +2475,6 @@ static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, cons dce_conn->wait_private = NULL; dce_conn->allow_bind = false; - dce_conn->allow_auth3 = false; dce_conn->allow_alter = false; dce_conn->allow_request = false; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index d3c0a080b27..c720816441d 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -203,6 +203,7 @@ struct dcesrv_auth { NTSTATUS (*session_key_fn)(struct dcesrv_auth *, DATA_BLOB *session_key); bool client_hdr_signing; bool hdr_signing; + bool auth_started; bool auth_finished; bool auth_invalid; }; @@ -295,7 +296,6 @@ struct dcesrv_connection { * remember which pdu types are allowed */ bool allow_bind; - bool allow_auth3; bool allow_alter; bool allow_request; diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index c64aa20bcfc..392a25cf780 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -40,6 +40,12 @@ static bool dcesrv_auth_prepare_gensec(struct dcesrv_call_state *call) bool want_header_signing = false; NTSTATUS status; + if (auth->auth_started) { + return false; + } + + auth->auth_started = true; + if (auth->auth_invalid) { return false; } @@ -243,6 +249,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) auth->auth_type = DCERPC_AUTH_TYPE_NONE; auth->auth_level = DCERPC_AUTH_LEVEL_NONE; auth->auth_context_id = 0; + auth->auth_started = true; log_successful_dcesrv_authz_event(call); @@ -338,7 +345,6 @@ NTSTATUS dcesrv_auth_prepare_bind_ack(struct dcesrv_call_state *call, struct nca struct dcesrv_auth *auth = call->auth_state; dce_conn->allow_alter = true; - dce_conn->allow_auth3 = true; if (call->pkt.auth_length == 0) { auth->auth_finished = true; -- 2.20.1.97.g81188d93c3-goog From 34bd7e0900a6e6aebe9449a9bb4a15aede7253c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Nov 2018 10:30:47 +0100 Subject: [PATCH 061/103] s4:rpc_server: replace dce_conn->allow_request with auth->auth_finished They both had the same lifetime and the disconnect case is now caught by auth->auth_invalid = true. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 6 ++---- source4/rpc_server/dcerpc_server.h | 1 - source4/rpc_server/dcesrv_auth.c | 6 +----- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 54ab2d0ec1d..e763b581f4d 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -666,7 +666,6 @@ static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, call->conn->allow_bind = false; call->conn->allow_alter = false; - call->conn->allow_request = false; call->conn->default_auth_state->auth_invalid = true; @@ -1851,7 +1850,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) struct ndr_pull *pull; NTSTATUS status; - if (!call->conn->allow_request) { + if (!auth->auth_finished) { return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); } @@ -2038,7 +2037,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, /* we have to check the signing here, before combining the pdus */ if (call->pkt.ptype == DCERPC_PKT_REQUEST) { - if (!call->conn->allow_request) { + if (!call->auth_state->auth_finished) { return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); } @@ -2476,7 +2475,6 @@ static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, cons dce_conn->allow_bind = false; dce_conn->allow_alter = false; - dce_conn->allow_request = false; dce_conn->default_auth_state->auth_invalid = true; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index c720816441d..4b6c0d145bf 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -297,7 +297,6 @@ struct dcesrv_connection { */ bool allow_bind; bool allow_alter; - bool allow_request; /* the association group the connection belongs to */ struct dcesrv_assoc_group *assoc_group; diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 392a25cf780..98827ffd214 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -279,7 +279,6 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) { - struct dcesrv_connection *dce_conn = call->conn; struct dcesrv_auth *auth = call->auth_state; const char *pdu = ""; @@ -320,7 +319,6 @@ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) return status; } auth->auth_finished = true; - dce_conn->allow_request = true; if (call->pkt.ptype != DCERPC_PKT_AUTH3) { return NT_STATUS_OK; @@ -348,7 +346,6 @@ NTSTATUS dcesrv_auth_prepare_bind_ack(struct dcesrv_call_state *call, struct nca if (call->pkt.auth_length == 0) { auth->auth_finished = true; - dce_conn->allow_request = true; return NT_STATUS_OK; } @@ -521,7 +518,6 @@ bool dcesrv_auth_pkt_pull(struct dcesrv_call_state *call, DATA_BLOB *payload_and_verifier) { struct ncacn_packet *pkt = &call->pkt; - struct dcesrv_connection *dce_conn = call->conn; struct dcesrv_auth *auth = call->auth_state; const struct dcerpc_auth tmp_auth = { .auth_type = auth->auth_type, @@ -530,7 +526,7 @@ bool dcesrv_auth_pkt_pull(struct dcesrv_call_state *call, }; NTSTATUS status; - if (!dce_conn->allow_request) { + if (!auth->auth_finished) { call->fault_code = DCERPC_NCA_S_PROTO_ERROR; return false; } -- 2.20.1.97.g81188d93c3-goog From 09f4dbc44e1bed4e79d5a580aca1006735e01aeb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 23:27:50 +0100 Subject: [PATCH 062/103] s4:rpc_server: add a min_auth_level to context handles BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.h | 1 + source4/rpc_server/handles.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 4b6c0d145bf..abfb5c0b894 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -189,6 +189,7 @@ struct dcesrv_handle { struct dcesrv_assoc_group *assoc_group; struct policy_handle wire_handle; struct dom_sid *sid; + enum dcerpc_AuthLevel min_auth_level; const struct dcesrv_interface *iface; void *data; }; diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index b0cef1c27f7..68bacefaaf5 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -65,6 +65,7 @@ struct dcesrv_handle *dcesrv_handle_create(struct dcesrv_call_state *call, talloc_free(h); return NULL; } + h->min_auth_level = call->auth_state->auth_level; h->assoc_group = context->conn->assoc_group; h->iface = context->iface; h->wire_handle.handle_type = handle_type; @@ -120,6 +121,12 @@ struct dcesrv_handle *dcesrv_handle_lookup(struct dcesrv_call_state *call, dom_sid_string(context, sid))); return NULL; } + if (call->auth_state->auth_level < h->min_auth_level) { + DEBUG(0,(__location__ ": Attempt to use invalid auth_level %u < %u\n", + call->auth_state->auth_level, + h->min_auth_level)); + return NULL; + } if (h->iface != context->iface) { DEBUG(0,(__location__ ": Attempt to use invalid iface\n")); return NULL; -- 2.20.1.97.g81188d93c3-goog From 7b33a93471b22ed8fe8102bd939e37bc773adb2a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 23:39:11 +0100 Subject: [PATCH 063/103] s4:rpc_server: move bind_time_features to dcesrv_assoc_group BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 2 +- source4/rpc_server/dcerpc_server.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e763b581f4d..a79a5694772 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1107,7 +1107,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN; } - call->conn->bind_time_features = a->reason.negotiate; + call->conn->assoc_group->bind_time_features = a->reason.negotiate; } /* diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index abfb5c0b894..557883090af 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -310,9 +310,6 @@ struct dcesrv_connection { */ const struct ndr_syntax_id *preferred_transfer; - /* the negotiated bind time features */ - uint16_t bind_time_features; - /* * This is used to block the connection during * pending authentication. @@ -359,6 +356,9 @@ struct dcesrv_assoc_group { /* parent context */ struct dcesrv_context *dce_ctx; + /* the negotiated bind time features */ + uint16_t bind_time_features; + /* Remote association group ID (if proxied) */ uint32_t proxied_id; }; -- 2.20.1.97.g81188d93c3-goog From a83cb5eeccb45769f11994feb03066ac5d390626 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 10 Dec 2018 22:41:31 +0100 Subject: [PATCH 064/103] s4:rpc_server: add dcesrv_iface_state_{store,find}_{assoc,conn}() helpers They can be used instead of dcesrv_connection_context->private_data and dcesrv_assoc_group->proxied_id. This is the first step to hide internal details of the core dcerpc server from the interface implementations. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.h | 38 +++++ source4/rpc_server/handles.c | 223 +++++++++++++++++++++++++++++ 2 files changed, 261 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 557883090af..ad97b0e0cee 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -38,6 +38,7 @@ struct dcesrv_connection; struct dcesrv_call_state; struct dcesrv_auth; struct dcesrv_connection_context; +struct dcesrv_iface_state; struct dcesrv_interface { const char *name; @@ -353,6 +354,11 @@ struct dcesrv_assoc_group { /* list of handles in this association group */ struct dcesrv_handle *handles; + /* + * list of iface states per assoc/conn + */ + struct dcesrv_iface_state *iface_states; + /* parent context */ struct dcesrv_context *dce_ctx; @@ -536,4 +542,36 @@ _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface); +_PUBLIC_ NTSTATUS _dcesrv_iface_state_store_assoc( + struct dcesrv_call_state *call, + uint64_t magic, + void *ptr, + const char *location); +#define dcesrv_iface_state_store_assoc(call, magic, ptr) \ + _dcesrv_iface_state_store_assoc((call), (magic), (ptr), \ + __location__) +_PUBLIC_ void *_dcesrv_iface_state_find_assoc( + struct dcesrv_call_state *call, + uint64_t magic); +#define dcesrv_iface_state_find_assoc(call, magic, _type) \ + talloc_get_type( \ + _dcesrv_iface_state_find_assoc((call), (magic)), \ + _type) + +_PUBLIC_ NTSTATUS _dcesrv_iface_state_store_conn( + struct dcesrv_call_state *call, + uint64_t magic, + void *_pptr, + const char *location); +#define dcesrv_iface_state_store_conn(call, magic, ptr) \ + _dcesrv_iface_state_store_conn((call), (magic), (ptr), \ + __location__) +_PUBLIC_ void *_dcesrv_iface_state_find_conn( + struct dcesrv_call_state *call, + uint64_t magic); +#define dcesrv_iface_state_find_conn(call, magic, _type) \ + talloc_get_type( \ + _dcesrv_iface_state_find_conn((call), (magic)), \ + _type) + #endif /* SAMBA_DCERPC_SERVER_H */ diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index 68bacefaaf5..91bfaf9c62c 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -137,3 +137,226 @@ struct dcesrv_handle *dcesrv_handle_lookup(struct dcesrv_call_state *call, return NULL; } + +struct dcesrv_iface_state { + struct dcesrv_iface_state *prev, *next; + struct dcesrv_assoc_group *assoc; + const struct dcesrv_interface *iface; + struct dom_sid owner; + const struct dcesrv_connection *conn; + const struct dcesrv_auth *auth; + const struct dcesrv_connection_context *pres; + uint64_t magic; + void *ptr; + const char *location; +}; + +static int dcesrv_iface_state_destructor(struct dcesrv_iface_state *istate) +{ + DLIST_REMOVE(istate->assoc->iface_states, istate); + return 0; +} + +static void *dcesrv_iface_state_find(struct dcesrv_assoc_group *assoc, + const struct dcesrv_interface *iface, + const struct dom_sid *owner, + const struct dcesrv_connection *conn, + const struct dcesrv_auth *auth, + const struct dcesrv_connection_context *pres, + uint64_t magic, + const void *ptr) +{ + struct dcesrv_iface_state *cur = NULL; + + for (cur = assoc->iface_states; cur != NULL; cur = cur->next) { + bool match; + + SMB_ASSERT(cur->assoc == assoc); + + if (cur->ptr == ptr) { + return cur->ptr; + } + + if (cur->iface != iface) { + continue; + } + + match = dom_sid_equal(&cur->owner, owner); + if (!match) { + continue; + } + + if (cur->conn != conn) { + continue; + } + + if (cur->auth != auth) { + continue; + } + + if (cur->pres != pres) { + continue; + } + + if (cur->magic != magic) { + continue; + } + + return cur->ptr; + } + + return NULL; +} + +static NTSTATUS dcesrv_iface_state_store(struct dcesrv_assoc_group *assoc, + const struct dcesrv_interface *iface, + const struct dom_sid *owner, + const struct dcesrv_connection *conn, + const struct dcesrv_auth *auth, + const struct dcesrv_connection_context *pres, + uint64_t magic, + TALLOC_CTX *mem_ctx, + void *ptr, + const char *location) +{ + struct dcesrv_iface_state *istate = NULL; + void *optr = NULL; + + optr = dcesrv_iface_state_find(assoc, + iface, + owner, + conn, + auth, + pres, + magic, + ptr); + if (optr != NULL) { + return NT_STATUS_OBJECTID_EXISTS; + } + + istate = talloc_zero(ptr, struct dcesrv_iface_state); + if (istate == NULL) { + return NT_STATUS_NO_MEMORY; + } + + *istate = (struct dcesrv_iface_state) { + .assoc = assoc, + .iface = iface, + .owner = *owner, + .conn = conn, + .auth = auth, + .pres = pres, + .magic = magic, + .location = location, + }; + + istate->ptr = talloc_steal(mem_ctx, ptr); + + talloc_set_destructor(istate, dcesrv_iface_state_destructor); + + DLIST_ADD_END(assoc->iface_states, istate); + + return NT_STATUS_OK; +} + +NTSTATUS _dcesrv_iface_state_store_assoc(struct dcesrv_call_state *call, + uint64_t magic, + void *ptr, + const char *location) +{ + struct auth_session_info *session_info = + dcesrv_call_session_info(call); + const struct dom_sid *owner = + &session_info->security_token->sids[0]; + NTSTATUS status; + + status = dcesrv_iface_state_store(call->conn->assoc_group, + call->context->iface, + owner, + NULL, /* conn */ + NULL, /* auth */ + NULL, /* pres */ + magic, + call->conn->assoc_group, /* mem_ctx */ + ptr, + location); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; +} + +void *_dcesrv_iface_state_find_assoc(struct dcesrv_call_state *call, uint64_t magic) +{ + struct auth_session_info *session_info = + dcesrv_call_session_info(call); + const struct dom_sid *owner = + &session_info->security_token->sids[0]; + void *ptr = NULL; + + ptr = dcesrv_iface_state_find(call->conn->assoc_group, + call->context->iface, + owner, + NULL, /* conn */ + NULL, /* auth */ + NULL, /* pres */ + magic, + NULL); /* ptr */ + if (ptr == NULL) { + return NULL; + } + + return ptr; +} + +NTSTATUS _dcesrv_iface_state_store_conn(struct dcesrv_call_state *call, + uint64_t magic, + void *ptr, + const char *location) +{ + struct auth_session_info *session_info = + dcesrv_call_session_info(call); + const struct dom_sid *owner = + &session_info->security_token->sids[0]; + NTSTATUS status; + + status = dcesrv_iface_state_store(call->conn->assoc_group, + call->context->iface, + owner, + call->conn, + call->auth_state, + call->context, + magic, + call->conn, /* mem_ctx */ + ptr, + location); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; +} + +void *_dcesrv_iface_state_find_conn(struct dcesrv_call_state *call, uint64_t magic) +{ + struct auth_session_info *session_info = + dcesrv_call_session_info(call); + const struct dom_sid *owner = + &session_info->security_token->sids[0]; + void *ptr = NULL; + + ptr = dcesrv_iface_state_find(call->conn->assoc_group, + call->context->iface, + owner, + call->conn, + call->auth_state, + call->context, + magic, + NULL); /* ptr */ + if (ptr == NULL) { + return NULL; + } + + return ptr; +} -- 2.20.1.97.g81188d93c3-goog From ae4e7b09bb9685116b631a5b4d4d04f0d599e19b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 10 Dec 2018 22:42:51 +0100 Subject: [PATCH 065/103] s4:rpc_server/netlogon: make use of dcesrv_iface_state_{create,find}_conn() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index c1237933e68..21374a209fb 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -63,6 +63,7 @@ static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_call_state *dce_cal return dcesrv_interface_bind_reject_connect(dce_call, iface); } +#define NETLOGON_SERVER_PIPE_STATE_MAGIC 0x4f555358 struct netlogon_server_pipe_state { struct netr_Credential client_challenge; struct netr_Credential server_challenge; @@ -71,19 +72,21 @@ struct netlogon_server_pipe_state { static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerReqChallenge *r) { - struct netlogon_server_pipe_state *pipe_state = - talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state); + struct netlogon_server_pipe_state *pipe_state = NULL; NTSTATUS ntstatus; ZERO_STRUCTP(r->out.return_credentials); - if (pipe_state) { - talloc_free(pipe_state); - dce_call->context->private_data = NULL; - } + pipe_state = dcesrv_iface_state_find_conn(dce_call, + NETLOGON_SERVER_PIPE_STATE_MAGIC, + struct netlogon_server_pipe_state); + TALLOC_FREE(pipe_state); - pipe_state = talloc(dce_call->context, struct netlogon_server_pipe_state); - NT_STATUS_HAVE_NO_MEMORY(pipe_state); + pipe_state = talloc_zero(dce_call, + struct netlogon_server_pipe_state); + if (pipe_state == NULL) { + return NT_STATUS_NO_MEMORY; + } pipe_state->client_challenge = *r->in.credentials; @@ -92,13 +95,19 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal *r->out.return_credentials = pipe_state->server_challenge; - dce_call->context->private_data = pipe_state; + ntstatus = dcesrv_iface_state_store_conn(dce_call, + NETLOGON_SERVER_PIPE_STATE_MAGIC, + pipe_state); + if (!NT_STATUS_IS_OK(ntstatus)) { + return ntstatus; + } ntstatus = schannel_save_challenge(dce_call->conn->dce_ctx->lp_ctx, &pipe_state->client_challenge, &pipe_state->server_challenge, r->in.computer_name); if (!NT_STATUS_IS_OK(ntstatus)) { + TALLOC_FREE(pipe_state); return ntstatus; } @@ -117,8 +126,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( const char **trust_account_in_db, struct dom_sid **sid) { - struct netlogon_server_pipe_state *pipe_state = - talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state); + struct netlogon_server_pipe_state *pipe_state = NULL; bool challenge_valid = false; struct netlogon_server_pipe_state challenge; struct netlogon_creds_CredentialState *creds; @@ -142,9 +150,10 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( ZERO_STRUCTP(r->out.return_credentials); *r->out.rid = 0; + pipe_state = dcesrv_iface_state_find_conn(dce_call, + NETLOGON_SERVER_PIPE_STATE_MAGIC, + struct netlogon_server_pipe_state); if (pipe_state != NULL) { - dce_call->context->private_data = NULL; - /* * If we had a challenge remembered on the connection * consider this for usage. This can't be cleanup -- 2.20.1.97.g81188d93c3-goog From 8ae71d517b961f87ca2774754880935bbe35b20a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 10 Dec 2018 22:42:51 +0100 Subject: [PATCH 066/103] s4:rpc_server/dnsserver: make use of dcesrv_iface_state_{create,find}_conn() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dnsserver/dcerpc_dnsserver.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c index 068305e5550..1f7a2e198a7 100644 --- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c +++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c @@ -36,6 +36,7 @@ static NTSTATUS dcesrv_interface_dnsserver_bind(struct dcesrv_call_state *dce_ca return dcesrv_interface_bind_require_integrity(dce_call, iface); } +#define DNSSERVER_STATE_MAGIC 0xc9657ab4 struct dnsserver_state { struct loadparm_context *lp_ctx; struct ldb_context *samdb; @@ -108,13 +109,16 @@ static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_c struct dnsserver_state *dsstate; struct dnsserver_zone *zones, *z, *znext; struct dnsserver_partition *partitions, *p; + NTSTATUS status; - dsstate = talloc_get_type(dce_call->context->private_data, struct dnsserver_state); + dsstate = dcesrv_iface_state_find_conn(dce_call, + DNSSERVER_STATE_MAGIC, + struct dnsserver_state); if (dsstate != NULL) { return dsstate; } - dsstate = talloc_zero(dce_call->context, struct dnsserver_state); + dsstate = talloc_zero(dce_call, struct dnsserver_state); if (dsstate == NULL) { return NULL; } @@ -173,7 +177,12 @@ static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_c } } - dce_call->context->private_data = dsstate; + status = dcesrv_iface_state_store_conn(dce_call, + DNSSERVER_STATE_MAGIC, + dsstate); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } return dsstate; -- 2.20.1.97.g81188d93c3-goog From 0927bcd6c1a343ec9c9623bac4061ed4beba7eab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 18:00:29 +0100 Subject: [PATCH 067/103] s4:rpc_server/remote: introduce remote_get_private() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/remote/dcesrv_remote.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 86d165bd6e2..17177096c29 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -180,6 +180,19 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct return NT_STATUS_OK; } +static NTSTATUS remote_get_private(struct dcesrv_call_state *dce_call, + struct dcesrv_remote_private **_priv) +{ + void *ptr = NULL; + struct dcesrv_remote_private *priv = NULL; + + ptr = dce_call->context->private_data; + priv = talloc_get_type_abort(ptr, struct dcesrv_remote_private); + + *_priv = priv; + return NT_STATUS_OK; +} + static NTSTATUS remote_op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r) { enum ndr_err_code ndr_err; @@ -227,13 +240,18 @@ static void remote_op_dispatch_done(struct tevent_req *subreq); static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { - struct dcesrv_remote_private *priv = talloc_get_type_abort(dce_call->context->private_data, - struct dcesrv_remote_private); + struct dcesrv_remote_private *priv = NULL; uint16_t opnum = dce_call->pkt.u.request.opnum; const struct ndr_interface_table *table = dce_call->context->iface->private_data; const struct ndr_interface_call *call; const char *name; struct tevent_req *subreq; + NTSTATUS status; + + status = remote_get_private(dce_call, &priv); + if (!NT_STATUS_IS_OK(status)) { + return status; + } name = table->calls[opnum].name; call = &table->calls[opnum]; -- 2.20.1.97.g81188d93c3-goog From 40aa788c9e0a073adebad201fc6f2e2c16b09207 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 19:08:59 +0100 Subject: [PATCH 068/103] s4:rpc_server/remote: remote_op_bind already has the table available BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/remote/dcesrv_remote.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 17177096c29..a3611adcb91 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -42,7 +42,8 @@ static NTSTATUS remote_op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX * static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version) { NTSTATUS status; - const struct ndr_interface_table *table; + const struct ndr_interface_table *table = + (const struct ndr_interface_table *)dce_call->context->iface->private_data; struct dcesrv_remote_private *priv; const char *binding = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "binding"); const char *user, *pass, *domain; @@ -72,12 +73,6 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct pass = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "password"); domain = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dceprc_remote", "domain"); - table = ndr_table_by_syntax(&iface->syntax_id); - if (!table) { - dce_call->fault_code = DCERPC_NCA_S_UNKNOWN_IF; - return NT_STATUS_NET_WRITE_FAULT; - } - credentials = dcesrv_call_credentials(dce_call); if (user && pass) { @@ -133,7 +128,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct } } - status = dcerpc_binding_set_abstract_syntax(b, &iface->syntax_id); + status = dcerpc_binding_set_abstract_syntax(b, &table->syntax_id); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("dcerpc_binding_set_abstract_syntax() - %s'\n", nt_errstr(status))); -- 2.20.1.97.g81188d93c3-goog From 145082ac3b0b2b338ab1cdb291191058b0d74db3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 19:13:50 +0100 Subject: [PATCH 069/103] s4:rpc_server/remote: reformat code to get "dcerpc_remote:binding" BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/remote/dcesrv_remote.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index a3611adcb91..6967216554b 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -45,7 +45,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct const struct ndr_interface_table *table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; struct dcesrv_remote_private *priv; - const char *binding = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "binding"); + const char *binding = NULL; const char *user, *pass, *domain; struct cli_credentials *credentials; bool must_free_credentials = false; @@ -64,7 +64,11 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct priv->c_pipe = NULL; dce_call->context->private_data = priv; - if (!binding) { + binding = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, + NULL, + "dcerpc_remote", + "binding"); + if (binding == NULL) { DEBUG(0,("You must specify a DCE/RPC binding string\n")); return NT_STATUS_INVALID_PARAMETER; } -- 2.20.1.97.g81188d93c3-goog From bd11b3ae5b1887b5f2acd0667a31df03760f417b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 19:14:59 +0100 Subject: [PATCH 070/103] s4:rpc_server/remote: reformat code to get "dcerpc_remote:use_machine_account" BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/remote/dcesrv_remote.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 6967216554b..fed5bc6c9dc 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -54,8 +54,6 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct struct composite_context *pipe_conn_req; uint32_t flags = 0; - machine_account = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "use_machine_account", false); - priv = talloc(dce_call->conn, struct dcesrv_remote_private); if (!priv) { return NT_STATUS_NO_MEMORY; @@ -77,6 +75,12 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct pass = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "password"); domain = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dceprc_remote", "domain"); + machine_account = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, + NULL, + "dcerpc_remote", + "use_machine_account", + false); + credentials = dcesrv_call_credentials(dce_call); if (user && pass) { -- 2.20.1.97.g81188d93c3-goog From 6bca22ed1a931f4dbdcf813b11fae1c3cf130a1a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Nov 2018 13:13:53 +0100 Subject: [PATCH 071/103] s4:rpc_server/remote: add dcerpc_remote:allow_anonymous_fallback option BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/remote/dcesrv_remote.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index fed5bc6c9dc..4a441f34b23 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -50,6 +50,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct struct cli_credentials *credentials; bool must_free_credentials = false; bool machine_account; + bool allow_anonymous; struct dcerpc_binding *b; struct composite_context *pipe_conn_req; uint32_t flags = 0; @@ -80,6 +81,11 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct "dcerpc_remote", "use_machine_account", false); + allow_anonymous = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, + NULL, + "dcerpc_remote", + "allow_anonymous_fallback", + false); credentials = dcesrv_call_credentials(dce_call); @@ -113,6 +119,13 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct } } else if (credentials != NULL) { DEBUG(5, ("dcerpc_remote: RPC Proxy: Using delegated credentials\n")); + } else if (allow_anonymous) { + DEBUG(5, ("dcerpc_remote: RPC Proxy: Using anonymous\n")); + credentials = cli_credentials_init_anon(priv); + if (!credentials) { + return NT_STATUS_NO_MEMORY; + } + must_free_credentials = true; } else { DEBUG(1,("dcerpc_remote: RPC Proxy: You must supply binding, user and password or have delegated credentials\n")); return NT_STATUS_INVALID_PARAMETER; -- 2.20.1.97.g81188d93c3-goog From 80b84c97fee8c1aa5985fd8156d709b4794d27d1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Nov 2018 13:15:10 +0100 Subject: [PATCH 072/103] selftest: use "dcerpc_remote:allow_anonymous_fallback = yes" for rpc_proxy This already uses anonymous credentials as the remote connection is done during the bind before the realm authentication has started. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- selftest/target/Samba4.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index fbcdfcdc2eb..20f7a2839a2 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -1213,6 +1213,7 @@ sub provision_rpc_proxy($$$) dcerpc_remote:binding = ncacn_ip_tcp:$dcvars->{SERVER} dcerpc endpoint servers = epmapper, remote dcerpc_remote:interfaces = rpcecho + dcerpc_remote:allow_anonymous_fallback = yes [cifs_to_dc] path = /tmp/_ignore_cifs_to_dc_/_none_ -- 2.20.1.97.g81188d93c3-goog From f6539121d159804d428d929cf05dfad34baf9538 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Nov 2018 14:21:45 +0100 Subject: [PATCH 073/103] s4:rpc_server/remote: fail the connection if the remote server don't support MPX If we already negotiated with our client to support concurent multiplexing (MPX), we need a remote connection that also supports it. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/remote/dcesrv_remote.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 4a441f34b23..9e40a974e0c 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -179,9 +179,13 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct return status; } - flags = dcerpc_binding_get_flags(priv->c_pipe->binding); - if (!(flags & DCERPC_CONCURRENT_MULTIPLEX)) { - dce_call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MULTIPLEXED; + if (dce_call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) { + flags = dcerpc_binding_get_flags(priv->c_pipe->binding); + if (!(flags & DCERPC_CONCURRENT_MULTIPLEX)) { + DEBUG(1,("dcerpc_remote: RPC Proxy: " + "Remote server doesn't support MPX\n")); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } } if (dce_call->conn->assoc_group->proxied_id == 0) { -- 2.20.1.97.g81188d93c3-goog From 66f3b4813f202dae9a994fa5f6fd533a399415a7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 19:19:15 +0100 Subject: [PATCH 074/103] s4:rpc_server/remote: defer the connect to the first client request This means we have a chance to use delegated credentials from the client if available, as the authentication is already completed. Before we only ever used the transport inherited credentials via SMB or anonymous. Note: most times we still fallback to anonymous... BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/remote/dcesrv_remote.c | 59 ++++++++++++----------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 9e40a974e0c..7a1ec3f78f9 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -41,10 +41,17 @@ static NTSTATUS remote_op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX * static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version) { - NTSTATUS status; + dce_call->context->private_data = NULL; + return NT_STATUS_OK; +} + +static NTSTATUS remote_get_private(struct dcesrv_call_state *dce_call, + struct dcesrv_remote_private **_priv) +{ const struct ndr_interface_table *table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; - struct dcesrv_remote_private *priv; + void *ptr = NULL; + struct dcesrv_remote_private *priv = NULL; const char *binding = NULL; const char *user, *pass, *domain; struct cli_credentials *credentials; @@ -54,14 +61,20 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct struct dcerpc_binding *b; struct composite_context *pipe_conn_req; uint32_t flags = 0; + NTSTATUS status; - priv = talloc(dce_call->conn, struct dcesrv_remote_private); - if (!priv) { - return NT_STATUS_NO_MEMORY; + ptr = dce_call->context->private_data; + if (ptr != NULL) { + priv = talloc_get_type_abort(ptr, struct dcesrv_remote_private); + + *_priv = priv; + return NT_STATUS_OK; + } + + priv = talloc_zero(dce_call, struct dcesrv_remote_private); + if (priv == NULL) { + return NT_STATUS_NO_MEMORY; } - - priv->c_pipe = NULL; - dce_call->context->private_data = priv; binding = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, @@ -132,7 +145,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct } /* parse binding string to the structure */ - status = dcerpc_parse_binding(dce_call->context, binding, &b); + status = dcerpc_parse_binding(priv, binding, &b); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to parse dcerpc binding '%s'\n", binding)); return status; @@ -156,7 +169,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct return status; } - if (dce_call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) { + if (dce_call->conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED) { status = dcerpc_binding_set_flags(b, DCERPC_CONCURRENT_MULTIPLEX, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("dcerpc_binding_set_flags(CONC_MPX) - %s'\n", @@ -167,9 +180,9 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct DEBUG(3, ("Using binding %s\n", dcerpc_binding_string(dce_call->context, b))); - pipe_conn_req = dcerpc_pipe_connect_b_send(dce_call->context, b, table, + pipe_conn_req = dcerpc_pipe_connect_b_send(priv, b, table, credentials, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); - status = dcerpc_pipe_connect_b_recv(pipe_conn_req, dce_call->context, &(priv->c_pipe)); + status = dcerpc_pipe_connect_b_recv(pipe_conn_req, priv, &(priv->c_pipe)); if (must_free_credentials) { talloc_free(credentials); @@ -179,7 +192,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct return status; } - if (dce_call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) { + if (dce_call->conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED) { flags = dcerpc_binding_get_flags(priv->c_pipe->binding); if (!(flags & DCERPC_CONCURRENT_MULTIPLEX)) { DEBUG(1,("dcerpc_remote: RPC Proxy: " @@ -197,17 +210,8 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct return status; } - return NT_STATUS_OK; -} - -static NTSTATUS remote_get_private(struct dcesrv_call_state *dce_call, - struct dcesrv_remote_private **_priv) -{ - void *ptr = NULL; - struct dcesrv_remote_private *priv = NULL; - - ptr = dce_call->context->private_data; - priv = talloc_get_type_abort(ptr, struct dcesrv_remote_private); + dce_call->context->private_data = priv; + talloc_reparent(dce_call, dce_call->conn, priv); *_priv = priv; return NT_STATUS_OK; @@ -268,14 +272,15 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT struct tevent_req *subreq; NTSTATUS status; + name = table->calls[opnum].name; + call = &table->calls[opnum]; + status = remote_get_private(dce_call, &priv); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("dcesrv_remote: call[%s] %s\n", name, nt_errstr(status))); return status; } - name = table->calls[opnum].name; - call = &table->calls[opnum]; - if (priv->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_IN) { ndr_print_function_debug(call->ndr_print, name, NDR_IN | NDR_SET_VALUES, r); } -- 2.20.1.97.g81188d93c3-goog From 1b72b4f6b96ec192200a0f93f77e28cb4f20d3ec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Nov 2018 14:28:56 +0100 Subject: [PATCH 075/103] s4:rpc_server/remote: introduce struct dcesrv_remote_call This holds the state for async requests. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/remote/dcesrv_remote.c | 26 +++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 7a1ec3f78f9..3fa847222c4 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -262,8 +262,14 @@ static NTSTATUS remote_op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CT static void remote_op_dispatch_done(struct tevent_req *subreq); +struct dcesrv_remote_call { + struct dcesrv_call_state *dce_call; + struct dcesrv_remote_private *priv; +}; + static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { + struct dcesrv_remote_call *rcall = NULL; struct dcesrv_remote_private *priv = NULL; uint16_t opnum = dce_call->pkt.u.request.opnum; const struct ndr_interface_table *table = dce_call->context->iface->private_data; @@ -281,6 +287,13 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT return status; } + rcall = talloc_zero(dce_call, struct dcesrv_remote_call); + if (rcall == NULL) { + return NT_STATUS_NO_MEMORY; + } + rcall->dce_call = dce_call; + rcall->priv = priv; + if (priv->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_IN) { ndr_print_function_debug(call->ndr_print, name, NDR_IN | NDR_SET_VALUES, r); } @@ -288,7 +301,7 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT priv->c_pipe->conn->flags |= DCERPC_NDR_REF_ALLOC; /* we didn't use the return code of this function as we only check the last_fault_code */ - subreq = dcerpc_binding_handle_call_send(dce_call, dce_call->event_ctx, + subreq = dcerpc_binding_handle_call_send(rcall, dce_call->event_ctx, priv->c_pipe->binding_handle, NULL, table, opnum, mem_ctx, r); @@ -296,7 +309,7 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT DEBUG(0,("dcesrv_remote: call[%s] dcerpc_binding_handle_call_send() failed!\n", name)); return NT_STATUS_NO_MEMORY; } - tevent_req_set_callback(subreq, remote_op_dispatch_done, dce_call); + tevent_req_set_callback(subreq, remote_op_dispatch_done, rcall); dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC; return NT_STATUS_OK; @@ -304,10 +317,11 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT static void remote_op_dispatch_done(struct tevent_req *subreq) { - struct dcesrv_call_state *dce_call = tevent_req_callback_data(subreq, - struct dcesrv_call_state); - struct dcesrv_remote_private *priv = talloc_get_type_abort(dce_call->context->private_data, - struct dcesrv_remote_private); + struct dcesrv_remote_call *rcall = + tevent_req_callback_data(subreq, + struct dcesrv_remote_call); + struct dcesrv_call_state *dce_call = rcall->dce_call; + struct dcesrv_remote_private *priv = rcall->priv; uint16_t opnum = dce_call->pkt.u.request.opnum; const struct ndr_interface_table *table = dce_call->context->iface->private_data; const struct ndr_interface_call *call; -- 2.20.1.97.g81188d93c3-goog From c3bdbb0900e87423ca37162e1d92107ad72ebb83 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 19:28:30 +0100 Subject: [PATCH 076/103] s4:rpc_server/remote: make use dcesrv_iface_state_{store,find}_{assoc,conn}() helpers BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/remote/dcesrv_remote.c | 51 +++++++++++++++++------ 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 3fa847222c4..a4abb4bc2cd 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -30,6 +30,12 @@ NTSTATUS dcerpc_server_remote_init(TALLOC_CTX *ctx); +#define DCESRV_REMOTE_ASSOC_MAGIC 0x782f50c4 +struct dcesrv_remote_assoc { + uint32_t assoc_group_id; +}; + +#define DCESRV_REMOTE_PRIVATE_MAGIC 0x7eceafa6 struct dcesrv_remote_private { struct dcerpc_pipe *c_pipe; }; @@ -41,7 +47,6 @@ static NTSTATUS remote_op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX * static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version) { - dce_call->context->private_data = NULL; return NT_STATUS_OK; } @@ -50,8 +55,8 @@ static NTSTATUS remote_get_private(struct dcesrv_call_state *dce_call, { const struct ndr_interface_table *table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; - void *ptr = NULL; struct dcesrv_remote_private *priv = NULL; + struct dcesrv_remote_assoc *assoc = NULL; const char *binding = NULL; const char *user, *pass, *domain; struct cli_credentials *credentials; @@ -63,10 +68,10 @@ static NTSTATUS remote_get_private(struct dcesrv_call_state *dce_call, uint32_t flags = 0; NTSTATUS status; - ptr = dce_call->context->private_data; - if (ptr != NULL) { - priv = talloc_get_type_abort(ptr, struct dcesrv_remote_private); - + priv = dcesrv_iface_state_find_conn(dce_call, + DCESRV_REMOTE_PRIVATE_MAGIC, + struct dcesrv_remote_private); + if (priv != NULL) { *_priv = priv; return NT_STATUS_OK; } @@ -76,6 +81,16 @@ static NTSTATUS remote_get_private(struct dcesrv_call_state *dce_call, return NT_STATUS_NO_MEMORY; } + assoc = dcesrv_iface_state_find_assoc(dce_call, + DCESRV_REMOTE_ASSOC_MAGIC, + struct dcesrv_remote_assoc); + if (assoc == NULL) { + assoc = talloc_zero(dce_call, struct dcesrv_remote_assoc); + if (assoc == NULL) { + return NT_STATUS_NO_MEMORY; + } + } + binding = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", @@ -152,9 +167,9 @@ static NTSTATUS remote_get_private(struct dcesrv_call_state *dce_call, } /* If we already have a remote association group ID, then use that */ - if (dce_call->conn->assoc_group->proxied_id != 0) { + if (assoc->assoc_group_id != 0) { status = dcerpc_binding_set_assoc_group_id(b, - dce_call->conn->assoc_group->proxied_id); + assoc->assoc_group_id); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("dcerpc_binding_set_assoc_group_id() - %s'\n", nt_errstr(status))); @@ -201,18 +216,28 @@ static NTSTATUS remote_get_private(struct dcesrv_call_state *dce_call, } } - if (dce_call->conn->assoc_group->proxied_id == 0) { - dce_call->conn->assoc_group->proxied_id = + if (assoc->assoc_group_id == 0) { + assoc->assoc_group_id = dcerpc_binding_get_assoc_group_id(priv->c_pipe->binding); + if (assoc->assoc_group_id == 0) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + status = dcesrv_iface_state_store_assoc(dce_call, + DCESRV_REMOTE_ASSOC_MAGIC, + assoc); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } + status = dcesrv_iface_state_store_conn(dce_call, + DCESRV_REMOTE_PRIVATE_MAGIC, + priv); if (!NT_STATUS_IS_OK(status)) { return status; } - dce_call->context->private_data = priv; - talloc_reparent(dce_call, dce_call->conn, priv); - *_priv = priv; return NT_STATUS_OK; } -- 2.20.1.97.g81188d93c3-goog From 4c0f6f4b09dc8493c814e985ebd90ef960d4bb6e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 20:05:01 +0100 Subject: [PATCH 077/103] s4:rpc_server/winreg: don't cache an ldb connection per presentation context We should do this per context handle, as these are available on all connections of the association group. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/winreg/rpc_winreg.c | 39 +++++++++----------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/source4/rpc_server/winreg/rpc_winreg.c b/source4/rpc_server/winreg/rpc_winreg.c index d7ae5ac694a..3adaafead7c 100644 --- a/source4/rpc_server/winreg/rpc_winreg.c +++ b/source4/rpc_server/winreg/rpc_winreg.c @@ -29,42 +29,29 @@ enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY }; -static NTSTATUS dcerpc_winreg_bind(struct dcesrv_call_state *dce_call, - const struct dcesrv_interface *iface) -{ - struct auth_session_info *session_info = - dcesrv_call_session_info(dce_call); - struct registry_context *ctx; - WERROR err; - - err = reg_open_samba(dce_call->context, - &ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - session_info, - NULL); - - if (!W_ERROR_IS_OK(err)) { - DEBUG(0, ("Error opening registry: %s\n", win_errstr(err))); - return werror_to_ntstatus(err); - } - - dce_call->context->private_data = ctx; - - return NT_STATUS_OK; -} - -#define DCESRV_INTERFACE_WINREG_BIND dcerpc_winreg_bind - static WERROR dcesrv_winreg_openhive(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, uint32_t hkey, struct policy_handle **outh) { - struct registry_context *ctx = dce_call->context->private_data; + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); + struct registry_context *ctx = NULL; struct dcesrv_handle *h; WERROR result; h = dcesrv_handle_create(dce_call, HTYPE_REGKEY); W_ERROR_HAVE_NO_MEMORY(h); + result = reg_open_samba(h, &ctx, + dce_call->event_ctx, + dce_call->conn->dce_ctx->lp_ctx, + session_info, + NULL); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("Error opening registry: %s\n", win_errstr(result))); + return result; + } + result = reg_get_predefined_key(ctx, hkey, (struct registry_key **)&h->data); if (!W_ERROR_IS_OK(result)) { -- 2.20.1.97.g81188d93c3-goog From f8351a4d157116525968ade8b3077a2d6c7a7331 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 23:38:25 +0100 Subject: [PATCH 078/103] s4:rpc_server: remove unused dcesrv_assoc_group->proxied_id BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index ad97b0e0cee..25ea3931dae 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -364,9 +364,6 @@ struct dcesrv_assoc_group { /* the negotiated bind time features */ uint16_t bind_time_features; - - /* Remote association group ID (if proxied) */ - uint32_t proxied_id; }; /* server-wide context information for the dcerpc server */ -- 2.20.1.97.g81188d93c3-goog From 13c65c22db7edc43ccbcabed39ec3c667dc38a03 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 10 Dec 2018 23:51:09 +0100 Subject: [PATCH 079/103] s4:rpc_server: remove unused dcesrv_connection_context->private_date dcesrv_iface_state_{create,find}_{assoc,conn}() should be used instead. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 1 - source4/rpc_server/dcerpc_server.h | 3 --- 2 files changed, 4 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a79a5694772..a79556dfc00 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1517,7 +1517,6 @@ static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call, context->context_id = ctx->context_id; context->iface = iface; context->transfer_syntax = *selected_transfer; - context->private_data = NULL; DLIST_ADD(call->conn->contexts, context); call->context = context; talloc_set_destructor(context, dcesrv_connection_context_destructor); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 25ea3931dae..f4ea993520f 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -220,9 +220,6 @@ struct dcesrv_connection_context { /* the ndr function table for the chosen interface */ const struct dcesrv_interface *iface; - /* private data for the interface implementation */ - void *private_data; - /* * the minimum required auth level for this interface */ -- 2.20.1.97.g81188d93c3-goog From 29fea356e9d7dea4b839b783b75c92607aac70b8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 20:06:21 +0100 Subject: [PATCH 080/103] s4:rpc_server: only use context within op_bind() hooks and dcesrv_interface_bind_*() functions BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- .../rpc_server/backupkey/dcesrv_backupkey.c | 3 +- .../backupkey/dcesrv_backupkey_heimdal.c | 3 +- source4/rpc_server/dcerpc_server.c | 38 +++++-------------- source4/rpc_server/dcerpc_server.h | 8 ++-- source4/rpc_server/dcesrv_mgmt.c | 3 +- .../rpc_server/dnsserver/dcerpc_dnsserver.c | 3 +- source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 3 +- source4/rpc_server/echo/rpc_echo.c | 3 +- source4/rpc_server/epmapper/rpc_epmapper.c | 3 +- source4/rpc_server/lsa/dcesrv_lsa.c | 3 +- source4/rpc_server/netlogon/dcerpc_netlogon.c | 3 +- source4/rpc_server/samr/dcesrv_samr.c | 3 +- 12 files changed, 34 insertions(+), 42 deletions(-) diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c index 10caf248db4..307a7f09b74 100644 --- a/source4/rpc_server/backupkey/dcesrv_backupkey.c +++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c @@ -47,7 +47,8 @@ static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { - return dcesrv_interface_bind_require_privacy(dce_call, iface); + struct dcesrv_connection_context *context = dce_call->context; + return dcesrv_interface_bind_require_privacy(context, iface); } static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx, diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c b/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c index 9cd912594c5..05113a9cc74 100644 --- a/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c +++ b/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c @@ -54,7 +54,8 @@ static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { - return dcesrv_interface_bind_require_privacy(dce_call, iface); + struct dcesrv_connection_context *context = dce_call->context; + return dcesrv_interface_bind_require_privacy(context, iface); } static const unsigned rsa_with_var_num[] = { 1, 2, 840, 113549, 1, 1, 1 }; diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a79556dfc00..9717a24d637 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -781,44 +781,31 @@ static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call) context->allow_connect); } -NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, +NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - if (dce_call->context == NULL) { - return NT_STATUS_INTERNAL_ERROR; - } - /* * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4) * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5). */ - dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET; + context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET; return NT_STATUS_OK; } -NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, +NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - if (dce_call->context == NULL) { - return NT_STATUS_INTERNAL_ERROR; - } - - dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY; + context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY; return NT_STATUS_OK; } -_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call, +_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; - const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint; + struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx; + const struct dcesrv_endpoint *endpoint = context->conn->endpoint; enum dcerpc_transport_t transport = dcerpc_binding_get_transport(endpoint->ep_description); - struct dcesrv_connection_context *context = dce_call->context; - - if (context == NULL) { - return NT_STATUS_INTERNAL_ERROR; - } if (transport == NCALRPC) { context->allow_connect = true; @@ -837,18 +824,13 @@ _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state return NT_STATUS_OK; } -_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call, +_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; - const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint; + struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx; + const struct dcesrv_endpoint *endpoint = context->conn->endpoint; enum dcerpc_transport_t transport = dcerpc_binding_get_transport(endpoint->ep_description); - struct dcesrv_connection_context *context = dce_call->context; - - if (context == NULL) { - return NT_STATUS_INTERNAL_ERROR; - } if (transport == NCALRPC) { context->allow_connect = true; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index f4ea993520f..dfe48883353 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -527,13 +527,13 @@ _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call, enum dcerpc_AuthType *auth_type, enum dcerpc_AuthLevel *auth_level); -_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, +_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface); -_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, +_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface); -_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call, +_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface); -_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call, +_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface); _PUBLIC_ NTSTATUS _dcesrv_iface_state_store_assoc( diff --git a/source4/rpc_server/dcesrv_mgmt.c b/source4/rpc_server/dcesrv_mgmt.c index ecb90d8848e..210a86de6ee 100644 --- a/source4/rpc_server/dcesrv_mgmt.c +++ b/source4/rpc_server/dcesrv_mgmt.c @@ -39,7 +39,8 @@ static NTSTATUS dcesrv_interface_mgmt_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { - return dcesrv_interface_bind_allow_connect(dce_call, iface); + struct dcesrv_connection_context *context = dce_call->context; + return dcesrv_interface_bind_allow_connect(context, iface); } /* diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c index 1f7a2e198a7..7c2ca8e4d52 100644 --- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c +++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c @@ -33,7 +33,8 @@ static NTSTATUS dcesrv_interface_dnsserver_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { - return dcesrv_interface_bind_require_integrity(dce_call, iface); + struct dcesrv_connection_context *context = dce_call->context; + return dcesrv_interface_bind_require_integrity(context, iface); } #define DNSSERVER_STATE_MAGIC 0xc9657ab4 diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index 415e8db084e..347823ebca3 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -47,7 +47,8 @@ static NTSTATUS dcesrv_interface_drsuapi_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { - return dcesrv_interface_bind_require_privacy(dce_call, iface); + struct dcesrv_connection_context *context = dce_call->context; + return dcesrv_interface_bind_require_privacy(context, iface); } /* diff --git a/source4/rpc_server/echo/rpc_echo.c b/source4/rpc_server/echo/rpc_echo.c index 49c9e23c678..e00eaecbd45 100644 --- a/source4/rpc_server/echo/rpc_echo.c +++ b/source4/rpc_server/echo/rpc_echo.c @@ -31,7 +31,8 @@ static NTSTATUS dcesrv_interface_rpcecho_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { - return dcesrv_interface_bind_allow_connect(dce_call, iface); + struct dcesrv_connection_context *context = dce_call->context; + return dcesrv_interface_bind_allow_connect(context, iface); } static NTSTATUS dcesrv_echo_AddOne(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct echo_AddOne *r) diff --git a/source4/rpc_server/epmapper/rpc_epmapper.c b/source4/rpc_server/epmapper/rpc_epmapper.c index 6b934d7d1b4..7e9c2614f29 100644 --- a/source4/rpc_server/epmapper/rpc_epmapper.c +++ b/source4/rpc_server/epmapper/rpc_epmapper.c @@ -29,7 +29,8 @@ static NTSTATUS dcesrv_interface_epmapper_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { - return dcesrv_interface_bind_allow_connect(dce_call, iface); + struct dcesrv_connection_context *context = dce_call->context; + return dcesrv_interface_bind_allow_connect(context, iface); } typedef uint32_t error_status_t; diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 8575db6b204..4a1bf60ac64 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -40,7 +40,8 @@ static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { - return dcesrv_interface_bind_reject_connect(dce_call, iface); + struct dcesrv_connection_context *context = dce_call->context; + return dcesrv_interface_bind_reject_connect(context, iface); } static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx, diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 21374a209fb..ca3dba374b9 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -60,7 +60,8 @@ static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { - return dcesrv_interface_bind_reject_connect(dce_call, iface); + struct dcesrv_connection_context *context = dce_call->context; + return dcesrv_interface_bind_reject_connect(context, iface); } #define NETLOGON_SERVER_PIPE_STATE_MAGIC 0x4f555358 diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 921d2965d7c..0ddbaae835d 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -46,7 +46,8 @@ static NTSTATUS dcesrv_interface_samr_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { - return dcesrv_interface_bind_reject_connect(dce_call, iface); + struct dcesrv_connection_context *context = dce_call->context; + return dcesrv_interface_bind_reject_connect(context, iface); } /* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */ -- 2.20.1.97.g81188d93c3-goog From 581df8665c615511c803e1c539f4ee4dae07d50e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 20:06:21 +0100 Subject: [PATCH 081/103] s4:rpc_server: only pass context to op_bind() hooks BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm | 4 ++-- source4/rpc_server/backupkey/dcesrv_backupkey.c | 7 +++---- source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c | 7 +++---- source4/rpc_server/dcerpc_server.c | 2 +- source4/rpc_server/dcerpc_server.h | 2 +- source4/rpc_server/dcesrv_mgmt.c | 7 +++---- source4/rpc_server/dnsserver/dcerpc_dnsserver.c | 7 +++---- source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 7 +++---- source4/rpc_server/echo/rpc_echo.c | 7 +++---- source4/rpc_server/epmapper/rpc_epmapper.c | 7 +++---- source4/rpc_server/lsa/dcesrv_lsa.c | 7 +++---- source4/rpc_server/netlogon/dcerpc_netlogon.c | 7 +++---- source4/rpc_server/remote/dcesrv_remote.c | 3 ++- source4/rpc_server/samr/dcesrv_samr.c | 7 +++---- source4/torture/rpc/spoolss_notify.c | 5 ++--- 15 files changed, 38 insertions(+), 48 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm index ad36f000077..e228a762591 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm @@ -81,10 +81,10 @@ sub Boilerplate_Iface($) my $if_version = $interface->{VERSION}; pidl " -static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version) +static NTSTATUS $name\__op_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { #ifdef DCESRV_INTERFACE_$uname\_BIND - return DCESRV_INTERFACE_$uname\_BIND(dce_call,iface); + return DCESRV_INTERFACE_$uname\_BIND(context,iface); #else return NT_STATUS_OK; #endif diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c index 307a7f09b74..a826ae083f4 100644 --- a/source4/rpc_server/backupkey/dcesrv_backupkey.c +++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c @@ -42,12 +42,11 @@ #include #include -#define DCESRV_INTERFACE_BACKUPKEY_BIND(call, iface) \ - dcesrv_interface_backupkey_bind(call, iface) -static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_call_state *dce_call, +#define DCESRV_INTERFACE_BACKUPKEY_BIND(context, iface) \ + dcesrv_interface_backupkey_bind(context, iface) +static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct dcesrv_connection_context *context = dce_call->context; return dcesrv_interface_bind_require_privacy(context, iface); } diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c b/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c index 05113a9cc74..60d082378d7 100644 --- a/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c +++ b/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c @@ -49,12 +49,11 @@ #include #endif -#define DCESRV_INTERFACE_BACKUPKEY_BIND(call, iface) \ - dcesrv_interface_backupkey_bind(call, iface) -static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_call_state *dce_call, +#define DCESRV_INTERFACE_BACKUPKEY_BIND(context, iface) \ + dcesrv_interface_backupkey_bind(context, iface) +static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct dcesrv_connection_context *context = dce_call->context; return dcesrv_interface_bind_require_privacy(context, iface); } diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 9717a24d637..d9ed390a498 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1510,7 +1510,7 @@ static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call, */ call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED; - status = iface->bind(call, iface, if_version); + status = iface->bind(context, iface); call->context = NULL; if (!NT_STATUS_IS_OK(status)) { /* we don't want to trigger the iface->unbind() hook */ diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index dfe48883353..8e404c0591c 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -45,7 +45,7 @@ struct dcesrv_interface { struct ndr_syntax_id syntax_id; /* this function is called when the client binds to this interface */ - NTSTATUS (*bind)(struct dcesrv_call_state *, const struct dcesrv_interface *, uint32_t if_version); + NTSTATUS (*bind)(struct dcesrv_connection_context *, const struct dcesrv_interface *); /* this function is called when the client disconnects the endpoint */ void (*unbind)(struct dcesrv_connection_context *, const struct dcesrv_interface *); diff --git a/source4/rpc_server/dcesrv_mgmt.c b/source4/rpc_server/dcesrv_mgmt.c index 210a86de6ee..e520a34f0bd 100644 --- a/source4/rpc_server/dcesrv_mgmt.c +++ b/source4/rpc_server/dcesrv_mgmt.c @@ -24,8 +24,8 @@ #include "rpc_server/dcerpc_server_proto.h" #include "librpc/gen_ndr/ndr_mgmt.h" -#define DCESRV_INTERFACE_MGMT_BIND(call, iface) \ - dcesrv_interface_mgmt_bind(call, iface) +#define DCESRV_INTERFACE_MGMT_BIND(context, iface) \ + dcesrv_interface_mgmt_bind(context, iface) /* * This #define allows the mgmt interface to accept invalid * association groups, because association groups are to coordinate @@ -36,10 +36,9 @@ #define DCESRV_INTERFACE_MGMT_FLAGS DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED -static NTSTATUS dcesrv_interface_mgmt_bind(struct dcesrv_call_state *dce_call, +static NTSTATUS dcesrv_interface_mgmt_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct dcesrv_connection_context *context = dce_call->context; return dcesrv_interface_bind_allow_connect(context, iface); } diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c index 7c2ca8e4d52..841557814a0 100644 --- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c +++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c @@ -28,12 +28,11 @@ #include "dns_server/dnsserver_common.h" #include "dnsserver.h" -#define DCESRV_INTERFACE_DNSSERVER_BIND(call, iface) \ - dcesrv_interface_dnsserver_bind(call, iface) -static NTSTATUS dcesrv_interface_dnsserver_bind(struct dcesrv_call_state *dce_call, +#define DCESRV_INTERFACE_DNSSERVER_BIND(context, iface) \ + dcesrv_interface_dnsserver_bind(context, iface) +static NTSTATUS dcesrv_interface_dnsserver_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct dcesrv_connection_context *context = dce_call->context; return dcesrv_interface_bind_require_integrity(context, iface); } diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index 347823ebca3..7e2b6174d2f 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -42,12 +42,11 @@ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); \ } while (0) -#define DCESRV_INTERFACE_DRSUAPI_BIND(call, iface) \ - dcesrv_interface_drsuapi_bind(call, iface) -static NTSTATUS dcesrv_interface_drsuapi_bind(struct dcesrv_call_state *dce_call, +#define DCESRV_INTERFACE_DRSUAPI_BIND(context, iface) \ + dcesrv_interface_drsuapi_bind(context, iface) +static NTSTATUS dcesrv_interface_drsuapi_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct dcesrv_connection_context *context = dce_call->context; return dcesrv_interface_bind_require_privacy(context, iface); } diff --git a/source4/rpc_server/echo/rpc_echo.c b/source4/rpc_server/echo/rpc_echo.c index e00eaecbd45..b0baf82d7d0 100644 --- a/source4/rpc_server/echo/rpc_echo.c +++ b/source4/rpc_server/echo/rpc_echo.c @@ -26,12 +26,11 @@ #include "librpc/gen_ndr/ndr_echo.h" #include "lib/events/events.h" -#define DCESRV_INTERFACE_RPCECHO_BIND(call, iface) \ - dcesrv_interface_rpcecho_bind(call, iface) -static NTSTATUS dcesrv_interface_rpcecho_bind(struct dcesrv_call_state *dce_call, +#define DCESRV_INTERFACE_RPCECHO_BIND(context, iface) \ + dcesrv_interface_rpcecho_bind(context, iface) +static NTSTATUS dcesrv_interface_rpcecho_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct dcesrv_connection_context *context = dce_call->context; return dcesrv_interface_bind_allow_connect(context, iface); } diff --git a/source4/rpc_server/epmapper/rpc_epmapper.c b/source4/rpc_server/epmapper/rpc_epmapper.c index 7e9c2614f29..793070d470e 100644 --- a/source4/rpc_server/epmapper/rpc_epmapper.c +++ b/source4/rpc_server/epmapper/rpc_epmapper.c @@ -24,12 +24,11 @@ #include "librpc/gen_ndr/ndr_epmapper.h" #include "rpc_server/dcerpc_server.h" -#define DCESRV_INTERFACE_EPMAPPER_BIND(call, iface) \ - dcesrv_interface_epmapper_bind(call, iface) -static NTSTATUS dcesrv_interface_epmapper_bind(struct dcesrv_call_state *dce_call, +#define DCESRV_INTERFACE_EPMAPPER_BIND(context, iface) \ + dcesrv_interface_epmapper_bind(context, iface) +static NTSTATUS dcesrv_interface_epmapper_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct dcesrv_connection_context *context = dce_call->context; return dcesrv_interface_bind_allow_connect(context, iface); } diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 4a1bf60ac64..ec3be02bf87 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -35,12 +35,11 @@ #include "lib/messaging/irpc.h" #include "libds/common/roles.h" -#define DCESRV_INTERFACE_LSARPC_BIND(call, iface) \ - dcesrv_interface_lsarpc_bind(call, iface) -static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_call_state *dce_call, +#define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \ + dcesrv_interface_lsarpc_bind(context, iface) +static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct dcesrv_connection_context *context = dce_call->context; return dcesrv_interface_bind_reject_connect(context, iface); } diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index ca3dba374b9..530350d442a 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -45,8 +45,8 @@ #include "rpc_server/common/sid_helper.h" #include "lib/util/util_str_escape.h" -#define DCESRV_INTERFACE_NETLOGON_BIND(call, iface) \ - dcesrv_interface_netlogon_bind(call, iface) +#define DCESRV_INTERFACE_NETLOGON_BIND(context, iface) \ + dcesrv_interface_netlogon_bind(context, iface) /* * This #define allows the netlogon interface to accept invalid @@ -57,10 +57,9 @@ */ #define DCESRV_INTERFACE_NETLOGON_FLAGS DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED -static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_call_state *dce_call, +static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct dcesrv_connection_context *context = dce_call->context; return dcesrv_interface_bind_reject_connect(context, iface); } diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index a4abb4bc2cd..0d3b123bcd2 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -45,7 +45,8 @@ static NTSTATUS remote_op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX * return NT_STATUS_OK; } -static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version) +static NTSTATUS remote_op_bind(struct dcesrv_connection_context *context, + const struct dcesrv_interface *iface) { return NT_STATUS_OK; } diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 0ddbaae835d..51fed4da62b 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -41,12 +41,11 @@ #include "lib/util/tsort.h" #include "libds/common/flag_mapping.h" -#define DCESRV_INTERFACE_SAMR_BIND(call, iface) \ - dcesrv_interface_samr_bind(call, iface) -static NTSTATUS dcesrv_interface_samr_bind(struct dcesrv_call_state *dce_call, +#define DCESRV_INTERFACE_SAMR_BIND(context, iface) \ + dcesrv_interface_samr_bind(context, iface) +static NTSTATUS dcesrv_interface_samr_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { - struct dcesrv_connection_context *context = dce_call->context; return dcesrv_interface_bind_reject_connect(context, iface); } diff --git a/source4/torture/rpc/spoolss_notify.c b/source4/torture/rpc/spoolss_notify.c index 718ae703bc9..2dd12994e8d 100644 --- a/source4/torture/rpc/spoolss_notify.c +++ b/source4/torture/rpc/spoolss_notify.c @@ -33,9 +33,8 @@ #include "ntvfs/ntvfs.h" #include "param/param.h" -static NTSTATUS spoolss__op_bind(struct dcesrv_call_state *dce_call, - const struct dcesrv_interface *iface, - uint32_t if_version) +static NTSTATUS spoolss__op_bind(struct dcesrv_connection_context *context, + const struct dcesrv_interface *iface) { return NT_STATUS_OK; } -- 2.20.1.97.g81188d93c3-goog From 6c544ed2eb9972ef920e01500f73cee23a697691 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Nov 2018 13:24:05 +0100 Subject: [PATCH 082/103] s4:rpc_server: SMB_ASSERT(auth->auth_finished); in order to get auth details Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/rpc_server/dcerpc_server.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d9ed390a498..6a41173d53a 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -500,7 +500,7 @@ _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call, DATA_BLOB *session_key) { struct dcesrv_auth *auth = call->auth_state; - + SMB_ASSERT(auth->auth_finished); return dcesrv_session_info_session_key(auth, session_key); } @@ -517,6 +517,8 @@ _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call, struct dcesrv_auth *auth = call->auth_state; NTSTATUS status; + SMB_ASSERT(auth->auth_finished); + if (auth->session_key_fn == NULL) { return NT_STATUS_NO_USER_SESSION_KEY; } @@ -3212,6 +3214,7 @@ NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx, _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call) { struct dcesrv_auth *auth = dce_call->auth_state; + SMB_ASSERT(auth->auth_finished); return auth->session_info->credentials; } @@ -3222,6 +3225,7 @@ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call) { struct dcesrv_auth *auth = dce_call->auth_state; enum security_user_level level; + SMB_ASSERT(auth->auth_finished); level = security_session_user_level(auth->session_info, NULL); return level >= SECURITY_USER; } @@ -3232,6 +3236,7 @@ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call) _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call) { struct dcesrv_auth *auth = dce_call->auth_state; + SMB_ASSERT(auth->auth_finished); return auth->session_info->info->account_name; } @@ -3241,6 +3246,7 @@ _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call) { struct dcesrv_auth *auth = dce_call->auth_state; + SMB_ASSERT(auth->auth_finished); return auth->session_info; } @@ -3253,6 +3259,8 @@ _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call, { struct dcesrv_auth *auth = dce_call->auth_state; + SMB_ASSERT(auth->auth_finished); + if (auth_type != NULL) { *auth_type = auth->auth_type; } -- 2.20.1.97.g81188d93c3-goog From 39bb0fbf36b100b6911ff95408564c48af836125 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 11:49:40 +0100 Subject: [PATCH 083/103] py:dcerpc/raw_testcase: add pfc_flags_2nd and use_auth3 options to do_generic_bind() This makes it more flexible and allows to write complex tests in an easier fashion. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- python/samba/tests/dcerpc/raw_testcase.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py index fc1c86a1283..555ea8d607d 100644 --- a/python/samba/tests/dcerpc/raw_testcase.py +++ b/python/samba/tests/dcerpc/raw_testcase.py @@ -282,7 +282,10 @@ class RawDCERPCTest(TestCase): samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, assoc_group_id=0, call_id=0, nak_reason=None, alter_fault=None, - start_with_alter=False): + start_with_alter=False, + pfc_flags_2nd=samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + use_auth3=False): ctx_list = [ctx] if auth_context is not None: @@ -392,14 +395,25 @@ class RawDCERPCTest(TestCase): if auth_context['hdr_signing']: auth_context["gensec"].want_feature(gensec.FEATURE_SIGN_PKT_HEADER) else: + self.assertFalse(use_auth3) self.assertFalse(finished) auth_info = self.generate_auth(auth_type=auth_context["auth_type"], auth_level=auth_context["auth_level"], auth_context_id=auth_context["auth_context_id"], auth_blob=to_server) + if use_auth3: + req = self.generate_auth3(call_id=call_id, + pfc_flags=pfc_flags_2nd, + auth_info=auth_info) + self.send_pdu(req) + rep = self.recv_pdu(timeout=0.01) + self.assertIsNone(rep) + self.assertIsConnected() + return ack req = self.generate_alter(call_id=call_id, ctx_list=ctx_list, + pfc_flags=pfc_flags_2nd, assoc_group_id=0xffffffff - assoc_group_id, auth_info=auth_info) self.send_pdu(req) @@ -417,7 +431,8 @@ class RawDCERPCTest(TestCase): self.assertEquals(rep.u.reserved, 0) self.assertEquals(len(rep.u.error_and_verifier), 0) return None - self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id) + self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, + pfc_flags=req.pfc_flags) self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) self.assertEquals(rep.u.assoc_group_id, assoc_group_id) -- 2.20.1.97.g81188d93c3-goog From 15a305475333234834503ddd88268e9848206301 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 11:49:40 +0100 Subject: [PATCH 084/103] py:dcerpc/raw_protocol: add tests for delayed header signing activation BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- python/samba/tests/dcerpc/raw_protocol.py | 186 ++++++++++++++++++ .../knownfail.d/test_krb5_hdr_sign_delayed | 2 + 2 files changed, 188 insertions(+) create mode 100644 selftest/knownfail.d/test_krb5_hdr_sign_delayed diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py index aab6d86253f..384b7d47bca 100755 --- a/python/samba/tests/dcerpc/raw_protocol.py +++ b/python/samba/tests/dcerpc/raw_protocol.py @@ -4988,6 +4988,192 @@ class TestDCERPC_BIND(RawDCERPCTest): conn2._disconnect("End of Test") return + def _test_krb5_hdr_sign_delayed1(self, do_upgrade): + auth_type = dcerpc.DCERPC_AUTH_TYPE_KRB5 + auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY + auth_context_id = 1 + + creds = self.get_user_creds() + + abstract = samba.dcerpc.mgmt.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + tsf1_list = [transfer] + ctx = samba.dcerpc.dcerpc.ctx_list() + ctx.context_id = 1 + ctx.num_transfer_syntaxes = len(tsf1_list) + ctx.abstract_syntax = abstract + ctx.transfer_syntaxes = tsf1_list + + auth_context = self.get_auth_context_creds(creds=creds, + auth_type=auth_type, + auth_level=auth_level, + auth_context_id=auth_context_id, + hdr_signing=False) + + ack = self.do_generic_bind(call_id=1, + ctx=ctx, + auth_context=auth_context) + + inq_if_ids = samba.dcerpc.mgmt.inq_if_ids() + self.do_single_request(call_id=2, ctx=ctx, io=inq_if_ids, + auth_context=auth_context) + + # + # This is just an alter context without authentication + # But it can turn on header signing for the whole connection + # + ack2 = self.do_generic_bind(call_id=3, ctx=ctx, + pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN, + assoc_group_id = ack.u.assoc_group_id, + start_with_alter=True) + + self.assertFalse(auth_context['hdr_signing']) + if do_upgrade: + auth_context['hdr_signing'] = True + auth_context["gensec"].want_feature(gensec.FEATURE_SIGN_PKT_HEADER) + fault_status=None + else: + fault_status=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR + + self.do_single_request(call_id=4, ctx=ctx, io=inq_if_ids, + auth_context=auth_context, + fault_status=fault_status) + + if fault_status is not None: + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + return + + self.do_single_request(call_id=5, ctx=ctx, io=inq_if_ids, + auth_context=auth_context) + return + + def test_krb5_hdr_sign_delayed1_ok1(self): + return self._test_krb5_hdr_sign_delayed1(do_upgrade=True) + + def test_krb5_hdr_sign_delayed1_fail1(self): + return self._test_krb5_hdr_sign_delayed1(do_upgrade=False) + + def _test_krb5_hdr_sign_delayed2(self, do_upgrade): + auth_type = dcerpc.DCERPC_AUTH_TYPE_KRB5 + auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY + auth_context_id = 1 + + creds = self.get_user_creds() + + abstract = samba.dcerpc.mgmt.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + tsf1_list = [transfer] + ctx = samba.dcerpc.dcerpc.ctx_list() + ctx.context_id = 1 + ctx.num_transfer_syntaxes = len(tsf1_list) + ctx.abstract_syntax = abstract + ctx.transfer_syntaxes = tsf1_list + + auth_context = self.get_auth_context_creds(creds=creds, + auth_type=auth_type, + auth_level=auth_level, + auth_context_id=auth_context_id, + hdr_signing=False) + + # + # SUPPORT_HEADER_SIGN on alter context activates header signing + # + ack = self.do_generic_bind(call_id=1, + ctx=ctx, + auth_context=auth_context, + pfc_flags_2nd=dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) + + self.assertFalse(auth_context['hdr_signing']) + if do_upgrade: + auth_context['hdr_signing'] = True + auth_context["gensec"].want_feature(gensec.FEATURE_SIGN_PKT_HEADER) + fault_status=None + else: + fault_status=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR + + inq_if_ids = samba.dcerpc.mgmt.inq_if_ids() + self.do_single_request(call_id=4, ctx=ctx, io=inq_if_ids, + auth_context=auth_context, + fault_status=fault_status) + + if fault_status is not None: + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + return + + self.do_single_request(call_id=5, ctx=ctx, io=inq_if_ids, + auth_context=auth_context) + return + + def test_krb5_hdr_sign_delayed2_ok1(self): + return self._test_krb5_hdr_sign_delayed2(do_upgrade=True) + + def test_krb5_hdr_sign_delayed2_fail1(self): + return self._test_krb5_hdr_sign_delayed2(do_upgrade=False) + + def test_krb5_hdr_sign_delayed3_fail1(self): + auth_type = dcerpc.DCERPC_AUTH_TYPE_KRB5 + auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY + auth_context_id = 1 + + creds = self.get_user_creds() + + abstract = samba.dcerpc.mgmt.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + tsf1_list = [transfer] + ctx = samba.dcerpc.dcerpc.ctx_list() + ctx.context_id = 1 + ctx.num_transfer_syntaxes = len(tsf1_list) + ctx.abstract_syntax = abstract + ctx.transfer_syntaxes = tsf1_list + + auth_context = self.get_auth_context_creds(creds=creds, + auth_type=auth_type, + auth_level=auth_level, + auth_context_id=auth_context_id, + hdr_signing=False) + + # + # SUPPORT_HEADER_SIGN on auth3 doesn't activate header signing + # + ack = self.do_generic_bind(call_id=1, + ctx=ctx, + auth_context=auth_context, + pfc_flags_2nd=dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN, + use_auth3=True) + + inq_if_ids = samba.dcerpc.mgmt.inq_if_ids() + self.do_single_request(call_id=2, ctx=ctx, io=inq_if_ids, + auth_context=auth_context) + + self.assertFalse(auth_context['hdr_signing']) + auth_context['hdr_signing'] = True + auth_context["gensec"].want_feature(gensec.FEATURE_SIGN_PKT_HEADER) + fault_status=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR + + self.do_single_request(call_id=4, ctx=ctx, io=inq_if_ids, + auth_context=auth_context, + fault_status=fault_status) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + return if __name__ == "__main__": global_ndr_print = True diff --git a/selftest/knownfail.d/test_krb5_hdr_sign_delayed b/selftest/knownfail.d/test_krb5_hdr_sign_delayed new file mode 100644 index 00000000000..62231cbb2f6 --- /dev/null +++ b/selftest/knownfail.d/test_krb5_hdr_sign_delayed @@ -0,0 +1,2 @@ +^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_krb5_hdr_sign_delayed1 +^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_krb5_hdr_sign_delayed2 -- 2.20.1.97.g81188d93c3-goog From e1305c9f9517f7daa40351f52c278402c46b8c99 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 11:49:40 +0100 Subject: [PATCH 085/103] py:dcerpc/raw_protocol: consistently call self.recv_pdu(timeout=0.01) after auth3 When we don't expect a FAULT, we should wait a little bit to check there's no response to auth3 request. This reduces the raw_procol test from 45s down to 35s total runtime against Windows. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- python/samba/tests/dcerpc/raw_protocol.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py index 384b7d47bca..f29255737a8 100755 --- a/python/samba/tests/dcerpc/raw_protocol.py +++ b/python/samba/tests/dcerpc/raw_protocol.py @@ -2982,7 +2982,7 @@ class TestDCERPC_BIND(RawDCERPCTest): req = self.generate_auth3(call_id=0, auth_info=auth_info) self.send_pdu(req) - rep = self.recv_pdu() + rep = self.recv_pdu(timeout=0.01) self.assertIsNone(rep) self.assertIsConnected() @@ -4231,6 +4231,8 @@ class TestDCERPC_BIND(RawDCERPCTest): req = self.generate_auth3(call_id=0, auth_info=auth_info) self.send_pdu(req) + rep = self.recv_pdu(timeout=0.01) + self.assertIsNone(rep) self.assertIsConnected() # And now try a request without auth_info -- 2.20.1.97.g81188d93c3-goog From 8387a8d84918d27e0cf8c30726c6600f511d690d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 09:39:36 +0100 Subject: [PATCH 086/103] s4:rpc_server: fix DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN negotiation to match Windows BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- .../knownfail.d/test_krb5_hdr_sign_delayed | 2 - source4/rpc_server/dcerpc_server.c | 9 ++- source4/rpc_server/dcerpc_server.h | 5 +- source4/rpc_server/dcesrv_auth.c | 76 +++++++++++++------ 4 files changed, 61 insertions(+), 31 deletions(-) delete mode 100644 selftest/knownfail.d/test_krb5_hdr_sign_delayed diff --git a/selftest/knownfail.d/test_krb5_hdr_sign_delayed b/selftest/knownfail.d/test_krb5_hdr_sign_delayed deleted file mode 100644 index 62231cbb2f6..00000000000 --- a/selftest/knownfail.d/test_krb5_hdr_sign_delayed +++ /dev/null @@ -1,2 +0,0 @@ -^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_krb5_hdr_sign_delayed1 -^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_krb5_hdr_sign_delayed2 diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 6a41173d53a..b34585db364 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -599,6 +599,12 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->max_xmit_frag = 5840; p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE; + p->support_hdr_signing = lpcfg_parm_bool(dce_ctx->lp_ctx, + NULL, + "dcesrv", + "header signing", + true); + auth = dcesrv_auth_create(p); if (auth == NULL) { talloc_free(p); @@ -1787,8 +1793,7 @@ static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why) static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call) { TALLOC_CTX *frame = talloc_stackframe(); - const struct dcesrv_auth *auth = call->auth_state; - const uint32_t bitmask1 = auth->client_hdr_signing ? + const uint32_t bitmask1 = call->conn->client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0; const struct dcerpc_sec_vt_pcontext pcontext = { .abstract_syntax = call->context->iface->syntax_id, diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 8e404c0591c..44bf6e6989c 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -203,8 +203,6 @@ struct dcesrv_auth { struct gensec_security *gensec_security; struct auth_session_info *session_info; NTSTATUS (*session_key_fn)(struct dcesrv_auth *, DATA_BLOB *session_key); - bool client_hdr_signing; - bool hdr_signing; bool auth_started; bool auth_finished; bool auth_invalid; @@ -290,6 +288,9 @@ struct dcesrv_connection { /* the current authentication state */ struct dcesrv_auth *default_auth_state; + bool client_hdr_signing; + bool support_hdr_signing; + bool negotiated_hdr_signing; /* * remember which pdu types are allowed diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 98827ffd214..192d90ba759 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -32,12 +32,49 @@ #include "param/param.h" #include "librpc/rpc/rpc_common.h" +static NTSTATUS dcesrv_auth_negotiate_hdr_signing(struct dcesrv_call_state *call, + struct ncacn_packet *pkt) +{ + struct dcesrv_connection *dce_conn = call->conn; + struct dcesrv_auth *auth = call->auth_state; + + if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)) { + return NT_STATUS_OK; + } + + if (dce_conn->client_hdr_signing) { + if (dce_conn->negotiated_hdr_signing && pkt != NULL) { + pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; + } + return NT_STATUS_OK; + } + + dce_conn->client_hdr_signing = true; + dce_conn->negotiated_hdr_signing = dce_conn->support_hdr_signing; + + if (!dce_conn->negotiated_hdr_signing) { + return NT_STATUS_OK; + } + + if (pkt != NULL) { + pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; + } + + if (auth->gensec_security == NULL) { + return NT_STATUS_OK; + } + + gensec_want_feature(auth->gensec_security, + GENSEC_FEATURE_SIGN_PKT_HEADER); + + return NT_STATUS_OK; +} + static bool dcesrv_auth_prepare_gensec(struct dcesrv_call_state *call) { struct cli_credentials *server_credentials = NULL; struct dcesrv_connection *dce_conn = call->conn; struct dcesrv_auth *auth = call->auth_state; - bool want_header_signing = false; NTSTATUS status; if (auth->auth_started) { @@ -180,28 +217,9 @@ static bool dcesrv_auth_prepare_gensec(struct dcesrv_call_state *call) return false; } - if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) { - auth->client_hdr_signing = true; - want_header_signing = true; - } - - if (want_header_signing) { - want_header_signing = gensec_have_feature(auth->gensec_security, - GENSEC_FEATURE_SIGN_PKT_HEADER); - } - - if (want_header_signing) { - want_header_signing = lpcfg_parm_bool(dce_conn->dce_ctx->lp_ctx, - NULL, - "dcesrv", - "header signing", - true); - } - - if (want_header_signing) { + if (dce_conn->negotiated_hdr_signing) { gensec_want_feature(auth->gensec_security, GENSEC_FEATURE_SIGN_PKT_HEADER); - auth->hdr_signing = true; } return true; @@ -341,6 +359,12 @@ NTSTATUS dcesrv_auth_prepare_bind_ack(struct dcesrv_call_state *call, struct nca { struct dcesrv_connection *dce_conn = call->conn; struct dcesrv_auth *auth = call->auth_state; + NTSTATUS status; + + status = dcesrv_auth_negotiate_hdr_signing(call, pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } dce_conn->allow_alter = true; @@ -354,10 +378,6 @@ NTSTATUS dcesrv_auth_prepare_bind_ack(struct dcesrv_call_state *call, struct nca return NT_STATUS_INTERNAL_ERROR; } - if (auth->hdr_signing) { - pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; - } - call->_out_auth_info = (struct dcerpc_auth) { .auth_type = auth->auth_type, .auth_level = auth->auth_level, @@ -486,6 +506,12 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) NTSTATUS dcesrv_auth_prepare_alter_ack(struct dcesrv_call_state *call, struct ncacn_packet *pkt) { struct dcesrv_auth *auth = call->auth_state; + NTSTATUS status; + + status = dcesrv_auth_negotiate_hdr_signing(call, pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } /* on a pure interface change there is no auth_info structure setup */ -- 2.20.1.97.g81188d93c3-goog From 6a4b73c1f541a6fdf9889d2c336d8af134a7d17b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 09:38:46 +0100 Subject: [PATCH 087/103] py:dcerpc/raw_protocol: enable tests with the DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- python/samba/tests/dcerpc/raw_protocol.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py index f29255737a8..764400e98a9 100755 --- a/python/samba/tests/dcerpc/raw_protocol.py +++ b/python/samba/tests/dcerpc/raw_protocol.py @@ -186,9 +186,7 @@ class TestDCERPC_BIND(RawDCERPCTest): dcerpc.DCERPC_PFC_FLAG_FIRST | dcerpc.DCERPC_PFC_FLAG_LAST) - # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN - # without authentication - def _test_no_auth_request_bind_pfc_HDR_SIGNING(self): + def test_no_auth_request_bind_pfc_HDR_SIGNING(self): return self._test_no_auth_request_bind_pfc_flags( req_pfc_flags=0 | dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | @@ -285,9 +283,7 @@ class TestDCERPC_BIND(RawDCERPCTest): dcerpc.DCERPC_PFC_FLAG_FIRST | dcerpc.DCERPC_PFC_FLAG_LAST) - # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN - # without authentication - def _test_no_auth_request_alter_pfc_HDR_SIGNING(self): + def test_no_auth_request_alter_pfc_HDR_SIGNING(self): return self._test_no_auth_request_alter_pfc_flags( req_pfc_flags=0 | dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | @@ -342,9 +338,7 @@ class TestDCERPC_BIND(RawDCERPCTest): dcerpc.DCERPC_PFC_FLAG_FIRST | dcerpc.DCERPC_PFC_FLAG_LAST) - # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN - # without authentication - def _test_no_auth_request_alter_pfc_ff(self): + def test_no_auth_request_alter_pfc_ff(self): return self._test_no_auth_request_alter_pfc_flags( req_pfc_flags=0 | 0xff | -- 2.20.1.97.g81188d93c3-goog From 414fd23e7149350e39fad31748b4c4fde5b11abd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Nov 2018 00:23:23 +0100 Subject: [PATCH 088/103] selftest:Samba4: allow dcerpc auth level connect:lsarpc = yes in chgdcpass This is required to explore the details of security context multiplexing using lsa_GetUserName(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- selftest/target/Samba4.pm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 20f7a2839a2..a44ad320074 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -2046,10 +2046,14 @@ sub provision_chgdcpass($$) my ($self, $prefix) = @_; print "PROVISIONING CHGDCPASS...\n"; - my $extra_provision_options = ["--use-ntvfs"]; # This environment disallows the use of this password # (and also removes the default AD complexity checks) my $unacceptable_password = "widk3Dsle32jxdBdskldsk55klASKQ"; + my $extra_smb_conf = " + check password script = sed -e '/$unacceptable_password/{;q1}; /$unacceptable_password/!{q0}' + allow dcerpc auth level connect:lsarpc = yes +"; + my $extra_provision_options = ["--use-ntvfs"]; push (@{$extra_provision_options}, "--dns-backend=BIND9_DLZ"); my $ret = $self->provision($prefix, "domain controller", @@ -2060,7 +2064,7 @@ sub provision_chgdcpass($$) "chgDCpass1", undef, undef, - "check password script = sed -e '/$unacceptable_password/{;q1}; /$unacceptable_password/!{q0}'\n", + $extra_smb_conf, "", $extra_provision_options); unless (defined $ret) { -- 2.20.1.97.g81188d93c3-goog From 27889bafd1402603188f7f222005cc0dc39e9f7b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Dec 2018 12:35:09 +0100 Subject: [PATCH 089/103] py:dcerpc/raw_protocol: add test_assoc_group_ok2 to check assoc groups over ncacn_np BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- python/samba/tests/dcerpc/raw_protocol.py | 31 +++++++++++++++++++++++ selftest/knownfail.d/test_assoc_group_ok2 | 1 + 2 files changed, 32 insertions(+) create mode 100644 selftest/knownfail.d/test_assoc_group_ok2 diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py index 764400e98a9..60e753c2d4e 100755 --- a/python/samba/tests/dcerpc/raw_protocol.py +++ b/python/samba/tests/dcerpc/raw_protocol.py @@ -4984,6 +4984,37 @@ class TestDCERPC_BIND(RawDCERPCTest): conn2._disconnect("End of Test") return + def test_assoc_group_ok2(self): + abstract = samba.dcerpc.mgmt.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + self.reconnect_smb_pipe(primary_address='\\pipe\\lsass', + transport_creds=self.get_user_creds()) + (ctx1, ack1) = self.prepare_presentation(abstract, transfer, + context_id=1, return_ack=True) + + conn2 = self.second_connection() + (ctx2, ack2) = conn2.prepare_presentation(abstract, transfer, + assoc_group_id=ack1.u.assoc_group_id, + context_id=2, return_ack=True) + + inq_if_ids = samba.dcerpc.mgmt.inq_if_ids() + self.do_single_request(call_id=1, ctx=ctx1, io=inq_if_ids) + conn2.do_single_request(call_id=1, ctx=ctx2, io=inq_if_ids) + + conn2.do_single_request(call_id=1, ctx=ctx1, io=inq_if_ids, + fault_pfc_flags=( + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE), + fault_status=dcerpc.DCERPC_NCA_S_UNKNOWN_IF, + fault_context_id=0) + + self.do_single_request(call_id=1, ctx=ctx1, io=inq_if_ids) + conn2.do_single_request(call_id=1, ctx=ctx2, io=inq_if_ids) + conn2._disconnect("End of Test") + return + def _test_krb5_hdr_sign_delayed1(self, do_upgrade): auth_type = dcerpc.DCERPC_AUTH_TYPE_KRB5 auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY diff --git a/selftest/knownfail.d/test_assoc_group_ok2 b/selftest/knownfail.d/test_assoc_group_ok2 new file mode 100644 index 00000000000..7d46cce2334 --- /dev/null +++ b/selftest/knownfail.d/test_assoc_group_ok2 @@ -0,0 +1 @@ +^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_assoc_group_ok2 -- 2.20.1.97.g81188d93c3-goog From c3e917faece9a700568ab221f0712fcaf9a0646a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Dec 2018 13:48:05 +0100 Subject: [PATCH 090/103] s4:rpc_server: don't replace '\\pipe\\' with '\\PIPE\\' This is not what Windows returns (at least for \\pipe\lsass). BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- selftest/knownfail.d/test_assoc_group_ok2 | 1 - source4/rpc_server/dcerpc_server.c | 18 +----------------- 2 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 selftest/knownfail.d/test_assoc_group_ok2 diff --git a/selftest/knownfail.d/test_assoc_group_ok2 b/selftest/knownfail.d/test_assoc_group_ok2 deleted file mode 100644 index 7d46cce2334..00000000000 --- a/selftest/knownfail.d/test_assoc_group_ok2 +++ /dev/null @@ -1 +0,0 @@ -^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_assoc_group_ok2 diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b34585db364..a36d91d9341 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -958,7 +958,6 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t extra_flags = 0; uint16_t max_req = 0; uint16_t max_rep = 0; - const char *ep_prefix = ""; const char *endpoint = NULL; struct dcesrv_auth *auth = call->auth_state; struct dcerpc_ack_ctx *ack_ctx_list = NULL; @@ -1178,22 +1177,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) endpoint = ""; } - if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) { - /* - * TODO: check if this is really needed - * - * Or if we should fix this in our idl files. - */ - ep_prefix = "\\PIPE\\"; - endpoint += 6; - } - - pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s", - ep_prefix, - endpoint); - if (pkt->u.bind_ack.secondary_address == NULL) { - return NT_STATUS_NO_MEMORY; - } + pkt->u.bind_ack.secondary_address = endpoint; pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts; pkt->u.bind_ack.ctx_list = ack_ctx_list; pkt->u.bind_ack.auth_info = data_blob_null; -- 2.20.1.97.g81188d93c3-goog From ef7bcb29ad496f2e68cb56186a2cfcc4c27d5c8e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Dec 2018 13:43:45 +0100 Subject: [PATCH 091/103] py:dcerpc/raw_protocol: add test_assoc_group_fail3() This demonstrates that assoc groups are only shared on the same transport (endpoint). BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- python/samba/tests/dcerpc/raw_protocol.py | 45 +++++++++++++++++++++ selftest/knownfail.d/test_assoc_group_fail3 | 1 + 2 files changed, 46 insertions(+) create mode 100644 selftest/knownfail.d/test_assoc_group_fail3 diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py index 60e753c2d4e..f5895078645 100755 --- a/python/samba/tests/dcerpc/raw_protocol.py +++ b/python/samba/tests/dcerpc/raw_protocol.py @@ -5015,6 +5015,51 @@ class TestDCERPC_BIND(RawDCERPCTest): conn2._disconnect("End of Test") return + def test_assoc_group_fail3(self): + abstract = samba.dcerpc.mgmt.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + (ctx1, ack1) = self.prepare_presentation(abstract, transfer, + context_id=1, return_ack=True) + + # assoc groups are per transport + connF = self.second_connection(primary_address="\\pipe\\lsass", + transport_creds=self.get_user_creds()) + tsfF_list = [transfer] + ctxF = samba.dcerpc.dcerpc.ctx_list() + ctxF.context_id = 0xF + ctxF.num_transfer_syntaxes = len(tsfF_list) + ctxF.abstract_syntax = abstract + ctxF.transfer_syntaxes = tsfF_list + ack = connF.do_generic_bind(ctx=ctxF, assoc_group_id=ack1.u.assoc_group_id, + nak_reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + # wait for a disconnect + rep = connF.recv_pdu() + self.assertIsNone(rep) + connF.assertNotConnected() + + conn2 = self.second_connection() + (ctx2, ack2) = conn2.prepare_presentation(abstract, transfer, + assoc_group_id=ack1.u.assoc_group_id, + context_id=2, return_ack=True) + + inq_if_ids = samba.dcerpc.mgmt.inq_if_ids() + self.do_single_request(call_id=1, ctx=ctx1, io=inq_if_ids) + conn2.do_single_request(call_id=1, ctx=ctx2, io=inq_if_ids) + + conn2.do_single_request(call_id=1, ctx=ctx1, io=inq_if_ids, + fault_pfc_flags=( + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE), + fault_status=dcerpc.DCERPC_NCA_S_UNKNOWN_IF, + fault_context_id=0) + + self.do_single_request(call_id=1, ctx=ctx1, io=inq_if_ids) + conn2.do_single_request(call_id=1, ctx=ctx2, io=inq_if_ids) + conn2._disconnect("End of Test") + return + def _test_krb5_hdr_sign_delayed1(self, do_upgrade): auth_type = dcerpc.DCERPC_AUTH_TYPE_KRB5 auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY diff --git a/selftest/knownfail.d/test_assoc_group_fail3 b/selftest/knownfail.d/test_assoc_group_fail3 new file mode 100644 index 00000000000..037f2b7c7a5 --- /dev/null +++ b/selftest/knownfail.d/test_assoc_group_fail3 @@ -0,0 +1 @@ +^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_assoc_group_fail3 -- 2.20.1.97.g81188d93c3-goog From eb170f71f34eaacbc5983e0ca33d5cd19ab9c102 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Dec 2018 13:49:35 +0100 Subject: [PATCH 092/103] s4:rpc_server: only share assoc group ids on the same transport BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- selftest/knownfail.d/test_assoc_group_fail3 | 1 - source4/rpc_server/dcerpc_server.c | 43 ++++++++++++++------- source4/rpc_server/dcerpc_server.h | 5 ++- 3 files changed, 34 insertions(+), 15 deletions(-) delete mode 100644 selftest/knownfail.d/test_assoc_group_fail3 diff --git a/selftest/knownfail.d/test_assoc_group_fail3 b/selftest/knownfail.d/test_assoc_group_fail3 deleted file mode 100644 index 037f2b7c7a5..00000000000 --- a/selftest/knownfail.d/test_assoc_group_fail3 +++ /dev/null @@ -1 +0,0 @@ -^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_assoc_group_fail3 diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a36d91d9341..96886eaa76e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -65,18 +65,34 @@ static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context /* take a reference to an existing association group */ -static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx, - struct dcesrv_context *dce_ctx, +static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(struct dcesrv_connection *conn, uint32_t id) { + const struct dcesrv_endpoint *endpoint = conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(endpoint->ep_description); struct dcesrv_assoc_group *assoc_group; - assoc_group = dcesrv_assoc_group_find(dce_ctx, id); + assoc_group = dcesrv_assoc_group_find(conn->dce_ctx, id); if (assoc_group == NULL) { - DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id)); + DBG_NOTICE("Failed to find assoc_group 0x%08x\n", id); + return NULL; + } + if (assoc_group->transport != transport) { + const char *at = + derpc_transport_string_by_transport( + assoc_group->transport); + const char *ct = + derpc_transport_string_by_transport( + transport); + + DBG_NOTICE("assoc_group 0x%08x (transport %s) " + "is not available on transport %s", + id, at, ct); return NULL; } - return talloc_reference(mem_ctx, assoc_group); + + return talloc_reference(conn, assoc_group); } static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group) @@ -93,13 +109,16 @@ static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group) /* allocate a new association group */ -static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx, - struct dcesrv_context *dce_ctx) +static struct dcesrv_assoc_group *dcesrv_assoc_group_new(struct dcesrv_connection *conn) { + struct dcesrv_context *dce_ctx = conn->dce_ctx; + const struct dcesrv_endpoint *endpoint = conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(endpoint->ep_description); struct dcesrv_assoc_group *assoc_group; int id; - assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group); + assoc_group = talloc_zero(conn, struct dcesrv_assoc_group); if (assoc_group == NULL) { return NULL; } @@ -111,6 +130,7 @@ static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx, return NULL; } + assoc_group->transport = transport; assoc_group->id = id; assoc_group->dce_ctx = dce_ctx; @@ -1003,11 +1023,9 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) */ if (call->pkt.u.bind.assoc_group_id != 0) { call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn, - call->conn->dce_ctx, call->pkt.u.bind.assoc_group_id); } else { - call->conn->assoc_group = dcesrv_assoc_group_new(call->conn, - call->conn->dce_ctx); + call->conn->assoc_group = dcesrv_assoc_group_new(call->conn); } /* @@ -1033,8 +1051,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) if (call->conn->assoc_group == NULL && !call->conn->endpoint->use_single_process) { call->conn->assoc_group - = dcesrv_assoc_group_new(call->conn, - call->conn->dce_ctx); + = dcesrv_assoc_group_new(call->conn); } if (call->conn->assoc_group == NULL) { return dcesrv_bind_nak(call, 0); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 44bf6e6989c..312721824ae 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -348,7 +348,10 @@ struct dcesrv_endpoint_server { struct dcesrv_assoc_group { /* the wire id */ uint32_t id; - + + /* The transport this is valid on */ + enum dcerpc_transport_t transport; + /* list of handles in this association group */ struct dcesrv_handle *handles; -- 2.20.1.97.g81188d93c3-goog From 2020bd993f7f9b9d95156ffd186e9b902c0782f7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Dec 2018 10:13:03 +0100 Subject: [PATCH 093/103] py:dcerpc/raw_protocol: demonstrate that \\pipe\lsarpc returns \\pipe\lsass as secondary_address BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- python/samba/tests/dcerpc/raw_protocol.py | 6 ++++-- selftest/knownfail.d/test_assoc_group_ok2 | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 selftest/knownfail.d/test_assoc_group_ok2 diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py index f5895078645..a306b17f437 100755 --- a/python/samba/tests/dcerpc/raw_protocol.py +++ b/python/samba/tests/dcerpc/raw_protocol.py @@ -4988,7 +4988,8 @@ class TestDCERPC_BIND(RawDCERPCTest): abstract = samba.dcerpc.mgmt.abstract_syntax() transfer = base.transfer_syntax_ndr() - self.reconnect_smb_pipe(primary_address='\\pipe\\lsass', + self.reconnect_smb_pipe(primary_address='\\pipe\\lsarpc', + secondary_address='\\pipe\\lsass', transport_creds=self.get_user_creds()) (ctx1, ack1) = self.prepare_presentation(abstract, transfer, context_id=1, return_ack=True) @@ -5023,7 +5024,8 @@ class TestDCERPC_BIND(RawDCERPCTest): context_id=1, return_ack=True) # assoc groups are per transport - connF = self.second_connection(primary_address="\\pipe\\lsass", + connF = self.second_connection(primary_address="\\pipe\\lsarpc", + secondary_address="\\pipe\\lsass", transport_creds=self.get_user_creds()) tsfF_list = [transfer] ctxF = samba.dcerpc.dcerpc.ctx_list() diff --git a/selftest/knownfail.d/test_assoc_group_ok2 b/selftest/knownfail.d/test_assoc_group_ok2 new file mode 100644 index 00000000000..7d46cce2334 --- /dev/null +++ b/selftest/knownfail.d/test_assoc_group_ok2 @@ -0,0 +1 @@ +^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_assoc_group_ok2 -- 2.20.1.97.g81188d93c3-goog From 538262c1a16edb67892a0602d4e950f1717a29fe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Dec 2018 22:41:56 +0100 Subject: [PATCH 094/103] s4:rpc_server: make it possible to specify ncacn_np_secondary_endpoint Even a connect to \\pipe\lsarpc should return a secondary_address of '\\pipe\\lsass'. But that will be implemented in a following commit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm | 12 +++++++++- source4/rpc_server/dcerpc_server.c | 27 ++++++++++++++++++++++- source4/rpc_server/dcerpc_server.h | 3 +++ source4/rpc_server/lsa/dcesrv_lsa.c | 1 + source4/rpc_server/remote/dcesrv_remote.c | 2 +- source4/torture/rpc/spoolss_notify.c | 6 ++++- 6 files changed, 47 insertions(+), 4 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm index e228a762591..945c0ffcee0 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm @@ -223,12 +223,22 @@ sub Boilerplate_Ep_Server($) static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server) { int i; +#ifdef DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT + const char *ncacn_np_secondary_endpoint = + DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT; +#else + const char *ncacn_np_secondary_endpoint = NULL; +#endif for (i=0;icount;i++) { NTSTATUS ret; const char *name = ndr_table_$name.endpoints->names[i]; - ret = dcesrv_interface_register(dce_ctx, name, &dcesrv_$name\_interface, NULL); + ret = dcesrv_interface_register(dce_ctx, + name, + ncacn_np_secondary_endpoint, + &dcesrv_$name\_interface, + NULL); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,(\"$name\_op_init_server: failed to register endpoint \'%s\'\\n\",name)); return ret; diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 96886eaa76e..75e1dfea1c7 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -284,12 +284,14 @@ static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_conne */ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, const char *ep_name, + const char *ncacn_np_secondary_endpoint, const struct dcesrv_interface *iface, const struct security_descriptor *sd) { struct dcesrv_endpoint *ep; struct dcesrv_if_list *ifl; struct dcerpc_binding *binding; + struct dcerpc_binding *binding2 = NULL; bool add_ep = false; NTSTATUS status; enum dcerpc_transport_t transport; @@ -354,6 +356,22 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, } } + if (transport == NCACN_NP && ncacn_np_secondary_endpoint != NULL) { + enum dcerpc_transport_t transport2; + + status = dcerpc_parse_binding(dce_ctx, + ncacn_np_secondary_endpoint, + &binding2); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Trouble parsing 2nd binding string '%s'\n", + ncacn_np_secondary_endpoint)); + return status; + } + + transport2 = dcerpc_binding_get_transport(binding2); + SMB_ASSERT(transport2 == transport); + } + /* see if the interface is already registered on the endpoint */ if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) { DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n", @@ -395,6 +413,7 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, } ZERO_STRUCTP(ep); ep->ep_description = talloc_move(ep, &binding); + ep->ep_2nd_description = talloc_move(ep, &binding2); add_ep = true; /* add mgmt interface */ @@ -978,6 +997,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t extra_flags = 0; uint16_t max_req = 0; uint16_t max_rep = 0; + struct dcerpc_binding *ep_2nd_description = NULL; const char *endpoint = NULL; struct dcesrv_auth *auth = call->auth_state; struct dcerpc_ack_ctx *ack_ctx_list = NULL; @@ -1187,8 +1207,13 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag; pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id; + ep_2nd_description = call->conn->endpoint->ep_2nd_description; + if (ep_2nd_description == NULL) { + ep_2nd_description = call->conn->endpoint->ep_description; + } + endpoint = dcerpc_binding_get_string_option( - call->conn->endpoint->ep_description, + ep_2nd_description, "endpoint"); if (endpoint == NULL) { endpoint = ""; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 312721824ae..25a3aedc2e1 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -383,6 +383,8 @@ struct dcesrv_context { struct dcesrv_endpoint *next, *prev; /* the type and location of the endpoint */ struct dcerpc_binding *ep_description; + /* the secondary endpoint description for the BIND_ACK */ + struct dcerpc_binding *ep_2nd_description; /* the security descriptor for smb named pipes */ struct security_descriptor *sd; /* the list of interfaces available on this endpoint */ @@ -424,6 +426,7 @@ struct model_ops; NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, const char *ep_name, + const char *ncacn_np_secondary_endpoint, const struct dcesrv_interface *iface, const struct security_descriptor *sd); NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server); diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index ec3be02bf87..c1bc78aa9d0 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -55,6 +55,7 @@ static NTSTATUS dcesrv_interface_lsarpc_init_server(struct dcesrv_context *dce_c if (lpcfg_lsa_over_netlogon(dce_ctx->lp_ctx)) { NTSTATUS ret = dcesrv_interface_register(dce_ctx, "ncacn_np:[\\pipe\\netlogon]", + NULL, &dcesrv_lsarpc_interface, NULL); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("lsarpc_op_init_server: failed to register endpoint '\\pipe\\netlogon'\n")); diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 0d3b123bcd2..d34643a68db 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -406,7 +406,7 @@ static NTSTATUS remote_register_one_iface(struct dcesrv_context *dce_ctx, const NTSTATUS ret; const char *name = table->endpoints->names[i]; - ret = dcesrv_interface_register(dce_ctx, name, iface, NULL); + ret = dcesrv_interface_register(dce_ctx, name, NULL, iface, NULL); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("remote_op_init_server: failed to register endpoint '%s'\n",name)); return ret; diff --git a/source4/torture/rpc/spoolss_notify.c b/source4/torture/rpc/spoolss_notify.c index 2dd12994e8d..fb01f71d53f 100644 --- a/source4/torture/rpc/spoolss_notify.c +++ b/source4/torture/rpc/spoolss_notify.c @@ -247,7 +247,11 @@ static NTSTATUS spoolss__op_init_server(struct dcesrv_context *dce_ctx, const st NTSTATUS ret; const char *name = ndr_table_spoolss.endpoints->names[i]; - ret = dcesrv_interface_register(dce_ctx, name, ¬ify_test_spoolss_interface, NULL); + ret = dcesrv_interface_register(dce_ctx, + name, + NULL, + ¬ify_test_spoolss_interface, + NULL); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("spoolss_op_init_server: failed to register endpoint '%s'\n",name)); return ret; -- 2.20.1.97.g81188d93c3-goog From 5509311a8afad0d04a67396d5cd6f59553742e2d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Dec 2018 22:41:56 +0100 Subject: [PATCH 095/103] s4:rpc_server/lsa: specify \\pipe\lsass as ncacn_np_secondary_endpoint BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- selftest/knownfail.d/test_assoc_group_ok2 | 1 - source4/rpc_server/lsa/dcesrv_lsa.c | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) delete mode 100644 selftest/knownfail.d/test_assoc_group_ok2 diff --git a/selftest/knownfail.d/test_assoc_group_ok2 b/selftest/knownfail.d/test_assoc_group_ok2 deleted file mode 100644 index 7d46cce2334..00000000000 --- a/selftest/knownfail.d/test_assoc_group_ok2 +++ /dev/null @@ -1 +0,0 @@ -^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_assoc_group_ok2 diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index c1bc78aa9d0..cbbd9f482f2 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -47,6 +47,10 @@ static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server); static const struct dcesrv_interface dcesrv_lsarpc_interface; +#define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]" +#define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]" +#define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT NCACN_NP_PIPE_LSASS + #define DCESRV_INTERFACE_LSARPC_INIT_SERVER \ dcesrv_interface_lsarpc_init_server static NTSTATUS dcesrv_interface_lsarpc_init_server(struct dcesrv_context *dce_ctx, @@ -54,8 +58,8 @@ static NTSTATUS dcesrv_interface_lsarpc_init_server(struct dcesrv_context *dce_c { if (lpcfg_lsa_over_netlogon(dce_ctx->lp_ctx)) { NTSTATUS ret = dcesrv_interface_register(dce_ctx, - "ncacn_np:[\\pipe\\netlogon]", - NULL, + NCACN_NP_PIPE_NETLOGON, + NCACN_NP_PIPE_LSASS, &dcesrv_lsarpc_interface, NULL); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("lsarpc_op_init_server: failed to register endpoint '\\pipe\\netlogon'\n")); -- 2.20.1.97.g81188d93c3-goog From 1ffff23a3c9287b3724fd8b5f0885963aabc0c51 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2018 16:47:15 +0100 Subject: [PATCH 096/103] s4:pyrpc: make use of pytalloc_get_type() in py_dcerpc_syntax_init_helper() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/librpc/rpc/pyrpc_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c index 21d94308cb9..cc67dfcdc3f 100644 --- a/source4/librpc/rpc/pyrpc_util.c +++ b/source4/librpc/rpc/pyrpc_util.c @@ -334,7 +334,7 @@ PyObject *py_dcerpc_syntax_init_helper(PyTypeObject *type, PyObject *args, PyObj return NULL; } - obj = (struct ndr_syntax_id *)pytalloc_get_ptr(ret); + obj = pytalloc_get_type(ret, struct ndr_syntax_id); *obj = *syntax; return ret; -- 2.20.1.97.g81188d93c3-goog From b763ef88e40dfc84f3fb3f097a97ae5f81ecbac6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2018 12:41:34 +0100 Subject: [PATCH 097/103] s4:pyrpc: add py_dcerpc_ndr_pointer_deref/wrap() infrastructure Some idl files use more than one layer of unique pointers. e.g. NTSTATUS lsa_GetUserName( [in,unique] [string,charset(UTF16)] uint16 *system_name, [in,out,ref] lsa_String **account_name, [in,out,unique] lsa_String **authority_name ); In order to specify *io.in.authority_name = NULL, we need to wrap the pointer value (lsa_String or None) into an base.ndr_pointer() object. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/librpc/rpc/pyrpc.c | 101 ++++++++++++++++++++++++++++++++ source4/librpc/rpc/pyrpc_util.c | 29 +++++++++ source4/librpc/rpc/pyrpc_util.h | 3 + 3 files changed, 133 insertions(+) diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c index e86ea0e94aa..cf2d4c24007 100644 --- a/source4/librpc/rpc/pyrpc.c +++ b/source4/librpc/rpc/pyrpc.c @@ -33,6 +33,8 @@ void initbase(void); static PyTypeObject dcerpc_InterfaceType; +static PyTypeObject *BaseObject_Type; + static PyTypeObject *ndr_syntax_id_Type; static bool PyString_AsGUID(PyObject *object, struct GUID *uuid) @@ -430,6 +432,88 @@ static PyTypeObject py_bind_time_features_syntax_SyntaxType = { .tp_new = py_bind_time_features_syntax_new, }; +struct py_dcerpc_ndr_pointer { + PyObject *value; +}; + +static void py_dcerpc_ndr_pointer_dealloc(PyObject* self) +{ + struct py_dcerpc_ndr_pointer *obj = + pytalloc_get_type(self, struct py_dcerpc_ndr_pointer); + + Py_DECREF(obj->value); + obj->value = NULL; + + self->ob_type->tp_free(self); +} + +static PyObject *py_dcerpc_ndr_pointer_get_value(PyObject *self, void *closure) +{ + struct py_dcerpc_ndr_pointer *obj = + pytalloc_get_type(self, struct py_dcerpc_ndr_pointer); + + Py_INCREF(obj->value); + return obj->value; +} + +static int py_dcerpc_ndr_pointer_set_value(PyObject *self, PyObject *value, void *closure) +{ + struct py_dcerpc_ndr_pointer *obj = + pytalloc_get_type(self, struct py_dcerpc_ndr_pointer); + + Py_DECREF(obj->value); + obj->value = value; + Py_INCREF(obj->value); + return 0; +} + +static PyGetSetDef py_dcerpc_ndr_pointer_getsetters[] = { + { discard_const_p(char, "value"), + py_dcerpc_ndr_pointer_get_value, + py_dcerpc_ndr_pointer_set_value, + discard_const_p(char, "the value store by the pointer") }, + { NULL } +}; + +static PyObject *py_dcerpc_ndr_pointer_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *ret = NULL; + struct py_dcerpc_ndr_pointer *obj = NULL; + const char *kwnames[] = { "value", NULL }; + PyObject *value = NULL; + bool ok; + + ok = PyArg_ParseTupleAndKeywords(args, kwargs, "O:value", + discard_const_p(char *, kwnames), + &value); + if (!ok) { + return NULL; + } + + ret = pytalloc_new(struct py_dcerpc_ndr_pointer, type); + if (ret == NULL) { + return NULL; + } + + obj = pytalloc_get_type(ret, struct py_dcerpc_ndr_pointer); + *obj = (struct py_dcerpc_ndr_pointer) { + .value = value, + }; + + Py_INCREF(obj->value); + return ret; +} + +static PyTypeObject py_dcerpc_ndr_pointer_type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "base.ndr_pointer", + .tp_dealloc = py_dcerpc_ndr_pointer_dealloc, + .tp_getset = py_dcerpc_ndr_pointer_getsetters, + .tp_doc = "ndr_pointer(value)\n", + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_new = py_dcerpc_ndr_pointer_new, +}; + static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, .m_name = "base", @@ -440,8 +524,17 @@ static struct PyModuleDef moduledef = { MODULE_INIT_FUNC(base) { PyObject *m; + PyObject *dep_talloc; PyObject *dep_samba_dcerpc_misc; + dep_talloc = PyImport_ImportModule("talloc"); + if (dep_talloc == NULL) + return NULL; + + BaseObject_Type = (PyTypeObject *)PyObject_GetAttrString(dep_talloc, "BaseObject"); + if (BaseObject_Type == NULL) + return NULL; + dep_samba_dcerpc_misc = PyImport_ImportModule("samba.dcerpc.misc"); if (dep_samba_dcerpc_misc == NULL) return NULL; @@ -457,6 +550,9 @@ MODULE_INIT_FUNC(base) py_bind_time_features_syntax_SyntaxType.tp_base = ndr_syntax_id_Type; py_bind_time_features_syntax_SyntaxType.tp_basicsize = pytalloc_BaseObject_size(); + py_dcerpc_ndr_pointer_type.tp_base = BaseObject_Type; + py_dcerpc_ndr_pointer_type.tp_basicsize = pytalloc_BaseObject_size(); + if (PyType_Ready(&dcerpc_InterfaceType) < 0) return NULL; @@ -467,6 +563,9 @@ MODULE_INIT_FUNC(base) if (PyType_Ready(&py_bind_time_features_syntax_SyntaxType) < 0) return NULL; + if (PyType_Ready(&py_dcerpc_ndr_pointer_type) < 0) + return NULL; + m = PyModule_Create(&moduledef); if (m == NULL) return NULL; @@ -480,5 +579,7 @@ MODULE_INIT_FUNC(base) PyModule_AddObject(m, "transfer_syntax_ndr64", (PyObject *)(void *)&py_transfer_syntax_ndr64_SyntaxType); Py_INCREF((PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType); PyModule_AddObject(m, "bind_time_features_syntax", (PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType); + Py_INCREF((PyObject *)(void *)&py_dcerpc_ndr_pointer_type); + PyModule_AddObject(m, "ndr_pointer", (PyObject *)(void *)&py_dcerpc_ndr_pointer_type); return m; } diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c index cc67dfcdc3f..3a151e1591f 100644 --- a/source4/librpc/rpc/pyrpc_util.c +++ b/source4/librpc/rpc/pyrpc_util.c @@ -448,3 +448,32 @@ void *pyrpc_export_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level, Py_XDECREF(ret_obj); return ret; } + +PyObject *py_dcerpc_ndr_pointer_deref(PyTypeObject *type, PyObject *obj) +{ + if (!PyObject_TypeCheck(obj, type)) { + PyErr_Format(PyExc_TypeError, + "Expected type '%s' but got type '%s'", + (type)->tp_name, Py_TYPE(obj)->tp_name); + return NULL; + } + + return PyObject_GetAttrString(obj, discard_const_p(char, "value")); +} + +PyObject *py_dcerpc_ndr_pointer_wrap(PyTypeObject *type, PyObject *obj) +{ + PyObject *args = NULL; + PyObject *ret_obj = NULL; + + args = PyTuple_New(1); + if (args == NULL) { + return NULL; + } + Py_XINCREF(obj); + PyTuple_SetItem(args, 0, obj); + + ret_obj = PyObject_Call((PyObject *)type, args, NULL); + Py_XDECREF(args); + return ret_obj; +} diff --git a/source4/librpc/rpc/pyrpc_util.h b/source4/librpc/rpc/pyrpc_util.h index 12733122bb1..5a5f14de285 100644 --- a/source4/librpc/rpc/pyrpc_util.h +++ b/source4/librpc/rpc/pyrpc_util.h @@ -64,4 +64,7 @@ PyObject *pyrpc_import_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level, void *pyrpc_export_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level, PyObject *in, const char *typename); +PyObject *py_dcerpc_ndr_pointer_deref(PyTypeObject *type, PyObject *obj); +PyObject *py_dcerpc_ndr_pointer_wrap(PyTypeObject *type, PyObject *obj); + #endif /* __PYRPC_UTIL_H__ */ -- 2.20.1.97.g81188d93c3-goog From a008b73053b3217efe789d8bbb1d8c0e23aa55c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2018 13:25:21 +0100 Subject: [PATCH 098/103] pidl/Python: use py_dcerpc_ndr_pointer_wrap/deref if multiple pointer levels are used This will help the raw_protocol test to explore lsa_GetUserName. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- pidl/lib/Parse/Pidl/Samba4/Python.pm | 35 ++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index 1ef64db14ee..5697b52c4fe 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -1902,6 +1902,9 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$) $recurse = $recurse + 1; if ($l->{TYPE} eq "POINTER") { + my $need_deindent = 0; + my $need_deref = 0; + if ($l->{POINTER_TYPE} ne "ref") { $self->pidl("if ($py_var == Py_None) {"); $self->indent; @@ -1909,10 +1912,13 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$) $self->deindent; $self->pidl("} else {"); $self->indent; + $need_deindent = 1; + if ($nl->{TYPE} eq "POINTER") { + $need_deref = 1; + } } - # if we want to handle more than one level of pointer in python interfaces - # then this is where we would need to allocate it - if ($l->{POINTER_TYPE} eq "ref") { + + if ($l->{POINTER_TYPE} eq "ref" or $need_deref == 1) { $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);"); $self->pidl("if ($var_name == NULL) {"); $self->indent; @@ -1932,11 +1938,15 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$) } else { $self->pidl("$var_name = NULL;"); } + if ($need_deref == 1) { + my $ndr_pointer_typename = $self->import_type_variable("samba.dcerpc.base", "ndr_pointer"); + $self->pidl("$py_var = py_dcerpc_ndr_pointer_deref($ndr_pointer_typename, $py_var);"); + } unless ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) { $var_name = get_value_of($var_name); } $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail, $recurse); - if ($l->{POINTER_TYPE} ne "ref") { + if ($need_deindent == 1) { $self->deindent; $self->pidl("}"); } @@ -2138,6 +2148,10 @@ sub ConvertObjectToPythonLevel($$$$$$$) } if ($l->{TYPE} eq "POINTER") { + my $need_wrap = 0; + if ($l->{POINTER_TYPE} ne "ref" and $nl->{TYPE} eq "POINTER") { + $need_wrap = 1; + } if ($l->{POINTER_TYPE} ne "ref") { if ($recurse == 0) { $self->pidl("if ($var_name == NULL) {"); @@ -2164,6 +2178,19 @@ sub ConvertObjectToPythonLevel($$$$$$$) $self->deindent; $self->pidl("}"); } + if ($need_wrap) { + my $py_var_wrap = undef; + $need_wrap = 1; + $self->pidl("{"); + $self->indent; + $py_var_wrap = "py_$e->{NAME}_level_$l->{LEVEL_INDEX}"; + $self->pidl("PyObject *$py_var_wrap = $py_var;"); + my $ndr_pointer_typename = $self->import_type_variable("samba.dcerpc.base", "ndr_pointer"); + $self->pidl("$py_var = py_dcerpc_ndr_pointer_wrap($ndr_pointer_typename, $py_var_wrap);"); + $self->pidl("Py_XDECREF($py_var_wrap);"); + $self->deindent; + $self->pidl("}"); + } } elsif ($l->{TYPE} eq "ARRAY") { if ($pl && $pl->{TYPE} eq "POINTER") { $var_name = get_pointer_to($var_name); -- 2.20.1.97.g81188d93c3-goog From 4f1af11086ee0c9cc1759cba799b74859ce3d12e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 26 Nov 2018 11:49:22 +0100 Subject: [PATCH 099/103] py:dcerpc/raw_testcase: add assertEqualsStrLower() BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- python/samba/tests/dcerpc/raw_testcase.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py index 555ea8d607d..1a174363214 100644 --- a/python/samba/tests/dcerpc/raw_testcase.py +++ b/python/samba/tests/dcerpc/raw_testcase.py @@ -1158,3 +1158,6 @@ class RawDCERPCTest(TestCase): return zero_pad = b'\0' * length self.assertEquals(pad, zero_pad) + + def assertEqualsStrLower(self, s1, s2): + self.assertEquals(str(s1).lower(), str(s2).lower()) -- 2.20.1.97.g81188d93c3-goog From b299108f6d4868bdfce5075e2a5f7cb12717e644 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2018 11:01:55 +0100 Subject: [PATCH 100/103] py:dcerpc/raw_protocol: add tests to demonstrate how security context multiplexing works Important things are this: - It's not required to use the bind time feature negotiation in order to use it, it's only a hint for the client, but nothing is really negotiated, unlike the request multiplexing with the DCERPC_PFC_FLAG_CONC_MPX. - There's special handling related to AUTH_LEVEL_CONNECT and requests without auth trailer - An security context is identified by the unique tuple of auth_type, auth_level and auth_context_id (all together!), not just the auth_context_id. - There's a limit of 2049 explicit authentication contexts. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- python/samba/tests/dcerpc/raw_protocol.py | 967 ++++++++++++++++++ .../knownfail.d/security_context_multiplexing | 4 + 2 files changed, 971 insertions(+) create mode 100644 selftest/knownfail.d/security_context_multiplexing diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py index a306b17f437..e2c45603d39 100755 --- a/python/samba/tests/dcerpc/raw_protocol.py +++ b/python/samba/tests/dcerpc/raw_protocol.py @@ -29,10 +29,14 @@ import samba.dcerpc.misc as misc import samba.dcerpc.epmapper import samba.dcerpc.mgmt import samba.dcerpc.netlogon +import samba.dcerpc.lsa import struct from samba import gensec from samba.tests.dcerpc.raw_testcase import RawDCERPCTest from samba.compat import binary_type +from samba.ntstatus import ( + NT_STATUS_SUCCESS +) global_ndr_print = False global_hexdump = False @@ -1467,6 +1471,41 @@ class TestDCERPC_BIND(RawDCERPCTest): self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) self.assertEquals(rep.u.auth_info, b'\0' * 0) + def test_no_auth_bind_time_sec_ctx_ignore_additional(self): + features1 = dcerpc.DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING + btf1 = base.bind_time_features_syntax(features1) + + features2 = dcerpc.DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN + btf2 = base.bind_time_features_syntax(features2) + + zero_syntax = misc.ndr_syntax_id() + ndr64 = base.transfer_syntax_ndr64() + + tsf1_list = [btf1, btf2, zero_syntax] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = ndr64 + ctx1.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertPadding(rep.u._pad1, 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) + self.assertEquals(rep.u.ctx_list[0].reason, features1) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax) + self.assertEquals(rep.u.auth_info, b'\0' * 0) + def _test_auth_type_level_bind_nak(self, auth_type, auth_level, creds=None, reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE): ndr32 = base.transfer_syntax_ndr() @@ -5249,6 +5288,934 @@ class TestDCERPC_BIND(RawDCERPCTest): self.assertNotConnected() return + def _test_lsa_multi_auth_connect1(self, smb_creds, + account_name0, authority_name0): + creds1 = self.get_anon_creds() + account_name1 = "ANONYMOUS LOGON" + authority_name1 = "NT AUTHORITY" + auth_type1 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level1 = dcerpc.DCERPC_AUTH_LEVEL_CONNECT + auth_context_id1 = 1 + + creds2 = self.get_user_creds() + account_name2 = creds2.get_username() + authority_name2 = creds2.get_domain() + auth_type2 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level2 = dcerpc.DCERPC_AUTH_LEVEL_CONNECT + auth_context_id2 = 2 + + abstract = samba.dcerpc.lsa.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + self.reconnect_smb_pipe(primary_address='\\pipe\\lsarpc', + secondary_address='\\pipe\\lsass', + transport_creds=smb_creds) + self.assertIsConnected() + + tsf1_list = [transfer] + ctx1 = samba.dcerpc.dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = abstract + ctx1.transfer_syntaxes = tsf1_list + + auth_context1 = self.get_auth_context_creds(creds=creds1, + auth_type=auth_type1, + auth_level=auth_level1, + auth_context_id=auth_context_id1, + hdr_signing=False) + auth_context2 = self.get_auth_context_creds(creds=creds2, + auth_type=auth_type2, + auth_level=auth_level2, + auth_context_id=auth_context_id2, + hdr_signing=False) + + get_user_name = samba.dcerpc.lsa.GetUserName() + get_user_name.in_system_name = self.target_hostname + get_user_name.in_account_name = None + get_user_name.in_authority_name = base.ndr_pointer(None) + + ack1 = self.do_generic_bind(call_id=0, + ctx=ctx1, + auth_context=auth_context1) + + # + # With just one explicit auth context and that + # uses AUTH_LEVEL_CONNECT context. + # + # We always get that by default instead of the one default one + # inherited from the transport + # + self.do_single_request(call_id=1, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=2, ctx=ctx1, io=get_user_name, + auth_context=auth_context1) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + ack2 = self.do_generic_bind(call_id=3, + ctx=ctx1, + auth_context=auth_context2, + assoc_group_id = ack1.u.assoc_group_id, + start_with_alter=True) + + # + # Now we have two explicit auth contexts + # + # If we don't specify one of them we get the default one + # inherited from the transport + # + self.do_single_request(call_id=4, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + self.do_single_request(call_id=5, ctx=ctx1, io=get_user_name, + auth_context=auth_context1) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=6, ctx=ctx1, io=get_user_name, + auth_context=auth_context2) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name2) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name2) + + self.do_single_request(call_id=7, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + return + + def test_lsa_multi_auth_connect1u(self): + smb_auth_creds = self.get_user_creds() + account_name0 = smb_auth_creds.get_username() + authority_name0 = smb_auth_creds.get_domain() + return self._test_lsa_multi_auth_connect1(smb_auth_creds, + account_name0, + authority_name0) + + def test_lsa_multi_auth_connect1a(self): + smb_auth_creds = self.get_anon_creds() + account_name0 = "ANONYMOUS LOGON" + authority_name0 = "NT AUTHORITY" + return self._test_lsa_multi_auth_connect1(smb_auth_creds, + account_name0, + authority_name0) + + def _test_lsa_multi_auth_connect2(self, smb_creds, + account_name0, authority_name0): + creds1 = self.get_anon_creds() + account_name1 = "ANONYMOUS LOGON" + authority_name1 = "NT AUTHORITY" + auth_type1 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level1 = dcerpc.DCERPC_AUTH_LEVEL_CONNECT + auth_context_id1 = 1 + + creds2 = self.get_user_creds() + account_name2 = creds2.get_username() + authority_name2 = creds2.get_domain() + auth_type2 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level2 = dcerpc.DCERPC_AUTH_LEVEL_CONNECT + auth_context_id2 = 2 + + abstract = samba.dcerpc.lsa.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + self.reconnect_smb_pipe(primary_address='\\pipe\\lsarpc', + secondary_address='\\pipe\\lsass', + transport_creds=smb_creds) + self.assertIsConnected() + + tsf1_list = [transfer] + ctx1 = samba.dcerpc.dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = abstract + ctx1.transfer_syntaxes = tsf1_list + + auth_context1 = self.get_auth_context_creds(creds=creds1, + auth_type=auth_type1, + auth_level=auth_level1, + auth_context_id=auth_context_id1, + hdr_signing=False) + auth_context2 = self.get_auth_context_creds(creds=creds2, + auth_type=auth_type2, + auth_level=auth_level2, + auth_context_id=auth_context_id2, + hdr_signing=False) + + get_user_name = samba.dcerpc.lsa.GetUserName() + get_user_name.in_system_name = self.target_hostname + get_user_name.in_account_name = None + get_user_name.in_authority_name = base.ndr_pointer(None) + + ack0 = self.do_generic_bind(call_id=0, ctx=ctx1) + + # + # We use the default auth context + # inherited from the transport + # + self.do_single_request(call_id=1, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + ack1 = self.do_generic_bind(call_id=2, + ctx=ctx1, + auth_context=auth_context1, + assoc_group_id = ack0.u.assoc_group_id, + start_with_alter=True) + + # + # With just one explicit auth context and that + # uses AUTH_LEVEL_CONNECT context. + # + # We always get that by default instead of the one default one + # inherited from the transport + # + self.do_single_request(call_id=3, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=4, ctx=ctx1, io=get_user_name, + auth_context=auth_context1) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + ack2 = self.do_generic_bind(call_id=5, + ctx=ctx1, + auth_context=auth_context2, + assoc_group_id = ack0.u.assoc_group_id, + start_with_alter=True) + + # + # Now we have two explicit auth contexts + # + # If we don't specify one of them we get the default one + # inherited from the transport (again) + # + self.do_single_request(call_id=6, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + self.do_single_request(call_id=7, ctx=ctx1, io=get_user_name, + auth_context=auth_context1) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=8, ctx=ctx1, io=get_user_name, + auth_context=auth_context2) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name2) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name2) + + self.do_single_request(call_id=9, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + return + + def test_lsa_multi_auth_connect2u(self): + smb_auth_creds = self.get_user_creds() + account_name0 = smb_auth_creds.get_username() + authority_name0 = smb_auth_creds.get_domain() + return self._test_lsa_multi_auth_connect2(smb_auth_creds, + account_name0, + authority_name0) + + def test_lsa_multi_auth_connect2a(self): + smb_auth_creds = self.get_anon_creds() + account_name0 = "ANONYMOUS LOGON" + authority_name0 = "NT AUTHORITY" + return self._test_lsa_multi_auth_connect2(smb_auth_creds, + account_name0, + authority_name0) + + def _test_lsa_multi_auth_connect3(self, smb_creds, + account_name0, authority_name0): + creds1 = self.get_anon_creds() + account_name1 = "ANONYMOUS LOGON" + authority_name1 = "NT AUTHORITY" + auth_type1 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level1 = dcerpc.DCERPC_AUTH_LEVEL_CONNECT + auth_context_id1 = 1 + + creds2 = self.get_user_creds() + account_name2 = creds2.get_username() + authority_name2 = creds2.get_domain() + auth_type2 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level2 = dcerpc.DCERPC_AUTH_LEVEL_CONNECT + auth_context_id2 = 2 + + abstract = samba.dcerpc.lsa.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + self.reconnect_smb_pipe(primary_address='\\pipe\\lsarpc', + secondary_address='\\pipe\\lsass', + transport_creds=smb_creds) + self.assertIsConnected() + + tsf1_list = [transfer] + ctx1 = samba.dcerpc.dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = abstract + ctx1.transfer_syntaxes = tsf1_list + + auth_context1 = self.get_auth_context_creds(creds=creds1, + auth_type=auth_type1, + auth_level=auth_level1, + auth_context_id=auth_context_id1, + hdr_signing=False) + auth_context2 = self.get_auth_context_creds(creds=creds2, + auth_type=auth_type2, + auth_level=auth_level2, + auth_context_id=auth_context_id2, + hdr_signing=False) + + get_user_name = samba.dcerpc.lsa.GetUserName() + get_user_name.in_system_name = self.target_hostname + get_user_name.in_account_name = None + get_user_name.in_authority_name = base.ndr_pointer(None) + + ack0 = self.do_generic_bind(call_id=0, ctx=ctx1) + + # + # We use the default auth context + # inherited from the transport + # + self.do_single_request(call_id=1, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + ack1 = self.do_generic_bind(call_id=2, + ctx=ctx1, + auth_context=auth_context1, + assoc_group_id = ack0.u.assoc_group_id, + start_with_alter=True) + + # + # With just one explicit auth context and that + # uses AUTH_LEVEL_CONNECT context. + # + # We always get that by default instead of the one default one + # inherited from the transport + # + # Until an explicit usage resets that mode + # + self.do_single_request(call_id=3, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=4, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=5, ctx=ctx1, io=get_user_name, + auth_context=auth_context1) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=6, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + ack2 = self.do_generic_bind(call_id=7, + ctx=ctx1, + auth_context=auth_context2, + assoc_group_id = ack0.u.assoc_group_id, + start_with_alter=True) + # + # A new auth context won't change that mode again. + # + self.do_single_request(call_id=8, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + self.do_single_request(call_id=9, ctx=ctx1, io=get_user_name, + auth_context=auth_context1) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=10, ctx=ctx1, io=get_user_name, + auth_context=auth_context2) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name2) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name2) + + self.do_single_request(call_id=11, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + return + + def test_lsa_multi_auth_connect3u(self): + smb_auth_creds = self.get_user_creds() + account_name0 = smb_auth_creds.get_username() + authority_name0 = smb_auth_creds.get_domain() + return self._test_lsa_multi_auth_connect3(smb_auth_creds, + account_name0, + authority_name0) + + def test_lsa_multi_auth_connect3a(self): + smb_auth_creds = self.get_anon_creds() + account_name0 = "ANONYMOUS LOGON" + authority_name0 = "NT AUTHORITY" + return self._test_lsa_multi_auth_connect3(smb_auth_creds, + account_name0, + authority_name0) + + def _test_lsa_multi_auth_connect4(self, smb_creds, + account_name0, authority_name0): + creds1 = self.get_anon_creds() + account_name1 = "ANONYMOUS LOGON" + authority_name1 = "NT AUTHORITY" + auth_type1 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level1 = dcerpc.DCERPC_AUTH_LEVEL_CONNECT + auth_context_id1 = 1 + + creds2 = self.get_user_creds() + account_name2 = creds2.get_username() + authority_name2 = creds2.get_domain() + auth_type2 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level2 = dcerpc.DCERPC_AUTH_LEVEL_CONNECT + auth_context_id2 = 2 + + creds3 = self.get_anon_creds() + account_name3 = "ANONYMOUS LOGON" + authority_name3 = "NT AUTHORITY" + auth_type3 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level3 = dcerpc.DCERPC_AUTH_LEVEL_CONNECT + auth_context_id3 = 3 + + creds4 = self.get_user_creds() + account_name4 = creds4.get_username() + authority_name4 = creds4.get_domain() + auth_type4 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level4 = dcerpc.DCERPC_AUTH_LEVEL_CONNECT + auth_context_id4 = 4 + + abstract = samba.dcerpc.lsa.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + self.reconnect_smb_pipe(primary_address='\\pipe\\lsarpc', + secondary_address='\\pipe\\lsass', + transport_creds=smb_creds) + self.assertIsConnected() + + tsf1_list = [transfer] + ctx1 = samba.dcerpc.dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = abstract + ctx1.transfer_syntaxes = tsf1_list + + auth_context1 = self.get_auth_context_creds(creds=creds1, + auth_type=auth_type1, + auth_level=auth_level1, + auth_context_id=auth_context_id1, + hdr_signing=False) + auth_context2 = self.get_auth_context_creds(creds=creds2, + auth_type=auth_type2, + auth_level=auth_level2, + auth_context_id=auth_context_id2, + hdr_signing=False) + auth_context3 = self.get_auth_context_creds(creds=creds3, + auth_type=auth_type3, + auth_level=auth_level3, + auth_context_id=auth_context_id3, + hdr_signing=False) + auth_context4 = self.get_auth_context_creds(creds=creds4, + auth_type=auth_type4, + auth_level=auth_level4, + auth_context_id=auth_context_id4, + hdr_signing=False) + + get_user_name = samba.dcerpc.lsa.GetUserName() + get_user_name.in_system_name = self.target_hostname + get_user_name.in_account_name = None + get_user_name.in_authority_name = base.ndr_pointer(None) + + ack0 = self.do_generic_bind(call_id=0, ctx=ctx1) + + # + # We use the default auth context + # inherited from the transport + # + self.do_single_request(call_id=1, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + ack1 = self.do_generic_bind(call_id=2, + ctx=ctx1, + auth_context=auth_context1, + assoc_group_id = ack0.u.assoc_group_id, + start_with_alter=True) + + # + # With just one explicit auth context and that + # uses AUTH_LEVEL_CONNECT context. + # + # We always get that by default instead of the one default one + # inherited from the transport + # + # Until a new explicit context resets the mode + # + self.do_single_request(call_id=3, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=4, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + ack2 = self.do_generic_bind(call_id=5, + ctx=ctx1, + auth_context=auth_context2, + assoc_group_id = ack0.u.assoc_group_id, + start_with_alter=True) + + # + # A new auth context with LEVEL_CONNECT resets the default. + # + self.do_single_request(call_id=6, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name2) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name2) + + self.do_single_request(call_id=7, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name2) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name2) + + ack3 = self.do_generic_bind(call_id=8, + ctx=ctx1, + auth_context=auth_context3, + assoc_group_id = ack0.u.assoc_group_id, + start_with_alter=True) + + # + # A new auth context with LEVEL_CONNECT resets the default. + # + self.do_single_request(call_id=9, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name3) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name3) + + self.do_single_request(call_id=10, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name3) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name3) + + ack4 = self.do_generic_bind(call_id=11, + ctx=ctx1, + auth_context=auth_context4, + assoc_group_id = ack0.u.assoc_group_id, + start_with_alter=True) + + # + # A new auth context with LEVEL_CONNECT resets the default. + # + self.do_single_request(call_id=12, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name4) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name4) + + self.do_single_request(call_id=13, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name4) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name4) + + # + # Only the explicit usage of any context reset that mode + # + self.do_single_request(call_id=14, ctx=ctx1, io=get_user_name, + auth_context=auth_context1) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=15, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + self.do_single_request(call_id=16, ctx=ctx1, io=get_user_name, + auth_context=auth_context1) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=17, ctx=ctx1, io=get_user_name, + auth_context=auth_context2) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name2) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name2) + + self.do_single_request(call_id=18, ctx=ctx1, io=get_user_name, + auth_context=auth_context3) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name3) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name3) + + self.do_single_request(call_id=19, ctx=ctx1, io=get_user_name, + auth_context=auth_context4) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name4) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name4) + + self.do_single_request(call_id=20, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + return + + def test_lsa_multi_auth_connect4u(self): + smb_auth_creds = self.get_user_creds() + account_name0 = smb_auth_creds.get_username() + authority_name0 = smb_auth_creds.get_domain() + return self._test_lsa_multi_auth_connect4(smb_auth_creds, + account_name0, + authority_name0) + + def test_lsa_multi_auth_connect4a(self): + smb_auth_creds = self.get_anon_creds() + account_name0 = "ANONYMOUS LOGON" + authority_name0 = "NT AUTHORITY" + return self._test_lsa_multi_auth_connect4(smb_auth_creds, + account_name0, + authority_name0) + + def _test_lsa_multi_auth_sign_connect1(self, smb_creds, + account_name0, authority_name0): + + creds1 = self.get_user_creds() + account_name1 = creds1.get_username() + authority_name1 = creds1.get_domain() + auth_type1 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level1 = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY + auth_context_id1 = 1 + + creds2 = self.get_user_creds() + account_name2 = creds2.get_username() + authority_name2 = creds2.get_domain() + auth_type2 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level2 = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY + auth_context_id2 = 2 + + creds3 = self.get_anon_creds() + account_name3 = "ANONYMOUS LOGON" + authority_name3 = "NT AUTHORITY" + auth_type3 = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP + auth_level3 = dcerpc.DCERPC_AUTH_LEVEL_CONNECT + auth_context_id3 = 3 + + abstract = samba.dcerpc.lsa.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + self.reconnect_smb_pipe(primary_address='\\pipe\\lsarpc', + secondary_address='\\pipe\\lsass', + transport_creds=smb_creds) + self.assertIsConnected() + + tsf1_list = [transfer] + ctx1 = samba.dcerpc.dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = abstract + ctx1.transfer_syntaxes = tsf1_list + + auth_context1 = self.get_auth_context_creds(creds=creds1, + auth_type=auth_type1, + auth_level=auth_level1, + auth_context_id=auth_context_id1, + hdr_signing=False) + auth_context2 = self.get_auth_context_creds(creds=creds2, + auth_type=auth_type2, + auth_level=auth_level2, + auth_context_id=auth_context_id2, + hdr_signing=False) + auth_context3 = self.get_auth_context_creds(creds=creds3, + auth_type=auth_type3, + auth_level=auth_level3, + auth_context_id=auth_context_id3, + hdr_signing=False) + + get_user_name = samba.dcerpc.lsa.GetUserName() + get_user_name.in_system_name = self.target_hostname + get_user_name.in_account_name = None + get_user_name.in_authority_name = base.ndr_pointer(None) + + ack1 = self.do_generic_bind(call_id=0, + ctx=ctx1, + auth_context=auth_context1) + + # + # With just one explicit auth context and that + # *not* uses AUTH_LEVEL_CONNECT context. + # + # We don't get the by default (auth_context1) + # + self.do_single_request(call_id=1, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + self.do_single_request(call_id=2, ctx=ctx1, io=get_user_name, + auth_context=auth_context1) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=3, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + ack2 = self.do_generic_bind(call_id=4, + ctx=ctx1, + auth_context=auth_context2, + assoc_group_id = ack1.u.assoc_group_id, + start_with_alter=True) + + # + # With just two explicit auth context and + # *none* uses AUTH_LEVEL_CONNECT context. + # + # We don't get auth_context1 or auth_context2 by default + # + self.do_single_request(call_id=5, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + self.do_single_request(call_id=6, ctx=ctx1, io=get_user_name, + auth_context=auth_context1) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=7, ctx=ctx1, io=get_user_name, + auth_context=auth_context2) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name2) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name2) + + self.do_single_request(call_id=8, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + ack3 = self.do_generic_bind(call_id=9, + ctx=ctx1, + auth_context=auth_context3, + assoc_group_id = ack1.u.assoc_group_id, + start_with_alter=True) + + # + # Now we have tree explicit auth contexts, + # but just one with AUTH_LEVEL_CONNECT + # + # If we don't specify one of them we get + # that one auth_level_connect context. + # + # Until an explicit usage of any auth context reset that mode. + # + self.do_single_request(call_id=10, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name3) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name3) + + self.do_single_request(call_id=11, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name3) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name3) + + self.do_single_request(call_id=12, ctx=ctx1, io=get_user_name, + auth_context=auth_context1) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name1) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name1) + + self.do_single_request(call_id=13, ctx=ctx1, io=get_user_name) + self.assertEqual(get_user_name.result[0], NT_STATUS_SUCCESS) + self.assertEqualsStrLower(get_user_name.out_account_name, account_name0) + self.assertEqualsStrLower(get_user_name.out_authority_name.value, authority_name0) + + return + + def test_lsa_multi_auth_sign_connect1u(self): + smb_auth_creds = self.get_user_creds() + account_name0 = smb_auth_creds.get_username() + authority_name0 = smb_auth_creds.get_domain() + return self._test_lsa_multi_auth_sign_connect1(smb_auth_creds, + account_name0, + authority_name0) + def test_lsa_multi_auth_sign_connect1a(self): + smb_auth_creds = self.get_anon_creds() + account_name0 = "ANONYMOUS LOGON" + authority_name0 = "NT AUTHORITY" + return self._test_lsa_multi_auth_sign_connect1(smb_auth_creds, + account_name0, + authority_name0) + + def test_spnego_multiple_auth_hdr_signing(self): + auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO + auth_level1 = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY + auth_context_id1=1 + auth_level2 = dcerpc.DCERPC_AUTH_LEVEL_PACKET + auth_context_id2=2 + + creds = self.get_user_creds() + + abstract = samba.dcerpc.mgmt.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + tsf1_list = [transfer] + ctx = samba.dcerpc.dcerpc.ctx_list() + ctx.context_id = 1 + ctx.num_transfer_syntaxes = len(tsf1_list) + ctx.abstract_syntax = abstract + ctx.transfer_syntaxes = tsf1_list + + auth_context1 = self.get_auth_context_creds(creds=creds, + auth_type=auth_type, + auth_level=auth_level1, + auth_context_id=auth_context_id1, + hdr_signing=False) + auth_context2 = self.get_auth_context_creds(creds=creds, + auth_type=auth_type, + auth_level=auth_level2, + auth_context_id=auth_context_id2, + hdr_signing=False) + + ack0 = self.do_generic_bind(call_id=1, ctx=ctx) + + ack1 = self.do_generic_bind(call_id=2, + ctx=ctx, + auth_context=auth_context1, + assoc_group_id = ack0.u.assoc_group_id, + start_with_alter=True) + ack2 = self.do_generic_bind(call_id=3, + ctx=ctx, + auth_context=auth_context2, + assoc_group_id = ack0.u.assoc_group_id, + start_with_alter=True) + + inq_if_ids = samba.dcerpc.mgmt.inq_if_ids() + self.do_single_request(call_id=4, ctx=ctx, io=inq_if_ids) + self.do_single_request(call_id=5, ctx=ctx, io=inq_if_ids, + auth_context=auth_context1) + self.do_single_request(call_id=6, ctx=ctx, io=inq_if_ids, + auth_context=auth_context2) + + ack3 = self.do_generic_bind(call_id=7, ctx=ctx, + pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN, + assoc_group_id = ack0.u.assoc_group_id, + start_with_alter=True) + + self.assertFalse(auth_context1['hdr_signing']) + auth_context1['hdr_signing'] = True + auth_context1["gensec"].want_feature(gensec.FEATURE_SIGN_PKT_HEADER) + + self.do_single_request(call_id=8, ctx=ctx, io=inq_if_ids) + self.do_single_request(call_id=9, ctx=ctx, io=inq_if_ids, + auth_context=auth_context1) + self.do_single_request(call_id=10, ctx=ctx, io=inq_if_ids, + auth_context=auth_context2, + fault_status=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def test_multiple_auth_limit(self): + creds = self.get_user_creds() + + abstract = samba.dcerpc.mgmt.abstract_syntax() + transfer = base.transfer_syntax_ndr() + + tsf1_list = [transfer] + ctx = samba.dcerpc.dcerpc.ctx_list() + ctx.context_id = 1 + ctx.num_transfer_syntaxes = len(tsf1_list) + ctx.abstract_syntax = abstract + ctx.transfer_syntaxes = tsf1_list + + ack0 = self.do_generic_bind(call_id=0, ctx=ctx) + + is_server_listening = samba.dcerpc.mgmt.is_server_listening() + + max_num_auth_str = samba.tests.env_get_var_value('MAX_NUM_AUTH', allow_missing=True) + if max_num_auth_str is not None: + max_num_auth = int(max_num_auth_str) + else: + max_num_auth = 2049 + + for i in range(1, max_num_auth+2): + auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO + auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY + auth_context_id = i + + auth_context = self.get_auth_context_creds(creds=creds, + auth_type=auth_type, + auth_level=auth_level, + auth_context_id=auth_context_id, + hdr_signing=False) + + alter_fault = None + if i > max_num_auth: + alter_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR + + ack = self.do_generic_bind(call_id=auth_context_id, + ctx=ctx, + auth_context=auth_context, + assoc_group_id = ack0.u.assoc_group_id, + alter_fault=alter_fault, + start_with_alter=True, + ) + if alter_fault is not None: + break + + + self.do_single_request(call_id=auth_context_id, + ctx=ctx, io=is_server_listening, + auth_context=auth_context) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + return + + if __name__ == "__main__": global_ndr_print = True global_hexdump = True diff --git a/selftest/knownfail.d/security_context_multiplexing b/selftest/knownfail.d/security_context_multiplexing new file mode 100644 index 00000000000..b5b9658af88 --- /dev/null +++ b/selftest/knownfail.d/security_context_multiplexing @@ -0,0 +1,4 @@ +^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_lsa_multi_auth.* +^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_spnego_multiple_auth_hdr_signing +^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_multiple_auth_limit +^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_no_auth_bind_time_sec_ctx_ignore_additional -- 2.20.1.97.g81188d93c3-goog From d970c00a8a442283d6e0d0b524bbe1d4992e2b1f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2018 14:59:58 +0100 Subject: [PATCH 101/103] s4:rpc_server: implement security context multiplexing There're some systems like Cisco ISE use security multiplexing without checking (via bind time feature negotiation) the server supports it. Others like VMWare View, fallback to NT4 style netlogon connections without using netlogon secure channel, which then triggers an error, with "server schannel = yes", see https://bugzilla.samba.org/show_bug.cgi?id=13464. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- .../knownfail.d/security_context_multiplexing | 4 - source4/rpc_server/dcerpc_server.c | 98 +++++++++++++++- source4/rpc_server/dcerpc_server.h | 6 + source4/rpc_server/dcesrv_auth.c | 108 ++++++++++++++++-- 4 files changed, 199 insertions(+), 17 deletions(-) delete mode 100644 selftest/knownfail.d/security_context_multiplexing diff --git a/selftest/knownfail.d/security_context_multiplexing b/selftest/knownfail.d/security_context_multiplexing deleted file mode 100644 index b5b9658af88..00000000000 --- a/selftest/knownfail.d/security_context_multiplexing +++ /dev/null @@ -1,4 +0,0 @@ -^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_lsa_multi_auth.* -^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_spnego_multiple_auth_hdr_signing -^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_multiple_auth_limit -^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_no_auth_bind_time_sec_ctx_ignore_additional diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 75e1dfea1c7..9c5bb4f6026 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -643,6 +643,11 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, "dcesrv", "header signing", true); + p->max_auth_states = lpcfg_parm_ulong(dce_ctx->lp_ctx, + NULL, + "dcesrv", + "max auth states", + 2049); auth = dcesrv_auth_create(p); if (auth == NULL) { @@ -707,6 +712,8 @@ static void dcesrv_call_set_list(struct dcesrv_call_state *call, static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, const char *reason) { + struct dcesrv_auth *a = NULL; + if (call->conn->terminate != NULL) { return; } @@ -716,6 +723,10 @@ static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, call->conn->default_auth_state->auth_invalid = true; + for (a = call->conn->auth_states; a != NULL; a = a->next) { + a->auth_invalid = true; + } + call->terminate_reason = talloc_strdup(call, reason); if (call->terminate_reason == NULL) { call->terminate_reason = __location__; @@ -1126,7 +1137,10 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK; a->reason.negotiate = 0; if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) { - /* not supported yet */ + if (call->conn->max_auth_states != 0) { + a->reason.negotiate |= + DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING; + } } if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) { a->reason.negotiate |= @@ -2018,6 +2032,10 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, NTSTATUS status; struct dcesrv_call_state *call; struct dcesrv_call_state *existing = NULL; + size_t num_auth_ctx = 0; + enum dcerpc_AuthType auth_type = 0; + enum dcerpc_AuthLevel auth_level = 0; + uint32_t auth_context_id = 0; call = talloc_zero(dce_conn, struct dcesrv_call_state); if (!call) { @@ -2036,7 +2054,73 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, talloc_steal(call, blob.data); call->pkt = *pkt; - call->auth_state = dce_conn->default_auth_state; + if (dce_conn->max_auth_states == 0) { + call->auth_state = dce_conn->default_auth_state; + } else if (call->pkt.auth_length == 0) { + if (call->pkt.ptype == DCERPC_PKT_REQUEST && + dce_conn->default_auth_level_connect != NULL) + { + call->auth_state = dce_conn->default_auth_level_connect; + } else { + call->auth_state = dce_conn->default_auth_state; + } + } + + if (call->auth_state == NULL) { + struct dcesrv_auth *a = NULL; + + auth_type = dcerpc_get_auth_type(&blob); + auth_level = dcerpc_get_auth_level(&blob); + auth_context_id = dcerpc_get_auth_context_id(&blob); + + if (call->pkt.ptype == DCERPC_PKT_REQUEST) { + dce_conn->default_auth_level_connect = NULL; + if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) { + dce_conn->got_explicit_auth_level_connect = true; + } + } + + for (a = dce_conn->auth_states; a != NULL; a = a->next) { + num_auth_ctx++; + + if (a->auth_type != auth_type) { + continue; + } + if (a->auth_finished && a->auth_level != auth_level) { + continue; + } + if (a->auth_context_id != auth_context_id) { + continue; + } + + DLIST_PROMOTE(dce_conn->auth_states, a); + call->auth_state = a; + break; + } + } + + if (call->auth_state == NULL) { + struct dcesrv_auth *a = NULL; + + if (num_auth_ctx >= dce_conn->max_auth_states) { + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); + } + + a = dcesrv_auth_create(dce_conn); + if (a == NULL) { + talloc_free(call); + return NT_STATUS_NO_MEMORY; + } + DLIST_ADD(dce_conn->auth_states, a); + if (call->pkt.ptype == DCERPC_PKT_REQUEST) { + /* + * This can never be valid. + */ + a->auth_invalid = true; + } + call->auth_state = a; + } talloc_set_destructor(call, dcesrv_call_dequeue); @@ -2051,7 +2135,10 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, /* we have to check the signing here, before combining the pdus */ if (call->pkt.ptype == DCERPC_PKT_REQUEST) { - if (!call->auth_state->auth_finished) { + dcesrv_default_auth_state_prepare_request(call); + + if (call->auth_state->auth_started && + !call->auth_state->auth_finished) { return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); } @@ -2479,6 +2566,7 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void) static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason) { struct dcesrv_context *dce_ctx = dce_conn->dce_ctx; + struct dcesrv_auth *a = NULL; struct stream_connection *srv_conn; srv_conn = talloc_get_type(dce_conn->transport.private_data, struct stream_connection); @@ -2492,6 +2580,10 @@ static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, cons dce_conn->default_auth_state->auth_invalid = true; + for (a = dce_conn->auth_states; a != NULL; a = a->next) { + a->auth_invalid = true; + } + if (dce_conn->pending_call_list == NULL) { char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 25a3aedc2e1..50b07462cfd 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -197,6 +197,7 @@ struct dcesrv_handle { /* hold the authentication state information */ struct dcesrv_auth { + struct dcesrv_auth *prev, *next; enum dcerpc_AuthType auth_type; enum dcerpc_AuthLevel auth_level; uint32_t auth_context_id; @@ -205,6 +206,7 @@ struct dcesrv_auth { NTSTATUS (*session_key_fn)(struct dcesrv_auth *, DATA_BLOB *session_key); bool auth_started; bool auth_finished; + bool auth_audited; bool auth_invalid; }; @@ -288,6 +290,10 @@ struct dcesrv_connection { /* the current authentication state */ struct dcesrv_auth *default_auth_state; + size_t max_auth_states; + struct dcesrv_auth *auth_states; + bool got_explicit_auth_level_connect; + struct dcesrv_auth *default_auth_level_connect; bool client_hdr_signing; bool support_hdr_signing; bool negotiated_hdr_signing; diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 192d90ba759..c71e4868436 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -36,7 +36,7 @@ static NTSTATUS dcesrv_auth_negotiate_hdr_signing(struct dcesrv_call_state *call struct ncacn_packet *pkt) { struct dcesrv_connection *dce_conn = call->conn; - struct dcesrv_auth *auth = call->auth_state; + struct dcesrv_auth *a = NULL; if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)) { return NT_STATUS_OK; @@ -60,12 +60,20 @@ static NTSTATUS dcesrv_auth_negotiate_hdr_signing(struct dcesrv_call_state *call pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; } - if (auth->gensec_security == NULL) { - return NT_STATUS_OK; + a = call->conn->default_auth_state; + if (a->gensec_security != NULL) { + gensec_want_feature(a->gensec_security, + GENSEC_FEATURE_SIGN_PKT_HEADER); } - gensec_want_feature(auth->gensec_security, - GENSEC_FEATURE_SIGN_PKT_HEADER); + for (a = call->conn->auth_states; a != NULL; a = a->next) { + if (a->gensec_security == NULL) { + continue; + } + + gensec_want_feature(a->gensec_security, + GENSEC_FEATURE_SIGN_PKT_HEADER); + } return NT_STATUS_OK; } @@ -250,6 +258,68 @@ static void log_successful_dcesrv_authz_event(struct dcesrv_call_state *call) auth_type, transport_protection, auth->session_info); + + auth->auth_audited = true; +} + +static void dcesrv_default_auth_state_finish_bind(struct dcesrv_call_state *call) +{ + SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_BIND); + + if (call->auth_state == call->conn->default_auth_state) { + return; + } + + if (call->conn->default_auth_state->auth_started) { + return; + } + + if (call->conn->default_auth_state->auth_invalid) { + return; + } + + call->conn->default_auth_state->auth_type = DCERPC_AUTH_TYPE_NONE; + call->conn->default_auth_state->auth_level = DCERPC_AUTH_LEVEL_NONE; + call->conn->default_auth_state->auth_context_id = 0; + call->conn->default_auth_state->auth_started = true; + call->conn->default_auth_state->auth_finished = true; + + /* + * + * We defer log_successful_dcesrv_authz_event() + * to dcesrv_default_auth_state_prepare_request() + * + * As we don't want to trigger authz_events + * just for alter_context requests without authentication + */ +} + +void dcesrv_default_auth_state_prepare_request(struct dcesrv_call_state *call) +{ + struct dcesrv_connection *dce_conn = call->conn; + struct dcesrv_auth *auth = call->auth_state; + + if (auth->auth_audited) { + return; + } + + if (call->pkt.ptype != DCERPC_PKT_REQUEST) { + return; + } + + if (auth != dce_conn->default_auth_state) { + return; + } + + if (auth->auth_invalid) { + return; + } + + if (!auth->auth_finished) { + return; + } + + log_successful_dcesrv_authz_event(call); } /* @@ -338,6 +408,12 @@ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) } auth->auth_finished = true; + if (auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT && + !call->conn->got_explicit_auth_level_connect) + { + call->conn->default_auth_level_connect = auth; + } + if (call->pkt.ptype != DCERPC_PKT_AUTH3) { return NT_STATUS_OK; } @@ -367,6 +443,7 @@ NTSTATUS dcesrv_auth_prepare_bind_ack(struct dcesrv_call_state *call, struct nca } dce_conn->allow_alter = true; + dcesrv_default_auth_state_finish_bind(call); if (call->pkt.auth_length == 0) { auth->auth_finished = true; @@ -467,11 +544,6 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) return false; } - /* We can't work without an existing gensec state */ - if (auth->gensec_security == NULL) { - return false; - } - status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.alter.auth_info, &call->in_auth_info, NULL, true); if (!NT_STATUS_IS_OK(status)) { @@ -479,6 +551,18 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) return false; } + if (!auth->auth_started) { + bool ok; + + ok = dcesrv_auth_prepare_gensec(call); + if (!ok) { + call->fault_code = DCERPC_FAULT_ACCESS_DENIED; + return false; + } + + return true; + } + if (call->in_auth_info.auth_type == DCERPC_AUTH_TYPE_NONE) { call->fault_code = DCERPC_FAULT_ACCESS_DENIED; return false; @@ -552,6 +636,10 @@ bool dcesrv_auth_pkt_pull(struct dcesrv_call_state *call, }; NTSTATUS status; + if (!auth->auth_started) { + return false; + } + if (!auth->auth_finished) { call->fault_code = DCERPC_NCA_S_PROTO_ERROR; return false; -- 2.20.1.97.g81188d93c3-goog From 178c940b92ee6dcfda2f3c3d7598440f96277ce0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Dec 2018 13:51:27 +0100 Subject: [PATCH 102/103] selftest:Samba4: run the raw_protocol test with a limit of 8 auth contexts This is much faster than exploring the limit of 2049 during autobuild. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- selftest/target/Samba4.pm | 1 + source4/selftest/tests.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index a44ad320074..fe6527c6678 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -2052,6 +2052,7 @@ sub provision_chgdcpass($$) my $extra_smb_conf = " check password script = sed -e '/$unacceptable_password/{;q1}; /$unacceptable_password/!{q0}' allow dcerpc auth level connect:lsarpc = yes + dcesrv:max auth states = 8 "; my $extra_provision_options = ["--use-ntvfs"]; push (@{$extra_provision_options}, "--dns-backend=BIND9_DLZ"); diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 32887066161..a1f38424af7 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -703,7 +703,9 @@ planoldpythontestsuite( planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) -planoldpythontestsuite("chgdcpass", "samba.tests.dcerpc.raw_protocol", extra_args=['-U"$USERNAME%$PASSWORD"'], py3_compatible=True) +planoldpythontestsuite("chgdcpass", "samba.tests.dcerpc.raw_protocol", py3_compatible=True, + environ={'MAX_NUM_AUTH': '8'}) + if have_heimdal_support: planoldpythontestsuite("ad_dc:local", "samba.tests.auth_log", extra_args=['-U"$USERNAME%$PASSWORD"'], environ={'CLIENT_IP': '127.0.0.11', -- 2.20.1.97.g81188d93c3-goog From 09e910fcc140c2d7795c5e6809e249f40b10ab82 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Dec 2018 13:36:39 +0100 Subject: [PATCH 103/103] selftest:Samba4: run fl2003dc without security context multiplexing BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- selftest/target/Samba4.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index fe6527c6678..87c9f7dc4f2 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -1678,6 +1678,7 @@ sub provision_fl2003dc($$$) print "PROVISIONING DC WITH FOREST LEVEL 2003...\n"; my $extra_conf_options = "allow dns updates = nonsecure and secure dcesrv:header signing = no + dcesrv:max auth states = 0 dns forwarder = 127.0.0.$swiface1 127.0.0.$swiface2"; my $extra_provision_options = ["--use-ntvfs"]; my $ret = $self->provision($prefix, -- 2.20.1.97.g81188d93c3-goog