summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2018-11-21 09:39:36 +0100
committerJeremy Allison <jra@samba.org>2019-01-12 03:13:40 +0100
commit975e8e1f25456302bddc7245bb1f0570518b4af1 (patch)
tree4e66cf0c2517be3ad211f3ff1b355e42f5121ea9 /source4
parentfb9f613364d6ec32ae22b12b1d6785f094154de2 (diff)
downloadsamba-975e8e1f25456302bddc7245bb1f0570518b4af1.tar.gz
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 <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source4')
-rw-r--r--source4/rpc_server/dcerpc_server.c9
-rw-r--r--source4/rpc_server/dcerpc_server.h5
-rw-r--r--source4/rpc_server/dcesrv_auth.c76
3 files changed, 61 insertions, 29 deletions
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 */