From 98c1677b1cdd844ca2b28b28e015e977eb2ef24f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Mar 2016 15:31:23 +0100 Subject: [PATCH] CVE-2016-2111: s4:rpc_server: implement 'server schannel = yes' restriction MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index b2f0073d091..045908882d3 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -126,6 +126,8 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(dce_call->conn->dce_ctx->lp_ctx); bool reject_des_client = !allow_nt4_crypto; bool reject_md5_client = lpcfg_reject_md5_clients(dce_call->conn->dce_ctx->lp_ctx); + int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); + bool reject_none_rpc = (schannel == true); ZERO_STRUCTP(r->out.return_credentials); *r->out.rid = 0; @@ -198,6 +200,10 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca negotiate_flags = *r->in.negotiate_flags & server_flags; + if (negotiate_flags & NETLOGON_NEG_AUTHENTICATED_RPC) { + reject_none_rpc = false; + } + if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) { reject_des_client = false; } @@ -234,6 +240,14 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca */ *r->out.negotiate_flags = negotiate_flags; + if (reject_none_rpc) { + /* schannel must be used, but client did not offer it. */ + DEBUG(0,("%s: schannel required but client failed " + "to offer it. Client was %s\n", + __func__, r->in.account_name)); + return NT_STATUS_ACCESS_DENIED; + } + switch (r->in.secure_channel_type) { case SEC_CHAN_WKSTA: case SEC_CHAN_DNS_DOMAIN: @@ -488,7 +502,8 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc { NTSTATUS nt_status; struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info; - bool schannel_global_required = false; /* Should be lpcfg_schannel_server() == true */ + int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); + bool schannel_global_required = (schannel == true); if (schannel_global_required) { nt_status = schannel_check_required(auth_info, -- 2.47.2