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