CVE-2016-2110: auth/ntlmssp: implement new_spnego support including MIC checking...
[metze/samba/wip.git] / auth / ntlmssp / ntlmssp_server.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    handle NTLMSSP, server side
5
6    Copyright (C) Andrew Tridgell      2001
7    Copyright (C) Andrew Bartlett 2001-2010
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "lib/util/time_basic.h"
25 #include "auth/ntlmssp/ntlmssp.h"
26 #include "auth/ntlmssp/ntlmssp_private.h"
27 #include "../librpc/gen_ndr/ndr_ntlmssp.h"
28 #include "auth/ntlmssp/ntlmssp_ndr.h"
29 #include "../libcli/auth/libcli_auth.h"
30 #include "../lib/crypto/crypto.h"
31 #include "auth/gensec/gensec.h"
32 #include "auth/gensec/gensec_internal.h"
33 #include "auth/common_auth.h"
34
35 /**
36  * Determine correct target name flags for reply, given server role
37  * and negotiated flags
38  *
39  * @param ntlmssp_state NTLMSSP State
40  * @param neg_flags The flags from the packet
41  * @param chal_flags The flags to be set in the reply packet
42  * @return The 'target name' string.
43  */
44
45 const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
46                                 uint32_t neg_flags, uint32_t *chal_flags)
47 {
48         if (neg_flags & NTLMSSP_REQUEST_TARGET) {
49                 *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
50                 *chal_flags |= NTLMSSP_REQUEST_TARGET;
51                 if (ntlmssp_state->server.is_standalone) {
52                         *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
53                         return ntlmssp_state->server.netbios_name;
54                 } else {
55                         *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
56                         return ntlmssp_state->server.netbios_domain;
57                 };
58         } else {
59                 return "";
60         }
61 }
62
63 /**
64  * Next state function for the NTLMSSP Negotiate packet
65  *
66  * @param gensec_security GENSEC state
67  * @param out_mem_ctx Memory context for *out
68  * @param in The request, as a DATA_BLOB.  reply.data must be NULL
69  * @param out The reply, as an allocated DATA_BLOB, caller to free.
70  * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
71  */
72
73 NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security,
74                                          TALLOC_CTX *out_mem_ctx,
75                                          const DATA_BLOB request, DATA_BLOB *reply)
76 {
77         struct gensec_ntlmssp_context *gensec_ntlmssp =
78                 talloc_get_type_abort(gensec_security->private_data,
79                                       struct gensec_ntlmssp_context);
80         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
81         struct auth4_context *auth_context = gensec_security->auth_context;
82         DATA_BLOB struct_blob;
83         uint32_t neg_flags = 0;
84         uint32_t ntlmssp_command, chal_flags;
85         uint8_t cryptkey[8];
86         const char *target_name;
87         NTSTATUS status;
88         struct timeval tv_now = timeval_current();
89         /*
90          * See [MS-NLMP]
91          *
92          * Windows NT 4.0, windows_2000: use 30 minutes,
93          * Windows XP, Windows Server 2003, Windows Vista,
94          * Windows Server 2008, Windows 7, and Windows Server 2008 R2
95          * use 36 hours.
96          *
97          * Newer systems doesn't check this, likely because the
98          * connectionless NTLMSSP is no longer supported.
99          *
100          * As we expect the AUTHENTICATION_MESSAGE to arrive
101          * directly after the NEGOTIATE_MESSAGE (typically less than
102          * as 1 second later). We use a hard timeout of 30 Minutes.
103          *
104          * We don't look at AUTHENTICATE_MESSAGE.NtChallengeResponse.TimeStamp
105          * instead we just remember our own time.
106          */
107         uint32_t max_lifetime = 30 * 60;
108         struct timeval tv_end = timeval_add(&tv_now, max_lifetime, 0);
109
110         /* parse the NTLMSSP packet */
111 #if 0
112         file_save("ntlmssp_negotiate.dat", request.data, request.length);
113 #endif
114
115         if (request.length) {
116                 if (request.length > UINT16_MAX) {
117                         DEBUG(1, ("ntlmssp_server_negotiate: reject large request of length %u\n",
118                                 (unsigned int)request.length));
119                         return NT_STATUS_INVALID_PARAMETER;
120                 }
121
122                 if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd",
123                                                           "NTLMSSP",
124                                                           &ntlmssp_command,
125                                                           &neg_flags)) {
126                         DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
127                                 (unsigned int)request.length));
128                         dump_data(2, request.data, request.length);
129                         return NT_STATUS_INVALID_PARAMETER;
130                 }
131                 debug_ntlmssp_flags(neg_flags);
132
133                 if (DEBUGLEVEL >= 10) {
134                         struct NEGOTIATE_MESSAGE *negotiate = talloc(
135                                 ntlmssp_state, struct NEGOTIATE_MESSAGE);
136                         if (negotiate != NULL) {
137                                 status = ntlmssp_pull_NEGOTIATE_MESSAGE(
138                                         &request, negotiate, negotiate);
139                                 if (NT_STATUS_IS_OK(status)) {
140                                         NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
141                                                         negotiate);
142                                 }
143                                 TALLOC_FREE(negotiate);
144                         }
145                 }
146         }
147
148         status = ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, "negotiate");
149         if (!NT_STATUS_IS_OK(status)){
150                 return status;
151         }
152
153         /* Ask our caller what challenge they would like in the packet */
154         if (auth_context->get_ntlm_challenge) {
155                 status = auth_context->get_ntlm_challenge(auth_context, cryptkey);
156                 if (!NT_STATUS_IS_OK(status)) {
157                         DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
158                                   nt_errstr(status)));
159                         return status;
160                 }
161         } else {
162                 DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
163                 return NT_STATUS_NOT_IMPLEMENTED;
164         }
165
166         /* The flags we send back are not just the negotiated flags,
167          * they are also 'what is in this packet'.  Therfore, we
168          * operate on 'chal_flags' from here on
169          */
170
171         chal_flags = ntlmssp_state->neg_flags;
172         ntlmssp_state->server.challenge_endtime = timeval_to_nttime(&tv_end);
173
174         /* get the right name to fill in as 'target' */
175         target_name = ntlmssp_target_name(ntlmssp_state,
176                                           neg_flags, &chal_flags);
177         if (target_name == NULL)
178                 return NT_STATUS_INVALID_PARAMETER;
179
180         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
181         ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state,
182                                                         cryptkey, 8);
183
184         /* This creates the 'blob' of names that appears at the end of the packet */
185         if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
186                 enum ndr_err_code err;
187                 struct AV_PAIR *pairs = NULL;
188                 uint32_t count = 5;
189
190                 pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count + 1);
191                 if (pairs == NULL) {
192                         return NT_STATUS_NO_MEMORY;
193                 }
194
195                 pairs[0].AvId                   = MsvAvNbDomainName;
196                 pairs[0].Value.AvNbDomainName   = target_name;
197
198                 pairs[1].AvId                   = MsvAvNbComputerName;
199                 pairs[1].Value.AvNbComputerName = ntlmssp_state->server.netbios_name;
200
201                 pairs[2].AvId                   = MsvAvDnsDomainName;
202                 pairs[2].Value.AvDnsDomainName  = ntlmssp_state->server.dns_domain;
203
204                 pairs[3].AvId                   = MsvAvDnsComputerName;
205                 pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name;
206
207                 if (!ntlmssp_state->force_old_spnego) {
208                         pairs[4].AvId                   = MsvAvTimestamp;
209                         pairs[4].Value.AvTimestamp      =
210                                                 timeval_to_nttime(&tv_now);
211                         count += 1;
212
213                         pairs[5].AvId                   = MsvAvEOL;
214                 } else {
215                         pairs[4].AvId                   = MsvAvEOL;
216                 }
217
218                 ntlmssp_state->server.av_pair_list.count = count;
219                 ntlmssp_state->server.av_pair_list.pair = pairs;
220
221                 err = ndr_push_struct_blob(&struct_blob,
222                                         ntlmssp_state,
223                                         &ntlmssp_state->server.av_pair_list,
224                                         (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST);
225                 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
226                         return NT_STATUS_NO_MEMORY;
227                 }
228         } else {
229                 struct_blob = data_blob_null;
230         }
231
232         {
233                 /* Marshal the packet in the right format, be it unicode or ASCII */
234                 const char *gen_string;
235                 const DATA_BLOB version_blob = ntlmssp_version_blob();
236
237                 if (ntlmssp_state->unicode) {
238                         gen_string = "CdUdbddBb";
239                 } else {
240                         gen_string = "CdAdbddBb";
241                 }
242
243                 status = msrpc_gen(out_mem_ctx, reply, gen_string,
244                         "NTLMSSP",
245                         NTLMSSP_CHALLENGE,
246                         target_name,
247                         chal_flags,
248                         cryptkey, 8,
249                         0, 0,
250                         struct_blob.data, struct_blob.length,
251                         version_blob.data, version_blob.length);
252
253                 if (!NT_STATUS_IS_OK(status)) {
254                         data_blob_free(&struct_blob);
255                         return status;
256                 }
257
258                 if (DEBUGLEVEL >= 10) {
259                         struct CHALLENGE_MESSAGE *challenge = talloc(
260                                 ntlmssp_state, struct CHALLENGE_MESSAGE);
261                         if (challenge != NULL) {
262                                 challenge->NegotiateFlags = chal_flags;
263                                 status = ntlmssp_pull_CHALLENGE_MESSAGE(
264                                         reply, challenge, challenge);
265                                 if (NT_STATUS_IS_OK(status)) {
266                                         NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
267                                                         challenge);
268                                 }
269                                 TALLOC_FREE(challenge);
270                         }
271                 }
272         }
273
274         data_blob_free(&struct_blob);
275
276         ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
277                                                              request);
278         if (ntlmssp_state->negotiate_blob.length != request.length) {
279                 return NT_STATUS_NO_MEMORY;
280         }
281
282         ntlmssp_state->challenge_blob = data_blob_dup_talloc(ntlmssp_state,
283                                                              *reply);
284         if (ntlmssp_state->challenge_blob.length != reply->length) {
285                 return NT_STATUS_NO_MEMORY;
286         }
287
288         ntlmssp_state->expected_state = NTLMSSP_AUTH;
289
290         return NT_STATUS_MORE_PROCESSING_REQUIRED;
291 }
292
293 struct ntlmssp_server_auth_state {
294         DATA_BLOB user_session_key;
295         DATA_BLOB lm_session_key;
296         /* internal variables used by KEY_EXCH (client-supplied user session key */
297         DATA_BLOB encrypted_session_key;
298         bool doing_ntlm2;
299         /* internal variables used by NTLM2 */
300         uint8_t session_nonce[16];
301 };
302
303 /**
304  * Next state function for the Authenticate packet
305  *
306  * @param ntlmssp_state NTLMSSP State
307  * @param request The request, as a DATA_BLOB
308  * @return Errors or NT_STATUS_OK.
309  */
310
311 static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
312                                        struct gensec_ntlmssp_context *gensec_ntlmssp,
313                                        struct ntlmssp_server_auth_state *state,
314                                        const DATA_BLOB request)
315 {
316         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
317         struct auth4_context *auth_context = gensec_security->auth_context;
318         uint32_t ntlmssp_command, auth_flags;
319         NTSTATUS nt_status;
320         const unsigned int version_len = 8;
321         DATA_BLOB version_blob = data_blob_null;
322         const unsigned int mic_len = NTLMSSP_MIC_SIZE;
323         DATA_BLOB mic_blob = data_blob_null;
324         uint8_t session_nonce_hash[16];
325         const char *parse_string;
326         bool ok;
327         struct timeval endtime;
328         bool expired = false;
329
330 #if 0
331         file_save("ntlmssp_auth.dat", request.data, request.length);
332 #endif
333
334         if (ntlmssp_state->unicode) {
335                 parse_string = "CdBBUUUBdbb";
336         } else {
337                 parse_string = "CdBBAAABdbb";
338         }
339
340         /* zero these out */
341         data_blob_free(&ntlmssp_state->session_key);
342         data_blob_free(&ntlmssp_state->lm_resp);
343         data_blob_free(&ntlmssp_state->nt_resp);
344
345         ntlmssp_state->user = NULL;
346         ntlmssp_state->domain = NULL;
347         ntlmssp_state->client.netbios_name = NULL;
348
349         /* now the NTLMSSP encoded auth hashes */
350         ok = msrpc_parse(ntlmssp_state, &request, parse_string,
351                          "NTLMSSP",
352                          &ntlmssp_command,
353                          &ntlmssp_state->lm_resp,
354                          &ntlmssp_state->nt_resp,
355                          &ntlmssp_state->domain,
356                          &ntlmssp_state->user,
357                          &ntlmssp_state->client.netbios_name,
358                          &state->encrypted_session_key,
359                          &auth_flags,
360                          &version_blob, version_len,
361                          &mic_blob, mic_len);
362         if (!ok) {
363                 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
364                 dump_data(10, request.data, request.length);
365
366                 data_blob_free(&version_blob);
367                 data_blob_free(&mic_blob);
368
369                 if (ntlmssp_state->unicode) {
370                         parse_string = "CdBBUUUBd";
371                 } else {
372                         parse_string = "CdBBAAABd";
373                 }
374
375                 ok = msrpc_parse(ntlmssp_state, &request, parse_string,
376                                  "NTLMSSP",
377                                  &ntlmssp_command,
378                                  &ntlmssp_state->lm_resp,
379                                  &ntlmssp_state->nt_resp,
380                                  &ntlmssp_state->domain,
381                                  &ntlmssp_state->user,
382                                  &ntlmssp_state->client.netbios_name,
383                                  &state->encrypted_session_key,
384                                  &auth_flags);
385         }
386
387         if (!ok) {
388                 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
389                 dump_data(10, request.data, request.length);
390
391                 /* zero this out */
392                 data_blob_free(&state->encrypted_session_key);
393                 auth_flags = 0;
394
395                 /* Try again with a shorter string (Win9X truncates this packet) */
396                 if (ntlmssp_state->unicode) {
397                         parse_string = "CdBBUUU";
398                 } else {
399                         parse_string = "CdBBAAA";
400                 }
401
402                 /* now the NTLMSSP encoded auth hashes */
403                 if (!msrpc_parse(ntlmssp_state, &request, parse_string,
404                                  "NTLMSSP",
405                                  &ntlmssp_command,
406                                  &ntlmssp_state->lm_resp,
407                                  &ntlmssp_state->nt_resp,
408                                  &ntlmssp_state->domain,
409                                  &ntlmssp_state->user,
410                                  &ntlmssp_state->client.netbios_name)) {
411                         DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
412                         dump_data(2, request.data, request.length);
413
414                         return NT_STATUS_INVALID_PARAMETER;
415                 }
416         }
417
418         talloc_steal(state, state->encrypted_session_key.data);
419
420         if (auth_flags != 0) {
421                 nt_status = ntlmssp_handle_neg_flags(ntlmssp_state,
422                                                      auth_flags,
423                                                      "authenticate");
424                 if (!NT_STATUS_IS_OK(nt_status)){
425                         return nt_status;
426                 }
427         }
428
429         if (DEBUGLEVEL >= 10) {
430                 struct AUTHENTICATE_MESSAGE *authenticate = talloc(
431                         ntlmssp_state, struct AUTHENTICATE_MESSAGE);
432                 if (authenticate != NULL) {
433                         NTSTATUS status;
434                         authenticate->NegotiateFlags = auth_flags;
435                         status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
436                                 &request, authenticate, authenticate);
437                         if (NT_STATUS_IS_OK(status)) {
438                                 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
439                                                 authenticate);
440                         }
441                         TALLOC_FREE(authenticate);
442                 }
443         }
444
445         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
446                  ntlmssp_state->user, ntlmssp_state->domain,
447                  ntlmssp_state->client.netbios_name,
448                  (unsigned long)ntlmssp_state->lm_resp.length,
449                  (unsigned long)ntlmssp_state->nt_resp.length));
450
451 #if 0
452         file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
453         file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
454 #endif
455
456         if (ntlmssp_state->nt_resp.length > 24) {
457                 struct NTLMv2_RESPONSE v2_resp;
458                 enum ndr_err_code err;
459                 uint32_t i = 0;
460                 uint32_t count = 0;
461                 const struct AV_PAIR *flags = NULL;
462                 const struct AV_PAIR *eol = NULL;
463                 uint32_t av_flags = 0;
464
465                 err = ndr_pull_struct_blob(&ntlmssp_state->nt_resp,
466                                         ntlmssp_state,
467                                         &v2_resp,
468                                         (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE);
469                 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
470                         nt_status = ndr_map_error2ntstatus(err);
471                         DEBUG(1,("%s: failed to parse NTLMv2_RESPONSE of length %zu for "
472                                  "user=[%s] domain=[%s] workstation=[%s] - %s %s\n",
473                                  __func__, ntlmssp_state->nt_resp.length,
474                                  ntlmssp_state->user, ntlmssp_state->domain,
475                                  ntlmssp_state->client.netbios_name,
476                                  ndr_errstr(err), nt_errstr(nt_status)));
477                         return nt_status;
478                 }
479
480                 if (DEBUGLVL(10)) {
481                         NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp);
482                 }
483
484                 eol = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
485                                           MsvAvEOL);
486                 if (eol == NULL) {
487                         DEBUG(1,("%s: missing MsvAvEOL for "
488                                  "user=[%s] domain=[%s] workstation=[%s]\n",
489                                  __func__, ntlmssp_state->user, ntlmssp_state->domain,
490                                  ntlmssp_state->client.netbios_name));
491                         return NT_STATUS_INVALID_PARAMETER;
492                 }
493
494                 flags = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
495                                             MsvAvFlags);
496                 if (flags != NULL) {
497                         av_flags = flags->Value.AvFlags;
498                 }
499
500                 if (av_flags & NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE) {
501                         if (mic_blob.length != NTLMSSP_MIC_SIZE) {
502                                 DEBUG(1,("%s: mic_blob.length[%u] for "
503                                          "user=[%s] domain=[%s] workstation=[%s]\n",
504                                          __func__,
505                                          (unsigned)mic_blob.length,
506                                          ntlmssp_state->user,
507                                          ntlmssp_state->domain,
508                                          ntlmssp_state->client.netbios_name));
509                                 return NT_STATUS_INVALID_PARAMETER;
510                         }
511
512                         if (request.length <
513                             (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE))
514                         {
515                                 DEBUG(1,("%s: missing MIC "
516                                          "request.length[%u] for "
517                                          "user=[%s] domain=[%s] workstation=[%s]\n",
518                                          __func__,
519                                          (unsigned)request.length,
520                                          ntlmssp_state->user,
521                                          ntlmssp_state->domain,
522                                          ntlmssp_state->client.netbios_name));
523                                 return NT_STATUS_INVALID_PARAMETER;
524                         }
525
526                         ntlmssp_state->new_spnego = true;
527                 }
528
529                 count = ntlmssp_state->server.av_pair_list.count;
530                 if (v2_resp.Challenge.AvPairs.count < count) {
531                         return NT_STATUS_INVALID_PARAMETER;
532                 }
533
534                 for (i = 0; i < count; i++) {
535                         const struct AV_PAIR *sp =
536                                 &ntlmssp_state->server.av_pair_list.pair[i];
537                         const struct AV_PAIR *cp = NULL;
538
539                         if (sp->AvId == MsvAvEOL) {
540                                 continue;
541                         }
542
543                         cp = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
544                                                  sp->AvId);
545                         if (cp == NULL) {
546                                 DEBUG(1,("%s: AvId 0x%x missing for"
547                                          "user=[%s] domain=[%s] "
548                                          "workstation=[%s]\n",
549                                          __func__,
550                                          (unsigned)sp->AvId,
551                                          ntlmssp_state->user,
552                                          ntlmssp_state->domain,
553                                          ntlmssp_state->client.netbios_name));
554                                 return NT_STATUS_INVALID_PARAMETER;
555                         }
556
557                         switch (cp->AvId) {
558 #define CASE_STRING(v) case Msv ## v: do { \
559         int cmp; \
560         if (sp->Value.v == NULL) { \
561                 return NT_STATUS_INTERNAL_ERROR; \
562         } \
563         if (cp->Value.v == NULL) { \
564                 DEBUG(1,("%s: invalid %s " \
565                          "got[%s] expect[%s] for " \
566                          "user=[%s] domain=[%s] workstation=[%s]\n", \
567                          __func__, #v, \
568                          cp->Value.v, \
569                          sp->Value.v, \
570                          ntlmssp_state->user, \
571                          ntlmssp_state->domain, \
572                          ntlmssp_state->client.netbios_name)); \
573                 return NT_STATUS_INVALID_PARAMETER; \
574         } \
575         cmp = strcmp(cp->Value.v, sp->Value.v); \
576         if (cmp != 0) { \
577                 DEBUG(1,("%s: invalid %s " \
578                          "got[%s] expect[%s] for " \
579                          "user=[%s] domain=[%s] workstation=[%s]\n", \
580                          __func__, #v, \
581                          cp->Value.v, \
582                          sp->Value.v, \
583                          ntlmssp_state->user, \
584                          ntlmssp_state->domain, \
585                          ntlmssp_state->client.netbios_name)); \
586                 return NT_STATUS_INVALID_PARAMETER; \
587         } \
588 } while(0); break
589                         CASE_STRING(AvNbComputerName);
590                         CASE_STRING(AvNbDomainName);
591                         CASE_STRING(AvDnsComputerName);
592                         CASE_STRING(AvDnsDomainName);
593                         CASE_STRING(AvDnsTreeName);
594                         case MsvAvTimestamp:
595                                 if (cp->Value.AvTimestamp != sp->Value.AvTimestamp) {
596                                         struct timeval ct;
597                                         struct timeval st;
598                                         struct timeval_buf tmp1;
599                                         struct timeval_buf tmp2;
600
601                                         nttime_to_timeval(&ct,
602                                                           cp->Value.AvTimestamp);
603                                         nttime_to_timeval(&st,
604                                                           sp->Value.AvTimestamp);
605
606                                         DEBUG(1,("%s: invalid AvTimestamp "
607                                                  "got[%s] expect[%s] for "
608                                                  "user=[%s] domain=[%s] "
609                                                  "workstation=[%s]\n",
610                                                  __func__,
611                                                  timeval_str_buf(&ct, false,
612                                                                  true, &tmp1),
613                                                  timeval_str_buf(&st, false,
614                                                                  true, &tmp2),
615                                                  ntlmssp_state->user,
616                                                  ntlmssp_state->domain,
617                                                  ntlmssp_state->client.netbios_name));
618                                         return NT_STATUS_INVALID_PARAMETER;
619                                 }
620                                 break;
621                         default:
622                                 /*
623                                  * This can't happen as we control
624                                  * ntlmssp_state->server.av_pair_list
625                                  */
626                                 return NT_STATUS_INTERNAL_ERROR;
627                         }
628                 }
629         }
630
631         nttime_to_timeval(&endtime, ntlmssp_state->server.challenge_endtime);
632         expired = timeval_expired(&endtime);
633         if (expired) {
634                 struct timeval_buf tmp;
635                 DEBUG(1,("%s: challenge invalid (expired %s) for "
636                          "user=[%s] domain=[%s] workstation=[%s]\n",
637                          __func__,
638                          timeval_str_buf(&endtime, false, true, &tmp),
639                          ntlmssp_state->user, ntlmssp_state->domain,
640                          ntlmssp_state->client.netbios_name));
641                 return NT_STATUS_INVALID_PARAMETER;
642         }
643
644         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
645            client challenge
646
647            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
648         */
649         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
650                 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
651                         MD5_CTX md5_session_nonce_ctx;
652                         state->doing_ntlm2 = true;
653
654                         memcpy(state->session_nonce, ntlmssp_state->internal_chal.data, 8);
655                         memcpy(&state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
656
657                         SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
658
659                         MD5Init(&md5_session_nonce_ctx);
660                         MD5Update(&md5_session_nonce_ctx, state->session_nonce, 16);
661                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
662
663                         /* LM response is no longer useful */
664                         data_blob_free(&ntlmssp_state->lm_resp);
665
666                         /* We changed the effective challenge - set it */
667                         if (auth_context->set_ntlm_challenge) {
668                                 nt_status = auth_context->set_ntlm_challenge(auth_context,
669                                                                              session_nonce_hash,
670                                                                              "NTLMSSP callback (NTLM2)");
671                                 if (!NT_STATUS_IS_OK(nt_status)) {
672                                         DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
673                                                   nt_errstr(nt_status)));
674                                         return nt_status;
675                                 }
676                         } else {
677                                 DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't have facility for challenge to be set\n"));
678
679                                 return NT_STATUS_NOT_IMPLEMENTED;
680                         }
681
682                         /* LM Key is incompatible. */
683                         ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
684                 }
685         }
686         return NT_STATUS_OK;
687 }
688
689 /**
690  * Check the password on an NTLMSSP login.
691  *
692  * Return the session keys used on the connection.
693  */
694
695 static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_security,
696                                               struct gensec_ntlmssp_context *gensec_ntlmssp,
697                                               TALLOC_CTX *mem_ctx,
698                                               DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
699 {
700         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
701         struct auth4_context *auth_context = gensec_security->auth_context;
702         NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
703         struct auth_usersupplied_info *user_info;
704
705         user_info = talloc_zero(ntlmssp_state, struct auth_usersupplied_info);
706         if (!user_info) {
707                 return NT_STATUS_NO_MEMORY;
708         }
709
710         user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
711         user_info->flags = 0;
712         user_info->mapped_state = false;
713         user_info->client.account_name = ntlmssp_state->user;
714         user_info->client.domain_name = ntlmssp_state->domain;
715         user_info->workstation_name = ntlmssp_state->client.netbios_name;
716         user_info->remote_host = gensec_get_remote_address(gensec_security);
717
718         user_info->password_state = AUTH_PASSWORD_RESPONSE;
719         user_info->password.response.lanman = ntlmssp_state->lm_resp;
720         user_info->password.response.lanman.data = talloc_steal(user_info, ntlmssp_state->lm_resp.data);
721         user_info->password.response.nt = ntlmssp_state->nt_resp;
722         user_info->password.response.nt.data = talloc_steal(user_info, ntlmssp_state->nt_resp.data);
723
724         if (auth_context->check_ntlm_password) {
725                 nt_status = auth_context->check_ntlm_password(auth_context,
726                                                               gensec_ntlmssp,
727                                                               user_info,
728                                                               &gensec_ntlmssp->server_returned_info,
729                                                               user_session_key, lm_session_key);
730         }
731
732         if (!NT_STATUS_IS_OK(nt_status)) {
733                 DEBUG(5, (__location__ ": Checking NTLMSSP password for %s\\%s failed: %s\n", user_info->client.domain_name, user_info->client.account_name, nt_errstr(nt_status)));
734         }
735         TALLOC_FREE(user_info);
736
737         NT_STATUS_NOT_OK_RETURN(nt_status);
738
739         talloc_steal(mem_ctx, user_session_key->data);
740         talloc_steal(mem_ctx, lm_session_key->data);
741
742         return nt_status;
743 }
744
745 /**
746  * Next state function for the Authenticate packet
747  * (after authentication - figures out the session keys etc)
748  *
749  * @param ntlmssp_state NTLMSSP State
750  * @return Errors or NT_STATUS_OK.
751  */
752
753 static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
754                                         struct gensec_ntlmssp_context *gensec_ntlmssp,
755                                         struct ntlmssp_server_auth_state *state,
756                                         DATA_BLOB request)
757 {
758         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
759         DATA_BLOB user_session_key = state->user_session_key;
760         DATA_BLOB lm_session_key = state->lm_session_key;
761         NTSTATUS nt_status = NT_STATUS_OK;
762         DATA_BLOB session_key = data_blob(NULL, 0);
763
764         dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
765         dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
766
767         /* Handle the different session key derivation for NTLM2 */
768         if (state->doing_ntlm2) {
769                 if (user_session_key.data && user_session_key.length == 16) {
770                         session_key = data_blob_talloc(ntlmssp_state,
771                                                        NULL, 16);
772                         hmac_md5(user_session_key.data, state->session_nonce,
773                                  sizeof(state->session_nonce), session_key.data);
774                         DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
775                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
776
777                 } else {
778                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
779                         session_key = data_blob_null;
780                 }
781         } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
782                 /* Ensure we can never get here on NTLMv2 */
783                 && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
784
785                 if (lm_session_key.data && lm_session_key.length >= 8) {
786                         if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
787                                 session_key = data_blob_talloc(ntlmssp_state,
788                                                                NULL, 16);
789                                 if (session_key.data == NULL) {
790                                         return NT_STATUS_NO_MEMORY;
791                                 }
792                                 SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data,
793                                                           session_key.data);
794                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
795                         } else {
796                                 static const uint8_t zeros[24] = {0, };
797                                 session_key = data_blob_talloc(
798                                         ntlmssp_state, NULL, 16);
799                                 if (session_key.data == NULL) {
800                                         return NT_STATUS_NO_MEMORY;
801                                 }
802                                 SMBsesskeygen_lm_sess_key(zeros, zeros,
803                                                           session_key.data);
804                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
805                         }
806                         dump_data_pw("LM session key:\n", session_key.data,
807                                      session_key.length);
808                 } else {
809                         /* LM Key not selected */
810                         ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
811
812                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
813                         session_key = data_blob_null;
814                 }
815
816         } else if (user_session_key.data) {
817                 session_key = user_session_key;
818                 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
819                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
820
821                 /* LM Key not selected */
822                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
823
824         } else if (lm_session_key.data) {
825                 /* Very weird to have LM key, but no user session key, but anyway.. */
826                 session_key = lm_session_key;
827                 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
828                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
829
830                 /* LM Key not selected */
831                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
832
833         } else {
834                 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
835                 session_key = data_blob_null;
836
837                 /* LM Key not selected */
838                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
839         }
840
841         /* With KEY_EXCH, the client supplies the proposed session key,
842            but encrypts it with the long-term key */
843         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
844                 if (!state->encrypted_session_key.data
845                     || state->encrypted_session_key.length != 16) {
846                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
847                                   (unsigned)state->encrypted_session_key.length));
848                         return NT_STATUS_INVALID_PARAMETER;
849                 } else if (!session_key.data || session_key.length != 16) {
850                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
851                                   (unsigned int)session_key.length));
852                         ntlmssp_state->session_key = session_key;
853                         talloc_steal(ntlmssp_state, session_key.data);
854                 } else {
855                         dump_data_pw("KEY_EXCH session key (enc):\n",
856                                      state->encrypted_session_key.data,
857                                      state->encrypted_session_key.length);
858                         arcfour_crypt(state->encrypted_session_key.data,
859                                       session_key.data,
860                                       state->encrypted_session_key.length);
861                         ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
862                                                                       state->encrypted_session_key.data,
863                                                                       state->encrypted_session_key.length);
864                         dump_data_pw("KEY_EXCH session key:\n",
865                                      state->encrypted_session_key.data,
866                                      state->encrypted_session_key.length);
867                 }
868         } else {
869                 ntlmssp_state->session_key = session_key;
870                 talloc_steal(ntlmssp_state, session_key.data);
871         }
872
873         if (ntlmssp_state->new_spnego) {
874                 HMACMD5Context ctx;
875                 uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
876                 int cmp;
877
878                 hmac_md5_init_limK_to_64(ntlmssp_state->session_key.data,
879                                          ntlmssp_state->session_key.length,
880                                          &ctx);
881
882                 hmac_md5_update(ntlmssp_state->negotiate_blob.data,
883                                 ntlmssp_state->negotiate_blob.length,
884                                 &ctx);
885                 hmac_md5_update(ntlmssp_state->challenge_blob.data,
886                                 ntlmssp_state->challenge_blob.length,
887                                 &ctx);
888
889                 /* checked were we set ntlmssp_state->new_spnego */
890                 SMB_ASSERT(request.length >
891                            (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
892
893                 hmac_md5_update(request.data, NTLMSSP_MIC_OFFSET, &ctx);
894                 hmac_md5_update(mic_buffer, NTLMSSP_MIC_SIZE, &ctx);
895                 hmac_md5_update(request.data +
896                                 (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE),
897                                 request.length -
898                                 (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE),
899                                 &ctx);
900                 hmac_md5_final(mic_buffer, &ctx);
901
902                 cmp = memcmp(request.data + NTLMSSP_MIC_OFFSET,
903                              mic_buffer, NTLMSSP_MIC_SIZE);
904                 if (cmp != 0) {
905                         DEBUG(1,("%s: invalid NTLMSSP_MIC for "
906                                  "user=[%s] domain=[%s] workstation=[%s]\n",
907                                  __func__,
908                                  ntlmssp_state->user,
909                                  ntlmssp_state->domain,
910                                  ntlmssp_state->client.netbios_name));
911                         dump_data(1, request.data + NTLMSSP_MIC_OFFSET,
912                                   NTLMSSP_MIC_SIZE);
913                         dump_data(1, mic_buffer,
914                                   NTLMSSP_MIC_SIZE);
915                         return NT_STATUS_INVALID_PARAMETER;
916                 }
917         }
918
919         data_blob_free(&ntlmssp_state->negotiate_blob);
920         data_blob_free(&ntlmssp_state->challenge_blob);
921
922         if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
923                 nt_status = ntlmssp_sign_init(ntlmssp_state);
924         }
925
926         ntlmssp_state->expected_state = NTLMSSP_DONE;
927
928         return nt_status;
929 }
930
931
932 /**
933  * Next state function for the NTLMSSP Authenticate packet
934  *
935  * @param gensec_security GENSEC state
936  * @param out_mem_ctx Memory context for *out
937  * @param in The request, as a DATA_BLOB.  reply.data must be NULL
938  * @param out The reply, as an allocated DATA_BLOB, caller to free.
939  * @return Errors or NT_STATUS_OK if authentication sucessful
940  */
941
942 NTSTATUS gensec_ntlmssp_server_auth(struct gensec_security *gensec_security,
943                                     TALLOC_CTX *out_mem_ctx,
944                                     const DATA_BLOB in, DATA_BLOB *out)
945 {
946         struct gensec_ntlmssp_context *gensec_ntlmssp =
947                 talloc_get_type_abort(gensec_security->private_data,
948                                       struct gensec_ntlmssp_context);
949         struct ntlmssp_server_auth_state *state;
950         NTSTATUS nt_status;
951
952         /* zero the outbound NTLMSSP packet */
953         *out = data_blob_null;
954
955         state = talloc_zero(gensec_ntlmssp, struct ntlmssp_server_auth_state);
956         if (state == NULL) {
957                 return NT_STATUS_NO_MEMORY;
958         }
959
960         nt_status = ntlmssp_server_preauth(gensec_security, gensec_ntlmssp, state, in);
961         if (!NT_STATUS_IS_OK(nt_status)) {
962                 TALLOC_FREE(state);
963                 return nt_status;
964         }
965
966         /*
967          * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
968          * is required (by "ntlm auth = no" and "lm auth = no" being set in the
969          * smb.conf file) and no NTLMv2 response was sent then the password check
970          * will fail here. JRA.
971          */
972
973         /* Finally, actually ask if the password is OK */
974         nt_status = ntlmssp_server_check_password(gensec_security, gensec_ntlmssp,
975                                                   state,
976                                                   &state->user_session_key,
977                                                   &state->lm_session_key);
978         if (!NT_STATUS_IS_OK(nt_status)) {
979                 TALLOC_FREE(state);
980                 return nt_status;
981         }
982
983         /* When we get more async in the auth code behind
984            ntlmssp_state->check_password, the ntlmssp_server_postpath
985            can be done in a callback */
986
987         nt_status = ntlmssp_server_postauth(gensec_security, gensec_ntlmssp, state, in);
988         TALLOC_FREE(state);
989         return nt_status;
990 }