diff options
author | Stefan Metzmacher <metze@samba.org> | 2018-11-21 09:39:36 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2019-01-12 03:13:40 +0100 |
commit | 975e8e1f25456302bddc7245bb1f0570518b4af1 (patch) | |
tree | 4e66cf0c2517be3ad211f3ff1b355e42f5121ea9 /source4 | |
parent | fb9f613364d6ec32ae22b12b1d6785f094154de2 (diff) | |
download | samba-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.c | 9 | ||||
-rw-r--r-- | source4/rpc_server/dcerpc_server.h | 5 | ||||
-rw-r--r-- | source4/rpc_server/dcesrv_auth.c | 76 |
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 */ |