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