1From 126e3e992bed7174d60ee19212db9b717647ab2e Mon Sep 17 00:00:00 2001
2From: Andreas Schneider <asn@cryptomilk.org>
3Date: Wed, 30 Mar 2016 16:55:44 +0200
4Subject: [PATCH 1/3] CVE-2016-2112: s3:ntlmssp: Implement missing
5 ntlmssp_have_feature()
6
7Signed-off-by: Andreas Schneider <asn@samba.org>
8---
9 source3/include/proto.h  |  1 +
10 source3/libsmb/ntlmssp.c | 30 ++++++++++++++++++++++++++++++
11 2 files changed, 31 insertions(+)
12
13--- a/source3/include/proto.h
14+++ b/source3/include/proto.h
15@@ -1260,6 +1260,7 @@ NTSTATUS ntlmssp_set_password(struct ntl
16 NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) ;
17 void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list);
18 void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature);
19+bool ntlmssp_have_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature);
20 NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
21 			const DATA_BLOB in, DATA_BLOB *out) ;
22 NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx,
23--- a/source3/libsmb/ntlmssp.c
24+++ b/source3/libsmb/ntlmssp.c
25@@ -162,6 +162,36 @@ NTSTATUS ntlmssp_set_domain(struct ntlms
26 	return NT_STATUS_OK;
27 }
28 
29+bool ntlmssp_have_feature(struct ntlmssp_state *ntlmssp_state,
30+			  uint32_t feature)
31+{
32+	if (feature & NTLMSSP_FEATURE_SIGN) {
33+		if (ntlmssp_state->session_key.length == 0) {
34+			return false;
35+		}
36+		if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
37+			return true;
38+		}
39+	}
40+
41+	if (feature & NTLMSSP_FEATURE_SEAL) {
42+		if (ntlmssp_state->session_key.length == 0) {
43+			return false;
44+		}
45+		if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
46+			return true;
47+		}
48+	}
49+
50+	if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
51+		if (ntlmssp_state->session_key.length > 0) {
52+			return true;
53+		}
54+	}
55+
56+	return false;
57+}
58+
59 /**
60  * Request features for the NTLMSSP negotiation
61  *
62--- a/source3/libads/sasl.c
63+++ b/source3/libads/sasl.c
64@@ -261,6 +261,37 @@ static ADS_STATUS ads_sasl_spnego_ntlmss
65 	/* we have a reference conter on ntlmssp_state, if we are signing
66 	   then the state will be kept by the signing engine */
67 
68+	if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SEAL) {
69+		bool ok;
70+
71+		ok = ntlmssp_have_feature(ntlmssp_state,
72+					  NTLMSSP_FEATURE_SEAL);
73+		if (!ok) {
74+			DEBUG(0,("The ntlmssp feature sealing request, but unavailable\n"));
75+			TALLOC_FREE(ntlmssp_state);
76+			return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
77+		}
78+
79+		ok = ntlmssp_have_feature(ntlmssp_state,
80+					  NTLMSSP_FEATURE_SIGN);
81+		if (!ok) {
82+			DEBUG(0,("The ntlmssp feature signing request, but unavailable\n"));
83+			TALLOC_FREE(ntlmssp_state);
84+			return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
85+		}
86+
87+	} else if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SIGN) {
88+		bool ok;
89+
90+		ok = ntlmssp_have_feature(ntlmssp_state,
91+					  NTLMSSP_FEATURE_SIGN);
92+		if (!ok) {
93+			DEBUG(0,("The gensec feature signing request, but unavailable\n"));
94+			TALLOC_FREE(ntlmssp_state);
95+			return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
96+		}
97+	}
98+
99 	if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
100 		ads->ldap.out.max_unwrapped = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED - NTLMSSP_SIG_SIZE;
101 		ads->ldap.out.sig_size = NTLMSSP_SIG_SIZE;
102--- a/docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml
103+++ b/docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml
104@@ -34,11 +34,9 @@
105 	</para>
106 
107 	<para>
108-	The default value is <emphasis>plain</emphasis> which is not irritable 
109-	to KRB5 clock skew errors. That implies synchronizing the time
110-	with the KDC in the case of using <emphasis>sign</emphasis> or 
111-	<emphasis>seal</emphasis>.
112+	The default value is <emphasis>sign</emphasis>. That implies synchronizing the time
113+	with the KDC in the case of using <emphasis>Kerberos</emphasis>.
114 	</para>
115 </description>
116-<value type="default">plain</value>
117+<value type="default">sign</value>
118 </samba:parameter>
119--- a/source3/param/loadparm.c
120+++ b/source3/param/loadparm.c
121@@ -5392,6 +5392,8 @@ static void init_globals(bool reinit_glo
122 	Globals.ldap_debug_level = 0;
123 	Globals.ldap_debug_threshold = 10;
124 
125+	Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
126+
127 	/* This is what we tell the afs client. in reality we set the token 
128 	 * to never expire, though, when this runs out the afs client will 
129 	 * forget the token. Set to 0 to get NEVERDATE.*/
130