mirror of
https://github.com/samba-team/samba.git
synced 2025-01-18 06:04:06 +03:00
s4:librpc/rpc: define required schannel flags and enforce them
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
This commit is contained in:
parent
69b0cbd13d
commit
25294685b1
@ -42,6 +42,7 @@ struct schannel_key_state {
|
|||||||
bool dcerpc_schannel_auto;
|
bool dcerpc_schannel_auto;
|
||||||
struct cli_credentials *credentials;
|
struct cli_credentials *credentials;
|
||||||
struct netlogon_creds_CredentialState *creds;
|
struct netlogon_creds_CredentialState *creds;
|
||||||
|
uint32_t required_negotiate_flags;
|
||||||
uint32_t local_negotiate_flags;
|
uint32_t local_negotiate_flags;
|
||||||
uint32_t remote_negotiate_flags;
|
uint32_t remote_negotiate_flags;
|
||||||
struct netr_Credential credentials1;
|
struct netr_Credential credentials1;
|
||||||
@ -235,6 +236,29 @@ static void continue_srv_auth2(struct tevent_req *subreq)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint32_t rqf = s->required_negotiate_flags;
|
||||||
|
uint32_t rf = s->remote_negotiate_flags;
|
||||||
|
uint32_t lf = s->local_negotiate_flags;
|
||||||
|
|
||||||
|
if ((rf & NETLOGON_NEG_SUPPORTS_AES) &&
|
||||||
|
(lf & NETLOGON_NEG_SUPPORTS_AES))
|
||||||
|
{
|
||||||
|
rqf &= ~NETLOGON_NEG_ARCFOUR;
|
||||||
|
rqf &= ~NETLOGON_NEG_STRONG_KEYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rqf & rf) != rqf) {
|
||||||
|
rqf = s->required_negotiate_flags;
|
||||||
|
DBG_ERR("The client capabilities don't match "
|
||||||
|
"the server capabilities: local[0x%08X] "
|
||||||
|
"required[0x%08X] remote[0x%08X]\n",
|
||||||
|
lf, rqf, rf);
|
||||||
|
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Strong keys could be unsupported (NT4) or disabled. So retry with the
|
* Strong keys could be unsupported (NT4) or disabled. So retry with the
|
||||||
* flags returned by the server. - asn
|
* flags returned by the server. - asn
|
||||||
@ -327,6 +351,8 @@ static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
|
|||||||
struct composite_context *epm_map_req;
|
struct composite_context *epm_map_req;
|
||||||
enum netr_SchannelType schannel_type = cli_credentials_get_secure_channel_type(credentials);
|
enum netr_SchannelType schannel_type = cli_credentials_get_secure_channel_type(credentials);
|
||||||
struct cli_credentials *epm_creds = NULL;
|
struct cli_credentials *epm_creds = NULL;
|
||||||
|
bool reject_md5_servers = false;
|
||||||
|
bool require_strong_key = false;
|
||||||
|
|
||||||
/* composite context allocation and setup */
|
/* composite context allocation and setup */
|
||||||
c = composite_create(mem_ctx, p->conn->event_ctx);
|
c = composite_create(mem_ctx, p->conn->event_ctx);
|
||||||
@ -340,19 +366,48 @@ static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
|
|||||||
s->pipe = p;
|
s->pipe = p;
|
||||||
s->credentials = credentials;
|
s->credentials = credentials;
|
||||||
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
|
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
|
||||||
|
s->required_negotiate_flags = NETLOGON_NEG_AUTHENTICATED_RPC;
|
||||||
|
|
||||||
/* allocate credentials */
|
/* allocate credentials */
|
||||||
if (s->pipe->conn->flags & DCERPC_SCHANNEL_128) {
|
if (s->pipe->conn->flags & DCERPC_SCHANNEL_128) {
|
||||||
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
|
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
|
||||||
|
require_strong_key = true;
|
||||||
}
|
}
|
||||||
if (s->pipe->conn->flags & DCERPC_SCHANNEL_AES) {
|
if (s->pipe->conn->flags & DCERPC_SCHANNEL_AES) {
|
||||||
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
|
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
|
||||||
s->local_negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES;
|
reject_md5_servers = true;
|
||||||
}
|
}
|
||||||
if (s->pipe->conn->flags & DCERPC_SCHANNEL_AUTO) {
|
if (s->pipe->conn->flags & DCERPC_SCHANNEL_AUTO) {
|
||||||
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
|
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
|
||||||
s->local_negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES;
|
s->local_negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES;
|
||||||
s->dcerpc_schannel_auto = true;
|
s->dcerpc_schannel_auto = true;
|
||||||
|
reject_md5_servers = lpcfg_reject_md5_servers(lp_ctx);
|
||||||
|
require_strong_key = lpcfg_require_strong_key(lp_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
|
||||||
|
reject_md5_servers = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reject_md5_servers) {
|
||||||
|
require_strong_key = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require_strong_key) {
|
||||||
|
s->required_negotiate_flags |= NETLOGON_NEG_ARCFOUR;
|
||||||
|
s->required_negotiate_flags |= NETLOGON_NEG_STRONG_KEYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reject_md5_servers) {
|
||||||
|
s->required_negotiate_flags |= NETLOGON_NEG_PASSWORD_SET2;
|
||||||
|
s->required_negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->local_negotiate_flags |= s->required_negotiate_flags;
|
||||||
|
|
||||||
|
if (s->required_negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||||
|
s->required_negotiate_flags &= ~NETLOGON_NEG_ARCFOUR;
|
||||||
|
s->required_negotiate_flags &= ~NETLOGON_NEG_STRONG_KEYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* type of authentication depends on schannel type */
|
/* type of authentication depends on schannel type */
|
||||||
@ -360,10 +415,6 @@ static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
|
|||||||
s->local_negotiate_flags |= NETLOGON_NEG_RODC_PASSTHROUGH;
|
s->local_negotiate_flags |= NETLOGON_NEG_RODC_PASSTHROUGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
|
|
||||||
s->local_negotiate_flags &= ~NETLOGON_NEG_ARCFOUR;
|
|
||||||
}
|
|
||||||
|
|
||||||
epm_creds = cli_credentials_init_anon(s);
|
epm_creds = cli_credentials_init_anon(s);
|
||||||
if (composite_nomem(epm_creds, c)) return c;
|
if (composite_nomem(epm_creds, c)) return c;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user