CC: samba: fix some security problems
[15.05/openwrt.git] / package / network / services / samba36 / patches / 023-CVE-2016-2110-v3-6.patch
1 From 202d69267c8550b850438877fb51c3d2c992949d Mon Sep 17 00:00:00 2001
2 From: Stefan Metzmacher <metze@samba.org>
3 Date: Tue, 1 Dec 2015 08:46:45 +0100
4 Subject: [PATCH 01/10] CVE-2016-2110: s3:ntlmssp: set and use
5  ntlmssp_state->allow_lm_key
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
9
10 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
11
12 Signed-off-by: Stefan Metzmacher <metze@samba.org>
13 Reviewed-by: Günther Deschner <gd@samba.org>
14 ---
15  source3/libsmb/ntlmssp.c | 4 +++-
16  1 file changed, 3 insertions(+), 1 deletion(-)
17
18 --- a/source3/libsmb/ntlmssp.c
19 +++ b/source3/libsmb/ntlmssp.c
20 @@ -176,17 +176,19 @@ void ntlmssp_want_feature_list(struct nt
21          * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
22          */
23         if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) {
24 -               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
25 +               ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
26         }
27         if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) {
28 -               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
29 +               ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
30         }
31         if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) {
32 -               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
33 +               ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
34         }
35         if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) {
36                 ntlmssp_state->use_ccache = true;
37         }
38 +
39 +       ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
40  }
41  
42  /**
43 @@ -199,17 +201,20 @@ void ntlmssp_want_feature(struct ntlmssp
44  {
45         /* As per JRA's comment above */
46         if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
47 -               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
48 +               ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
49         }
50         if (feature & NTLMSSP_FEATURE_SIGN) {
51 -               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
52 +               ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
53         }
54         if (feature & NTLMSSP_FEATURE_SEAL) {
55 -               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
56 +               ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
57 +               ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
58         }
59         if (feature & NTLMSSP_FEATURE_CCACHE) {
60                 ntlmssp_state->use_ccache = true;
61         }
62 +
63 +       ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
64  }
65  
66  /**
67 @@ -387,7 +392,12 @@ static NTSTATUS ntlmssp_client_initial(s
68         }
69  
70         if (ntlmssp_state->use_ntlmv2) {
71 -               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
72 +               ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2;
73 +               ntlmssp_state->allow_lm_key = false;
74 +       }
75 +
76 +       if (ntlmssp_state->allow_lm_key) {
77 +               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
78         }
79  
80         /* generate the ntlmssp negotiate packet */
81 @@ -422,6 +432,86 @@ static NTSTATUS ntlmssp_client_initial(s
82         return NT_STATUS_MORE_PROCESSING_REQUIRED;
83  }
84  
85 +static NTSTATUS ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
86 +                                         uint32_t flags)
87 +{
88 +       uint32_t missing_flags = ntlmssp_state->required_flags;
89 +
90 +       if (flags & NTLMSSP_NEGOTIATE_UNICODE) {
91 +               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
92 +               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
93 +               ntlmssp_state->unicode = true;
94 +       } else {
95 +               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
96 +               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
97 +               ntlmssp_state->unicode = false;
98 +       }
99 +
100 +       /*
101 +        * NTLMSSP_NEGOTIATE_NTLM2 (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY)
102 +        * has priority over NTLMSSP_NEGOTIATE_LM_KEY
103 +        */
104 +       if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) {
105 +               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
106 +       }
107 +
108 +       if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
109 +               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
110 +       }
111 +
112 +       if (!(flags & NTLMSSP_NEGOTIATE_LM_KEY)) {
113 +               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
114 +       }
115 +
116 +       if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
117 +               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
118 +       }
119 +
120 +       if (!(flags & NTLMSSP_NEGOTIATE_128)) {
121 +               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
122 +       }
123 +
124 +       if (!(flags & NTLMSSP_NEGOTIATE_56)) {
125 +               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
126 +       }
127 +
128 +       if (!(flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
129 +               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
130 +       }
131 +
132 +       if (!(flags & NTLMSSP_NEGOTIATE_SIGN)) {
133 +               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
134 +       }
135 +
136 +       if (!(flags & NTLMSSP_NEGOTIATE_SEAL)) {
137 +               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
138 +       }
139 +
140 +       if ((flags & NTLMSSP_REQUEST_TARGET)) {
141 +               ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
142 +       }
143 +
144 +       missing_flags &= ~ntlmssp_state->neg_flags;
145 +       if (missing_flags != 0) {
146 +               NTSTATUS status = NT_STATUS_RPC_SEC_PKG_ERROR;
147 +               DEBUG(1, ("%s: Got challenge flags[0x%08x] "
148 +                         "- possible downgrade detected! "
149 +                         "missing_flags[0x%08x] - %s\n",
150 +                         __func__,
151 +                         (unsigned)flags,
152 +                         (unsigned)missing_flags,
153 +                         nt_errstr(status)));
154 +               debug_ntlmssp_flags(missing_flags);
155 +               DEBUGADD(4, ("neg_flags[0x%08x]\n",
156 +                            (unsigned)ntlmssp_state->neg_flags));
157 +               debug_ntlmssp_flags(ntlmssp_state->neg_flags);
158 +
159 +               return status;
160 +       }
161 +
162 +       return NT_STATUS_OK;
163 +}
164 +
165  /**
166   * Next state function for the Challenge Packet.  Generate an auth packet.
167   *
168 @@ -448,6 +538,26 @@ static NTSTATUS ntlmssp_client_challenge
169         DATA_BLOB encrypted_session_key = data_blob_null;
170         NTSTATUS nt_status = NT_STATUS_OK;
171  
172 +       if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
173 +                        "NTLMSSP",
174 +                        &ntlmssp_command,
175 +                        &server_domain_blob,
176 +                        &chal_flags)) {
177 +               DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
178 +               dump_data(2, reply.data, reply.length);
179 +
180 +               return NT_STATUS_INVALID_PARAMETER;
181 +       }
182 +       data_blob_free(&server_domain_blob);
183 +
184 +       DEBUG(3, ("Got challenge flags:\n"));
185 +       debug_ntlmssp_flags(chal_flags);
186 +
187 +       nt_status = ntlmssp3_handle_neg_flags(ntlmssp_state, chal_flags);
188 +       if (!NT_STATUS_IS_OK(nt_status)) {
189 +               return nt_status;
190 +       }
191 +
192         if (ntlmssp_state->use_ccache) {
193                 struct wbcCredentialCacheParams params;
194                 struct wbcCredentialCacheInfo *info = NULL;
195 @@ -498,17 +608,6 @@ static NTSTATUS ntlmssp_client_challenge
196  
197  noccache:
198  
199 -       if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
200 -                        "NTLMSSP",
201 -                        &ntlmssp_command,
202 -                        &server_domain_blob,
203 -                        &chal_flags)) {
204 -               DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
205 -               dump_data(2, reply.data, reply.length);
206 -
207 -               return NT_STATUS_INVALID_PARAMETER;
208 -       }
209 -
210         if (DEBUGLEVEL >= 10) {
211                 struct CHALLENGE_MESSAGE *challenge = talloc(
212                         talloc_tos(), struct CHALLENGE_MESSAGE);
213 @@ -525,13 +624,6 @@ noccache:
214                 }
215         }
216  
217 -       data_blob_free(&server_domain_blob);
218 -
219 -       DEBUG(3, ("Got challenge flags:\n"));
220 -       debug_ntlmssp_flags(chal_flags);
221 -
222 -       ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
223 -
224         if (ntlmssp_state->unicode) {
225                 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
226                         chal_parse_string = "CdUdbddB";
227 @@ -769,6 +861,7 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX
228         ntlmssp_state->unicode = True;
229  
230         ntlmssp_state->use_ntlmv2 = use_ntlmv2;
231 +       ntlmssp_state->allow_lm_key = lp_client_lanman_auth();
232  
233         ntlmssp_state->expected_state = NTLMSSP_INITIAL;
234  
235 @@ -780,6 +873,10 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX
236                 NTLMSSP_NEGOTIATE_KEY_EXCH |
237                 NTLMSSP_REQUEST_TARGET;
238  
239 +       if (ntlmssp_state->use_ntlmv2) {
240 +               ntlmssp_state->allow_lm_key = false;
241 +       }
242 +
243         ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
244         if (!ntlmssp_state->client.netbios_name) {
245                 talloc_free(ntlmssp_state);
246 --- a/libcli/auth/ntlmssp.h
247 +++ b/libcli/auth/ntlmssp.h
248 @@ -83,6 +83,7 @@ struct ntlmssp_state
249         DATA_BLOB nt_resp;
250         DATA_BLOB session_key;
251  
252 +       uint32_t required_flags;
253         uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */
254  
255         /**