From 126e3e992bed7174d60ee19212db9b717647ab2e Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 30 Mar 2016 16:55:44 +0200 Subject: [PATCH 1/3] CVE-2016-2112: s3:ntlmssp: Implement missing ntlmssp_have_feature() Signed-off-by: Andreas Schneider --- source3/include/proto.h | 1 + source3/libsmb/ntlmssp.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) --- source3/include/proto.h +++ source3/include/proto.h @@ -1260,6 +1260,7 @@ NTSTATUS ntlmssp_set_password(struct ntl NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) ; void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list); void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature); +bool ntlmssp_have_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature); NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB in, DATA_BLOB *out) ; NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, --- source3/libsmb/ntlmssp.c +++ source3/libsmb/ntlmssp.c @@ -162,6 +162,36 @@ NTSTATUS ntlmssp_set_domain(struct ntlms return NT_STATUS_OK; } +bool ntlmssp_have_feature(struct ntlmssp_state *ntlmssp_state, + uint32_t feature) +{ + if (feature & NTLMSSP_FEATURE_SIGN) { + if (ntlmssp_state->session_key.length == 0) { + return false; + } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { + return true; + } + } + + if (feature & NTLMSSP_FEATURE_SEAL) { + if (ntlmssp_state->session_key.length == 0) { + return false; + } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + return true; + } + } + + if (feature & NTLMSSP_FEATURE_SESSION_KEY) { + if (ntlmssp_state->session_key.length > 0) { + return true; + } + } + + return false; +} + /** * Request features for the NTLMSSP negotiation * --- source3/libads/sasl.c +++ source3/libads/sasl.c @@ -261,6 +261,37 @@ static ADS_STATUS ads_sasl_spnego_ntlmss /* we have a reference conter on ntlmssp_state, if we are signing then the state will be kept by the signing engine */ + if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SEAL) { + bool ok; + + ok = ntlmssp_have_feature(ntlmssp_state, + NTLMSSP_FEATURE_SEAL); + if (!ok) { + DEBUG(0,("The ntlmssp feature sealing request, but unavailable\n")); + TALLOC_FREE(ntlmssp_state); + return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + } + + ok = ntlmssp_have_feature(ntlmssp_state, + NTLMSSP_FEATURE_SIGN); + if (!ok) { + DEBUG(0,("The ntlmssp feature signing request, but unavailable\n")); + TALLOC_FREE(ntlmssp_state); + return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + } + + } else if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SIGN) { + bool ok; + + ok = ntlmssp_have_feature(ntlmssp_state, + NTLMSSP_FEATURE_SIGN); + if (!ok) { + DEBUG(0,("The gensec feature signing request, but unavailable\n")); + TALLOC_FREE(ntlmssp_state); + return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + } + } + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { ads->ldap.out.max_unwrapped = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED - NTLMSSP_SIG_SIZE; ads->ldap.out.sig_size = NTLMSSP_SIG_SIZE; --- docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml +++ docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml @@ -34,11 +34,9 @@ - The default value is plain which is not irritable - to KRB5 clock skew errors. That implies synchronizing the time - with the KDC in the case of using sign or - seal. + The default value is sign. That implies synchronizing the time + with the KDC in the case of using Kerberos. -plain +sign --- source3/param/loadparm.c +++ source3/param/loadparm.c @@ -5392,6 +5392,8 @@ static void init_globals(bool reinit_glo Globals.ldap_debug_level = 0; Globals.ldap_debug_threshold = 10; + Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN; + /* This is what we tell the afs client. in reality we set the token * to never expire, though, when this runs out the afs client will * forget the token. Set to 0 to get NEVERDATE.*/