s3:ntlmssp Split the NTLMSSP server into before and after authentication
[amitay/samba.git] / source3 / libsmb / ntlmssp.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    handle NLTMSSP, server side
5
6    Copyright (C) Andrew Tridgell      2001
7    Copyright (C) Andrew Bartlett 2001-2010
8    Copyright (C) Stefan Metzmacher 2005
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "../libcli/auth/ntlmssp.h"
26 #include "../libcli/auth/ntlmssp_private.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../librpc/gen_ndr/ndr_ntlmssp.h"
29 #include "../libcli/auth/ntlmssp_ndr.h"
30 #include "../lib/crypto/md5.h"
31 #include "../lib/crypto/arcfour.h"
32 #include "../lib/crypto/hmacmd5.h"
33
34 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
35                                        TALLOC_CTX *out_mem_ctx, /* Unused at this time */
36                                        DATA_BLOB reply, DATA_BLOB *next_request);
37 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
38                                          TALLOC_CTX *out_mem_ctx,
39                                          const DATA_BLOB in, DATA_BLOB *out);
40 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
41                                          TALLOC_CTX *out_mem_ctx, /* Unused at this time */
42                                          const DATA_BLOB reply, DATA_BLOB *next_request);
43 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
44                                     TALLOC_CTX *out_mem_ctx,
45                                     const DATA_BLOB request, DATA_BLOB *reply);
46
47 /**
48  * Callbacks for NTLMSSP - for both client and server operating modes
49  *
50  */
51
52 static const struct ntlmssp_callbacks {
53         enum ntlmssp_role role;
54         enum ntlmssp_message_type ntlmssp_command;
55         NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state,
56                        TALLOC_CTX *out_mem_ctx,
57                        DATA_BLOB in, DATA_BLOB *out);
58 } ntlmssp_callbacks[] = {
59         {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},
60         {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},
61         {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},
62         {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},
63         {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
64         {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
65 };
66
67
68 /**
69  * Default challenge generation code.
70  *
71  */
72
73 static NTSTATUS get_challenge(const struct ntlmssp_state *ntlmssp_state,
74                               uint8_t chal[8])
75 {
76         generate_random_buffer(chal, 8);
77         return NT_STATUS_OK;
78 }
79
80 /**
81  * Default 'we can set the challenge to anything we like' implementation
82  *
83  */
84
85 static bool may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
86 {
87         return True;
88 }
89
90 /**
91  * Default 'we can set the challenge to anything we like' implementation
92  *
93  * Does not actually do anything, as the value is always in the structure anyway.
94  *
95  */
96
97 static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
98 {
99         SMB_ASSERT(challenge->length == 8);
100         return NT_STATUS_OK;
101 }
102
103 /**
104  * Set a username on an NTLMSSP context - ensures it is talloc()ed
105  *
106  */
107
108 NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user)
109 {
110         ntlmssp_state->user = talloc_strdup(ntlmssp_state, user ? user : "" );
111         if (!ntlmssp_state->user) {
112                 return NT_STATUS_NO_MEMORY;
113         }
114         return NT_STATUS_OK;
115 }
116
117 /**
118  * Store NT and LM hashes on an NTLMSSP context - ensures they are talloc()ed
119  *
120  */
121 NTSTATUS ntlmssp_set_hashes(struct ntlmssp_state *ntlmssp_state,
122                             const uint8_t lm_hash[16],
123                             const uint8_t nt_hash[16])
124 {
125         ntlmssp_state->lm_hash = (uint8_t *)
126                 TALLOC_MEMDUP(ntlmssp_state, lm_hash, 16);
127         ntlmssp_state->nt_hash = (uint8_t *)
128                 TALLOC_MEMDUP(ntlmssp_state, nt_hash, 16);
129         if (!ntlmssp_state->lm_hash || !ntlmssp_state->nt_hash) {
130                 TALLOC_FREE(ntlmssp_state->lm_hash);
131                 TALLOC_FREE(ntlmssp_state->nt_hash);
132                 return NT_STATUS_NO_MEMORY;
133         }
134         return NT_STATUS_OK;
135 }
136
137 /**
138  * Converts a password to the hashes on an NTLMSSP context.
139  *
140  */
141 NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password)
142 {
143         if (!password) {
144                 ntlmssp_state->lm_hash = NULL;
145                 ntlmssp_state->nt_hash = NULL;
146         } else {
147                 uint8_t lm_hash[16];
148                 uint8_t nt_hash[16];
149
150                 E_deshash(password, lm_hash);
151                 E_md4hash(password, nt_hash);
152                 return ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash);
153         }
154         return NT_STATUS_OK;
155 }
156
157 /**
158  * Set a domain on an NTLMSSP context - ensures it is talloc()ed
159  *
160  */
161 NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain)
162 {
163         ntlmssp_state->domain = talloc_strdup(ntlmssp_state,
164                                               domain ? domain : "" );
165         if (!ntlmssp_state->domain) {
166                 return NT_STATUS_NO_MEMORY;
167         }
168         return NT_STATUS_OK;
169 }
170
171 /**
172  * Request features for the NTLMSSP negotiation
173  *
174  * @param ntlmssp_state NTLMSSP state
175  * @param feature_list List of space seperated features requested from NTLMSSP.
176  */
177 void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list)
178 {
179         /*
180          * We need to set this to allow a later SetPassword
181          * via the SAMR pipe to succeed. Strange.... We could
182          * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
183          */
184         if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) {
185                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
186         }
187         if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) {
188                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
189         }
190         if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) {
191                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
192         }
193         if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) {
194                 ntlmssp_state->use_ccache = true;
195         }
196 }
197
198 /**
199  * Request a feature for the NTLMSSP negotiation
200  *
201  * @param ntlmssp_state NTLMSSP state
202  * @param feature Bit flag specifying the requested feature
203  */
204 void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature)
205 {
206         /* As per JRA's comment above */
207         if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
208                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
209         }
210         if (feature & NTLMSSP_FEATURE_SIGN) {
211                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
212         }
213         if (feature & NTLMSSP_FEATURE_SEAL) {
214                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
215         }
216         if (feature & NTLMSSP_FEATURE_CCACHE) {
217                 ntlmssp_state->use_ccache = true;
218         }
219 }
220
221 /**
222  * Next state function for the NTLMSSP state machine
223  *
224  * @param ntlmssp_state NTLMSSP State
225  * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
226  * @param out The reply, as an allocated DATA_BLOB, caller to free.
227  * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK.
228  */
229
230 NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
231                         const DATA_BLOB input, DATA_BLOB *out)
232 {
233         uint32_t ntlmssp_command;
234         int i;
235
236         if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
237                 /* Called update after negotiations finished. */
238                 DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n"));
239                 return NT_STATUS_INVALID_PARAMETER;
240         }
241
242         *out = data_blob_null;
243
244         if (!input.length) {
245                 switch (ntlmssp_state->role) {
246                 case NTLMSSP_CLIENT:
247                         ntlmssp_command = NTLMSSP_INITIAL;
248                         break;
249                 case NTLMSSP_SERVER:
250                         /* 'datagram' mode - no neg packet */
251                         ntlmssp_command = NTLMSSP_NEGOTIATE;
252                         break;
253                 }
254         } else {
255                 if (!msrpc_parse(ntlmssp_state, &input, "Cd",
256                                  "NTLMSSP",
257                                  &ntlmssp_command)) {
258                         DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
259                         dump_data(2, input.data, input.length);
260                         return NT_STATUS_INVALID_PARAMETER;
261                 }
262         }
263
264         if (ntlmssp_command != ntlmssp_state->expected_state) {
265                 DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
266                 return NT_STATUS_INVALID_PARAMETER;
267         }
268
269         for (i=0; ntlmssp_callbacks[i].fn; i++) {
270                 if (ntlmssp_callbacks[i].role == ntlmssp_state->role
271                     && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) {
272                         return ntlmssp_callbacks[i].fn(ntlmssp_state, ntlmssp_state, input, out);
273                 }
274         }
275
276         DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n",
277                   ntlmssp_state->role, ntlmssp_command));
278
279         return NT_STATUS_INVALID_PARAMETER;
280 }
281
282 /**
283  * Next state function for the Negotiate packet
284  *
285  * @param ntlmssp_state NTLMSSP state
286  * @param out_mem_ctx Memory context for *out
287  * @param in The request, as a DATA_BLOB.  reply.data must be NULL
288  * @param out The reply, as an allocated DATA_BLOB, caller to free.
289  * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
290  */
291
292 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
293                                          TALLOC_CTX *out_mem_ctx,
294                                          const DATA_BLOB request, DATA_BLOB *reply)
295 {
296         DATA_BLOB struct_blob;
297         uint32_t neg_flags = 0;
298         uint32_t ntlmssp_command, chal_flags;
299         uint8_t cryptkey[8];
300         const char *target_name;
301         NTSTATUS status;
302
303         /* parse the NTLMSSP packet */
304 #if 0
305         file_save("ntlmssp_negotiate.dat", request.data, request.length);
306 #endif
307
308         if (request.length) {
309                 if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd",
310                                                           "NTLMSSP",
311                                                           &ntlmssp_command,
312                                                           &neg_flags)) {
313                         DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
314                                 (unsigned int)request.length));
315                         dump_data(2, request.data, request.length);
316                         return NT_STATUS_INVALID_PARAMETER;
317                 }
318                 debug_ntlmssp_flags(neg_flags);
319
320                 if (DEBUGLEVEL >= 10) {
321                         struct NEGOTIATE_MESSAGE *negotiate = talloc(
322                                 ntlmssp_state, struct NEGOTIATE_MESSAGE);
323                         if (negotiate != NULL) {
324                                 status = ntlmssp_pull_NEGOTIATE_MESSAGE(
325                                         &request, negotiate, negotiate);
326                                 if (NT_STATUS_IS_OK(status)) {
327                                         NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
328                                                         negotiate);
329                                 }
330                                 TALLOC_FREE(negotiate);
331                         }
332                 }
333         }
334
335         ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key);
336
337         /* Ask our caller what challenge they would like in the packet */
338         status = ntlmssp_state->get_challenge(ntlmssp_state, cryptkey);
339         if (!NT_STATUS_IS_OK(status)) {
340                 DEBUG(1, ("ntlmssp_server_negotiate: backend doesn't give a challenge: %s\n",
341                           nt_errstr(status)));
342                 return status;
343         }
344
345         /* Check if we may set the challenge */
346         if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
347                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
348         }
349
350         /* The flags we send back are not just the negotiated flags,
351          * they are also 'what is in this packet'.  Therfore, we
352          * operate on 'chal_flags' from here on
353          */
354
355         chal_flags = ntlmssp_state->neg_flags;
356
357         /* get the right name to fill in as 'target' */
358         target_name = ntlmssp_target_name(ntlmssp_state,
359                                           neg_flags, &chal_flags);
360         if (target_name == NULL)
361                 return NT_STATUS_INVALID_PARAMETER;
362
363         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
364         ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state,
365                                                         cryptkey, 8);
366
367         /* This creates the 'blob' of names that appears at the end of the packet */
368         if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO)
369         {
370                 msrpc_gen(ntlmssp_state, &struct_blob, "aaaaa",
371                           MsvAvNbDomainName, target_name,
372                           MsvAvNbComputerName, ntlmssp_state->server.netbios_name,
373                           MsvAvDnsDomainName, ntlmssp_state->server.dns_domain,
374                           MsvAvDnsComputerName, ntlmssp_state->server.dns_name,
375                           MsvAvEOL, "");
376         } else {
377                 struct_blob = data_blob_null;
378         }
379
380         {
381                 /* Marshal the packet in the right format, be it unicode or ASCII */
382                 const char *gen_string;
383                 DATA_BLOB version_blob = data_blob_null;
384
385                 if (chal_flags & NTLMSSP_NEGOTIATE_VERSION) {
386                         enum ndr_err_code err;
387                         struct VERSION vers;
388
389                         /* "What Windows returns" as a version number. */
390                         ZERO_STRUCT(vers);
391                         vers.ProductMajorVersion = NTLMSSP_WINDOWS_MAJOR_VERSION_6;
392                         vers.ProductMinorVersion = NTLMSSP_WINDOWS_MINOR_VERSION_1;
393                         vers.ProductBuild = 0;
394                         vers.NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3;
395
396                         err = ndr_push_struct_blob(&version_blob,
397                                                 ntlmssp_state,
398                                                 &vers,
399                                                 (ndr_push_flags_fn_t)ndr_push_VERSION);
400
401                         if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
402                                 data_blob_free(&struct_blob);
403                                 return NT_STATUS_NO_MEMORY;
404                         }
405                 }
406
407                 if (ntlmssp_state->unicode) {
408                         gen_string = "CdUdbddBb";
409                 } else {
410                         gen_string = "CdAdbddBb";
411                 }
412
413                 msrpc_gen(out_mem_ctx, reply, gen_string,
414                         "NTLMSSP",
415                         NTLMSSP_CHALLENGE,
416                         target_name,
417                         chal_flags,
418                         cryptkey, 8,
419                         0, 0,
420                         struct_blob.data, struct_blob.length,
421                         version_blob.data, version_blob.length);
422
423                 data_blob_free(&version_blob);
424
425                 if (DEBUGLEVEL >= 10) {
426                         struct CHALLENGE_MESSAGE *challenge = talloc(
427                                 ntlmssp_state, struct CHALLENGE_MESSAGE);
428                         if (challenge != NULL) {
429                                 challenge->NegotiateFlags = chal_flags;
430                                 status = ntlmssp_pull_CHALLENGE_MESSAGE(
431                                         reply, challenge, challenge);
432                                 if (NT_STATUS_IS_OK(status)) {
433                                         NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
434                                                         challenge);
435                                 }
436                                 TALLOC_FREE(challenge);
437                         }
438                 }
439         }
440
441         data_blob_free(&struct_blob);
442
443         ntlmssp_state->expected_state = NTLMSSP_AUTH;
444
445         return NT_STATUS_MORE_PROCESSING_REQUIRED;
446 }
447
448 struct ntlmssp_server_auth_state {
449         DATA_BLOB user_session_key;
450         DATA_BLOB lm_session_key;
451         /* internal variables used by KEY_EXCH (client-supplied user session key */
452         DATA_BLOB encrypted_session_key;
453         bool doing_ntlm2;
454         /* internal variables used by NTLM2 */
455         uint8_t session_nonce[16];
456 };
457
458 /**
459  * Next state function for the Authenticate packet
460  *
461  * @param ntlmssp_state NTLMSSP State
462  * @param request The request, as a DATA_BLOB
463  * @return Errors or NT_STATUS_OK.
464  */
465
466 static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state,
467                                        struct ntlmssp_server_auth_state *state,
468                                        const DATA_BLOB request)
469 {
470         uint32_t ntlmssp_command, auth_flags;
471         NTSTATUS nt_status;
472
473         uint8_t session_nonce_hash[16];
474
475         const char *parse_string;
476
477 #if 0
478         file_save("ntlmssp_auth.dat", request.data, request.length);
479 #endif
480
481         if (ntlmssp_state->unicode) {
482                 parse_string = "CdBBUUUBd";
483         } else {
484                 parse_string = "CdBBAAABd";
485         }
486
487         /* zero these out */
488         data_blob_free(&ntlmssp_state->session_key);
489         data_blob_free(&ntlmssp_state->lm_resp);
490         data_blob_free(&ntlmssp_state->nt_resp);
491
492         ntlmssp_state->user = NULL;
493         ntlmssp_state->domain = NULL;
494         ntlmssp_state->client.netbios_name = NULL;
495
496         /* now the NTLMSSP encoded auth hashes */
497         if (!msrpc_parse(ntlmssp_state, &request, parse_string,
498                          "NTLMSSP",
499                          &ntlmssp_command,
500                          &ntlmssp_state->lm_resp,
501                          &ntlmssp_state->nt_resp,
502                          &ntlmssp_state->domain,
503                          &ntlmssp_state->user,
504                          &ntlmssp_state->client.netbios_name,
505                          &state->encrypted_session_key,
506                          &auth_flags)) {
507                 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
508                 dump_data(10, request.data, request.length);
509
510                 /* zero this out */
511                 data_blob_free(&state->encrypted_session_key);
512                 auth_flags = 0;
513
514                 /* Try again with a shorter string (Win9X truncates this packet) */
515                 if (ntlmssp_state->unicode) {
516                         parse_string = "CdBBUUU";
517                 } else {
518                         parse_string = "CdBBAAA";
519                 }
520
521                 /* now the NTLMSSP encoded auth hashes */
522                 if (!msrpc_parse(ntlmssp_state, &request, parse_string,
523                                  "NTLMSSP",
524                                  &ntlmssp_command,
525                                  &ntlmssp_state->lm_resp,
526                                  &ntlmssp_state->nt_resp,
527                                  &ntlmssp_state->domain,
528                                  &ntlmssp_state->user,
529                                  &ntlmssp_state->client.netbios_name)) {
530                         DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
531                         dump_data(2, request.data, request.length);
532
533                         return NT_STATUS_INVALID_PARAMETER;
534                 }
535         }
536
537         talloc_steal(state, state->encrypted_session_key.data);
538
539         if (auth_flags)
540                 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key);
541
542         if (DEBUGLEVEL >= 10) {
543                 struct AUTHENTICATE_MESSAGE *authenticate = talloc(
544                         ntlmssp_state, struct AUTHENTICATE_MESSAGE);
545                 if (authenticate != NULL) {
546                         NTSTATUS status;
547                         authenticate->NegotiateFlags = auth_flags;
548                         status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
549                                 &request, authenticate, authenticate);
550                         if (NT_STATUS_IS_OK(status)) {
551                                 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
552                                                 authenticate);
553                         }
554                         TALLOC_FREE(authenticate);
555                 }
556         }
557
558         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
559                  ntlmssp_state->user, ntlmssp_state->domain,
560                  ntlmssp_state->client.netbios_name,
561                  (unsigned long)ntlmssp_state->lm_resp.length,
562                  (unsigned long)ntlmssp_state->nt_resp.length));
563
564 #if 0
565         file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
566         file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
567 #endif
568
569         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
570            client challenge
571
572            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
573         */
574         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
575                 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
576                         struct MD5Context md5_session_nonce_ctx;
577                         state->doing_ntlm2 = true;
578
579                         memcpy(state->session_nonce, ntlmssp_state->internal_chal.data, 8);
580                         memcpy(&state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
581
582                         SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
583
584                         MD5Init(&md5_session_nonce_ctx);
585                         MD5Update(&md5_session_nonce_ctx, state->session_nonce, 16);
586                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
587
588                         ntlmssp_state->chal = data_blob_talloc(
589                                 ntlmssp_state, session_nonce_hash, 8);
590
591                         /* LM response is no longer useful */
592                         data_blob_free(&ntlmssp_state->lm_resp);
593
594                         /* We changed the effective challenge - set it */
595                         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
596                                 return nt_status;
597                         }
598
599                         /* LM Key is incompatible. */
600                         ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
601                 }
602         }
603         return NT_STATUS_OK;
604 }
605
606 /**
607  * Next state function for the Authenticate packet
608  * (after authentication - figures out the session keys etc)
609  *
610  * @param ntlmssp_state NTLMSSP State
611  * @return Errors or NT_STATUS_OK.
612  */
613
614 static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
615                                         struct ntlmssp_server_auth_state *state)
616 {
617         DATA_BLOB user_session_key = state->user_session_key;
618         DATA_BLOB lm_session_key = state->lm_session_key;
619         NTSTATUS nt_status;
620         DATA_BLOB session_key = data_blob(NULL, 0);
621
622         dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
623         dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
624
625         /* Handle the different session key derivation for NTLM2 */
626         if (state->doing_ntlm2) {
627                 if (user_session_key.data && user_session_key.length == 16) {
628                         session_key = data_blob_talloc(ntlmssp_state,
629                                                        NULL, 16);
630                         hmac_md5(user_session_key.data, state->session_nonce,
631                                  sizeof(state->session_nonce), session_key.data);
632                         DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
633                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
634
635                 } else {
636                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
637                         session_key = data_blob_null;
638                 }
639         } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
640                 /* Ensure we can never get here on NTLMv2 */
641                 && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
642
643                 if (lm_session_key.data && lm_session_key.length >= 8) {
644                         if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
645                                 session_key = data_blob_talloc(ntlmssp_state,
646                                                                NULL, 16);
647                                 if (session_key.data == NULL) {
648                                         return NT_STATUS_NO_MEMORY;
649                                 }
650                                 SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data,
651                                                           session_key.data);
652                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
653                         } else {
654                                 static const uint8_t zeros[24] = {0, };
655                                 session_key = data_blob_talloc(
656                                         ntlmssp_state, NULL, 16);
657                                 if (session_key.data == NULL) {
658                                         return NT_STATUS_NO_MEMORY;
659                                 }
660                                 SMBsesskeygen_lm_sess_key(zeros, zeros,
661                                                           session_key.data);
662                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
663                         }
664                         dump_data_pw("LM session key:\n", session_key.data,
665                                      session_key.length);
666                 } else {
667                         /* LM Key not selected */
668                         ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
669
670                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
671                         session_key = data_blob_null;
672                 }
673
674         } else if (user_session_key.data) {
675                 session_key = user_session_key;
676                 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
677                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
678
679                 /* LM Key not selected */
680                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
681
682         } else if (lm_session_key.data) {
683                 /* Very weird to have LM key, but no user session key, but anyway.. */
684                 session_key = lm_session_key;
685                 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
686                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
687
688                 /* LM Key not selected */
689                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
690
691         } else {
692                 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
693                 session_key = data_blob_null;
694
695                 /* LM Key not selected */
696                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
697         }
698
699         /* With KEY_EXCH, the client supplies the proposed session key,
700            but encrypts it with the long-term key */
701         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
702                 if (!state->encrypted_session_key.data
703                     || state->encrypted_session_key.length != 16) {
704                         data_blob_free(&state->encrypted_session_key);
705                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
706                                   (unsigned)state->encrypted_session_key.length));
707                         return NT_STATUS_INVALID_PARAMETER;
708                 } else if (!session_key.data || session_key.length != 16) {
709                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
710                                   (unsigned int)session_key.length));
711                         ntlmssp_state->session_key = session_key;
712                 } else {
713                         dump_data_pw("KEY_EXCH session key (enc):\n",
714                                      state->encrypted_session_key.data,
715                                      state->encrypted_session_key.length);
716                         arcfour_crypt(state->encrypted_session_key.data,
717                                       session_key.data,
718                                       state->encrypted_session_key.length);
719                         ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
720                                                                       state->encrypted_session_key.data,
721                                                                       state->encrypted_session_key.length);
722                         dump_data_pw("KEY_EXCH session key:\n",
723                                      state->encrypted_session_key.data,
724                                      state->encrypted_session_key.length);
725                         talloc_free(session_key.data);
726                 }
727         } else {
728                 ntlmssp_state->session_key = session_key;
729         }
730
731         if (ntlmssp_state->session_key.length) {
732                 nt_status = ntlmssp_sign_init(ntlmssp_state);
733         }
734
735         ntlmssp_state->expected_state = NTLMSSP_DONE;
736
737         return nt_status;
738 }
739
740
741 /**
742  * Next state function for the Authenticate packet
743  *
744  * @param gensec_security GENSEC state
745  * @param out_mem_ctx Memory context for *out
746  * @param in The request, as a DATA_BLOB.  reply.data must be NULL
747  * @param out The reply, as an allocated DATA_BLOB, caller to free.
748  * @return Errors or NT_STATUS_OK if authentication sucessful
749  */
750
751 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
752                                     TALLOC_CTX *out_mem_ctx,
753                                     const DATA_BLOB in, DATA_BLOB *out)
754 {
755         struct ntlmssp_server_auth_state *state;
756         NTSTATUS nt_status;
757
758         /* zero the outbound NTLMSSP packet */
759         *out = data_blob_null;
760
761         state = talloc_zero(ntlmssp_state, struct ntlmssp_server_auth_state);
762         if (state == NULL) {
763                 return NT_STATUS_NO_MEMORY;
764         }
765
766         nt_status = ntlmssp_server_preauth(ntlmssp_state, state, in);
767         if (!NT_STATUS_IS_OK(nt_status)) {
768                 TALLOC_FREE(state);
769                 return nt_status;
770         }
771
772         /*
773          * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
774          * is required (by "ntlm auth = no" and "lm auth = no" being set in the
775          * smb.conf file) and no NTLMv2 response was sent then the password check
776          * will fail here. JRA.
777          */
778
779         /* Finally, actually ask if the password is OK */
780         nt_status = ntlmssp_state->check_password(ntlmssp_state,
781                                                   &state->user_session_key,
782                                                   &state->lm_session_key);
783         if (!NT_STATUS_IS_OK(nt_status)) {
784                 TALLOC_FREE(state);
785                 return nt_status;
786         }
787
788         /* When we get more async in the auth code behind
789            ntlmssp_state->check_password, the ntlmssp_server_postpath
790            can be done in a callback */
791
792         nt_status = ntlmssp_server_postauth(ntlmssp_state, state);
793         if (!NT_STATUS_IS_OK(nt_status)) {
794                 TALLOC_FREE(state);
795                 return nt_status;
796         }
797
798         TALLOC_FREE(state);
799         return NT_STATUS_OK;
800 }
801
802 /**
803  * Create an NTLMSSP state machine
804  *
805  * @param ntlmssp_state NTLMSSP State, allocated by this function
806  */
807
808 NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx,
809                               bool is_standalone,
810                               const char *netbios_name,
811                               const char *netbios_domain,
812                               const char *dns_name,
813                               const char *dns_domain,
814                               struct ntlmssp_state **_ntlmssp_state)
815 {
816         struct ntlmssp_state *ntlmssp_state;
817
818         if (!netbios_name) {
819                 netbios_name = "";
820         }
821
822         if (!netbios_domain) {
823                 netbios_domain = "";
824         }
825
826         if (!dns_domain) {
827                 dns_domain = "";
828         }
829
830         if (!dns_name) {
831                 dns_name = "";
832         }
833
834         ntlmssp_state = talloc_zero(mem_ctx, struct ntlmssp_state);
835         if (!ntlmssp_state) {
836                 return NT_STATUS_NO_MEMORY;
837         }
838
839         ntlmssp_state->role = NTLMSSP_SERVER;
840
841         ntlmssp_state->get_challenge = get_challenge;
842         ntlmssp_state->set_challenge = set_challenge;
843         ntlmssp_state->may_set_challenge = may_set_challenge;
844
845         ntlmssp_state->server.is_standalone = is_standalone;
846
847         ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
848
849         ntlmssp_state->allow_lm_key = lp_lanman_auth();
850
851         ntlmssp_state->neg_flags =
852                 NTLMSSP_NEGOTIATE_128 |
853                 NTLMSSP_NEGOTIATE_56 |
854                 NTLMSSP_NEGOTIATE_VERSION |
855                 NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
856                 NTLMSSP_NEGOTIATE_NTLM |
857                 NTLMSSP_NEGOTIATE_NTLM2 |
858                 NTLMSSP_NEGOTIATE_KEY_EXCH |
859                 NTLMSSP_NEGOTIATE_SIGN |
860                 NTLMSSP_NEGOTIATE_SEAL;
861
862         ntlmssp_state->server.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
863         if (!ntlmssp_state->server.netbios_name) {
864                 talloc_free(ntlmssp_state);
865                 return NT_STATUS_NO_MEMORY;
866         }
867         ntlmssp_state->server.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain);
868         if (!ntlmssp_state->server.netbios_domain) {
869                 talloc_free(ntlmssp_state);
870                 return NT_STATUS_NO_MEMORY;
871         }
872         ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state, dns_name);
873         if (!ntlmssp_state->server.dns_name) {
874                 talloc_free(ntlmssp_state);
875                 return NT_STATUS_NO_MEMORY;
876         }
877         ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, dns_domain);
878         if (!ntlmssp_state->server.dns_domain) {
879                 talloc_free(ntlmssp_state);
880                 return NT_STATUS_NO_MEMORY;
881         }
882
883         *_ntlmssp_state = ntlmssp_state;
884         return NT_STATUS_OK;
885 }
886
887 /*********************************************************************
888  Client side NTLMSSP
889 *********************************************************************/
890
891 /**
892  * Next state function for the Initial packet
893  *
894  * @param ntlmssp_state NTLMSSP State
895  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
896  * @param request The reply, as an allocated DATA_BLOB, caller to free.
897  * @return Errors or NT_STATUS_OK.
898  */
899
900 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
901                                   TALLOC_CTX *out_mem_ctx, /* Unused at this time */
902                                   DATA_BLOB reply, DATA_BLOB *next_request)
903 {
904         if (ntlmssp_state->unicode) {
905                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
906         } else {
907                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
908         }
909
910         if (ntlmssp_state->use_ntlmv2) {
911                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
912         }
913
914         /* generate the ntlmssp negotiate packet */
915         msrpc_gen(ntlmssp_state, next_request, "CddAA",
916                   "NTLMSSP",
917                   NTLMSSP_NEGOTIATE,
918                   ntlmssp_state->neg_flags,
919                   ntlmssp_state->client.netbios_domain,
920                   ntlmssp_state->client.netbios_name);
921
922         if (DEBUGLEVEL >= 10) {
923                 struct NEGOTIATE_MESSAGE *negotiate = talloc(
924                         talloc_tos(), struct NEGOTIATE_MESSAGE);
925                 if (negotiate != NULL) {
926                         NTSTATUS status;
927                         status = ntlmssp_pull_NEGOTIATE_MESSAGE(
928                                 next_request, negotiate, negotiate);
929                         if (NT_STATUS_IS_OK(status)) {
930                                 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
931                                                 negotiate);
932                         }
933                         TALLOC_FREE(negotiate);
934                 }
935         }
936
937         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
938
939         return NT_STATUS_MORE_PROCESSING_REQUIRED;
940 }
941
942 /**
943  * Next state function for the Challenge Packet.  Generate an auth packet.
944  *
945  * @param ntlmssp_state NTLMSSP State
946  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
947  * @param request The reply, as an allocated DATA_BLOB, caller to free.
948  * @return Errors or NT_STATUS_OK.
949  */
950
951 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
952                                          TALLOC_CTX *out_mem_ctx, /* Unused at this time */
953                                          const DATA_BLOB reply, DATA_BLOB *next_request)
954 {
955         uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
956         DATA_BLOB server_domain_blob;
957         DATA_BLOB challenge_blob;
958         DATA_BLOB struct_blob = data_blob_null;
959         char *server_domain;
960         const char *chal_parse_string;
961         const char *auth_gen_string;
962         DATA_BLOB lm_response = data_blob_null;
963         DATA_BLOB nt_response = data_blob_null;
964         DATA_BLOB session_key = data_blob_null;
965         DATA_BLOB encrypted_session_key = data_blob_null;
966         NTSTATUS nt_status = NT_STATUS_OK;
967
968         if (ntlmssp_state->use_ccache) {
969                 struct wbcCredentialCacheParams params;
970                 struct wbcCredentialCacheInfo *info = NULL;
971                 struct wbcAuthErrorInfo *error = NULL;
972                 struct wbcNamedBlob auth_blob;
973                 struct wbcBlob *wbc_next = NULL;
974                 struct wbcBlob *wbc_session_key = NULL;
975                 wbcErr wbc_status;
976                 int i;
977
978                 params.account_name = ntlmssp_state->user;
979                 params.domain_name = ntlmssp_state->domain;
980                 params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP;
981
982                 auth_blob.name = "challenge_blob";
983                 auth_blob.flags = 0;
984                 auth_blob.blob.data = reply.data;
985                 auth_blob.blob.length = reply.length;
986                 params.num_blobs = 1;
987                 params.blobs = &auth_blob;
988
989                 wbc_status = wbcCredentialCache(&params, &info, &error);
990                 if (error != NULL) {
991                         wbcFreeMemory(error);
992                 }
993                 if (!WBC_ERROR_IS_OK(wbc_status)) {
994                         goto noccache;
995                 }
996
997                 for (i=0; i<info->num_blobs; i++) {
998                         if (strequal(info->blobs[i].name, "auth_blob")) {
999                                 wbc_next = &info->blobs[i].blob;
1000                         }
1001                         if (strequal(info->blobs[i].name, "session_key")) {
1002                                 wbc_session_key = &info->blobs[i].blob;
1003                         }
1004                 }
1005                 if ((wbc_next == NULL) || (wbc_session_key == NULL)) {
1006                         wbcFreeMemory(info);
1007                         goto noccache;
1008                 }
1009
1010                 *next_request = data_blob(wbc_next->data, wbc_next->length);
1011                 ntlmssp_state->session_key = data_blob(
1012                         wbc_session_key->data, wbc_session_key->length);
1013
1014                 wbcFreeMemory(info);
1015                 goto done;
1016         }
1017
1018 noccache:
1019
1020         if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
1021                          "NTLMSSP",
1022                          &ntlmssp_command,
1023                          &server_domain_blob,
1024                          &chal_flags)) {
1025                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
1026                 dump_data(2, reply.data, reply.length);
1027
1028                 return NT_STATUS_INVALID_PARAMETER;
1029         }
1030
1031         if (DEBUGLEVEL >= 10) {
1032                 struct CHALLENGE_MESSAGE *challenge = talloc(
1033                         talloc_tos(), struct CHALLENGE_MESSAGE);
1034                 if (challenge != NULL) {
1035                         NTSTATUS status;
1036                         challenge->NegotiateFlags = chal_flags;
1037                         status = ntlmssp_pull_CHALLENGE_MESSAGE(
1038                                 &reply, challenge, challenge);
1039                         if (NT_STATUS_IS_OK(status)) {
1040                                 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
1041                                                 challenge);
1042                         }
1043                         TALLOC_FREE(challenge);
1044                 }
1045         }
1046
1047         data_blob_free(&server_domain_blob);
1048
1049         DEBUG(3, ("Got challenge flags:\n"));
1050         debug_ntlmssp_flags(chal_flags);
1051
1052         ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
1053
1054         if (ntlmssp_state->unicode) {
1055                 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
1056                         chal_parse_string = "CdUdbddB";
1057                 } else {
1058                         chal_parse_string = "CdUdbdd";
1059                 }
1060                 auth_gen_string = "CdBBUUUBd";
1061         } else {
1062                 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
1063                         chal_parse_string = "CdAdbddB";
1064                 } else {
1065                         chal_parse_string = "CdAdbdd";
1066                 }
1067
1068                 auth_gen_string = "CdBBAAABd";
1069         }
1070
1071         DEBUG(3, ("NTLMSSP: Set final flags:\n"));
1072         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
1073
1074         if (!msrpc_parse(ntlmssp_state, &reply, chal_parse_string,
1075                          "NTLMSSP",
1076                          &ntlmssp_command,
1077                          &server_domain,
1078                          &chal_flags,
1079                          &challenge_blob, 8,
1080                          &unkn1, &unkn2,
1081                          &struct_blob)) {
1082                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
1083                 dump_data(2, reply.data, reply.length);
1084                 return NT_STATUS_INVALID_PARAMETER;
1085         }
1086
1087         if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) {
1088                 ntlmssp_state->server.is_standalone = true;
1089         } else {
1090                 ntlmssp_state->server.is_standalone = false;
1091         }
1092         /* TODO: parse struct_blob and fill in the rest */
1093         ntlmssp_state->server.netbios_name = "";
1094         ntlmssp_state->server.netbios_domain = server_domain;
1095         ntlmssp_state->server.dns_name = "";
1096         ntlmssp_state->server.dns_domain = "";
1097
1098         if (challenge_blob.length != 8) {
1099                 data_blob_free(&struct_blob);
1100                 return NT_STATUS_INVALID_PARAMETER;
1101         }
1102
1103         if (!ntlmssp_state->nt_hash || !ntlmssp_state->lm_hash) {
1104                 static const uint8_t zeros[16] = {0, };
1105                 /* do nothing - blobs are zero length */
1106
1107                 /* session key is all zeros */
1108                 session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1109
1110                 /* not doing NLTM2 without a password */
1111                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
1112         } else if (ntlmssp_state->use_ntlmv2) {
1113                 if (!struct_blob.length) {
1114                         /* be lazy, match win2k - we can't do NTLMv2 without it */
1115                         DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
1116                         return NT_STATUS_INVALID_PARAMETER;
1117                 }
1118
1119                 /* TODO: if the remote server is standalone, then we should replace 'domain'
1120                    with the server name as supplied above */
1121
1122                 if (!SMBNTLMv2encrypt_hash(ntlmssp_state,
1123                                            ntlmssp_state->user,
1124                                            ntlmssp_state->domain,
1125                                            ntlmssp_state->nt_hash, &challenge_blob,
1126                                            &struct_blob,
1127                                            &lm_response, &nt_response, NULL,
1128                                            &session_key)) {
1129                         data_blob_free(&challenge_blob);
1130                         data_blob_free(&struct_blob);
1131                         return NT_STATUS_NO_MEMORY;
1132                 }
1133         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
1134                 struct MD5Context md5_session_nonce_ctx;
1135                 uint8_t session_nonce[16];
1136                 uint8_t session_nonce_hash[16];
1137                 uint8_t user_session_key[16];
1138
1139                 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1140                 generate_random_buffer(lm_response.data, 8);
1141                 memset(lm_response.data+8, 0, 16);
1142
1143                 memcpy(session_nonce, challenge_blob.data, 8);
1144                 memcpy(&session_nonce[8], lm_response.data, 8);
1145
1146                 MD5Init(&md5_session_nonce_ctx);
1147                 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
1148                 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
1149                 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
1150
1151                 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
1152                 DEBUG(5, ("challenge is: \n"));
1153                 dump_data(5, session_nonce_hash, 8);
1154
1155                 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1156                 SMBNTencrypt_hash(ntlmssp_state->nt_hash,
1157                                   session_nonce_hash,
1158                                   nt_response.data);
1159
1160                 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1161
1162                 SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, user_session_key);
1163                 hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
1164                 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
1165         } else {
1166                 /* lanman auth is insecure, it may be disabled */
1167                 if (lp_client_lanman_auth()) {
1168                         lm_response = data_blob_talloc(ntlmssp_state,
1169                                                        NULL, 24);
1170                         SMBencrypt_hash(ntlmssp_state->lm_hash,challenge_blob.data,
1171                                    lm_response.data);
1172                 }
1173
1174                 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1175                 SMBNTencrypt_hash(ntlmssp_state->nt_hash,challenge_blob.data,
1176                              nt_response.data);
1177
1178                 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1179                 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
1180                     && lp_client_lanman_auth()) {
1181                         SMBsesskeygen_lm_sess_key(ntlmssp_state->lm_hash, lm_response.data,
1182                                         session_key.data);
1183                         dump_data_pw("LM session key\n", session_key.data, session_key.length);
1184                 } else {
1185                         SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, session_key.data);
1186                         dump_data_pw("NT session key:\n", session_key.data, session_key.length);
1187                 }
1188         }
1189         data_blob_free(&struct_blob);
1190
1191         /* Key exchange encryptes a new client-generated session key with
1192            the password-derived key */
1193         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1194                 /* Make up a new session key */
1195                 uint8_t client_session_key[16];
1196                 generate_random_buffer(client_session_key, sizeof(client_session_key));
1197
1198                 /* Encrypt the new session key with the old one */
1199                 encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
1200                 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
1201                 arcfour_crypt_blob(encrypted_session_key.data, encrypted_session_key.length, &session_key);
1202                 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
1203
1204                 /* Mark the new session key as the 'real' session key */
1205                 data_blob_free(&session_key);
1206                 session_key = data_blob_talloc(ntlmssp_state,
1207                                                client_session_key,
1208                                                sizeof(client_session_key));
1209         }
1210
1211         /* this generates the actual auth packet */
1212         if (!msrpc_gen(ntlmssp_state, next_request, auth_gen_string,
1213                        "NTLMSSP",
1214                        NTLMSSP_AUTH,
1215                        lm_response.data, lm_response.length,
1216                        nt_response.data, nt_response.length,
1217                        ntlmssp_state->domain,
1218                        ntlmssp_state->user,
1219                        ntlmssp_state->client.netbios_name,
1220                        encrypted_session_key.data, encrypted_session_key.length,
1221                        ntlmssp_state->neg_flags)) {
1222
1223                 return NT_STATUS_NO_MEMORY;
1224         }
1225
1226         if (DEBUGLEVEL >= 10) {
1227                 struct AUTHENTICATE_MESSAGE *authenticate = talloc(
1228                         talloc_tos(), struct AUTHENTICATE_MESSAGE);
1229                 if (authenticate != NULL) {
1230                         NTSTATUS status;
1231                         authenticate->NegotiateFlags =
1232                                 ntlmssp_state->neg_flags;
1233                         status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
1234                                 next_request, authenticate, authenticate);
1235                         if (NT_STATUS_IS_OK(status)) {
1236                                 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
1237                                                 authenticate);
1238                         }
1239                         TALLOC_FREE(authenticate);
1240                 }
1241         }
1242
1243         data_blob_free(&encrypted_session_key);
1244
1245         data_blob_free(&ntlmssp_state->chal);
1246
1247         ntlmssp_state->session_key = session_key;
1248
1249         ntlmssp_state->chal = challenge_blob;
1250         ntlmssp_state->lm_resp = lm_response;
1251         ntlmssp_state->nt_resp = nt_response;
1252
1253 done:
1254
1255         ntlmssp_state->expected_state = NTLMSSP_DONE;
1256
1257         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
1258                 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
1259         }
1260
1261         return nt_status;
1262 }
1263
1264 NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx,
1265                               const char *netbios_name,
1266                               const char *netbios_domain,
1267                               bool use_ntlmv2,
1268                               struct ntlmssp_state **_ntlmssp_state)
1269 {
1270         struct ntlmssp_state *ntlmssp_state;
1271
1272         if (!netbios_name) {
1273                 netbios_name = "";
1274         }
1275
1276         if (!netbios_domain) {
1277                 netbios_domain = "";
1278         }
1279
1280         ntlmssp_state = talloc_zero(mem_ctx, struct ntlmssp_state);
1281         if (!ntlmssp_state) {
1282                 return NT_STATUS_NO_MEMORY;
1283         }
1284
1285         ntlmssp_state->role = NTLMSSP_CLIENT;
1286
1287         ntlmssp_state->unicode = True;
1288
1289         ntlmssp_state->use_ntlmv2 = use_ntlmv2;
1290
1291         ntlmssp_state->expected_state = NTLMSSP_INITIAL;
1292
1293         ntlmssp_state->neg_flags =
1294                 NTLMSSP_NEGOTIATE_128 |
1295                 NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
1296                 NTLMSSP_NEGOTIATE_NTLM |
1297                 NTLMSSP_NEGOTIATE_NTLM2 |
1298                 NTLMSSP_NEGOTIATE_KEY_EXCH |
1299                 NTLMSSP_REQUEST_TARGET;
1300
1301         ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
1302         if (!ntlmssp_state->client.netbios_name) {
1303                 talloc_free(ntlmssp_state);
1304                 return NT_STATUS_NO_MEMORY;
1305         }
1306         ntlmssp_state->client.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain);
1307         if (!ntlmssp_state->client.netbios_domain) {
1308                 talloc_free(ntlmssp_state);
1309                 return NT_STATUS_NO_MEMORY;
1310         }
1311
1312         *_ntlmssp_state = ntlmssp_state;
1313         return NT_STATUS_OK;
1314 }