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