79c45f697b5ce35aac69fa8a66892e138273ed20
[sfrench/samba-autobuild/.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 "../auth/ntlmssp/ntlmssp.h"
26 #include "../auth/ntlmssp/ntlmssp_private.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../librpc/gen_ndr/ndr_ntlmssp.h"
29 #include "../auth/ntlmssp/ntlmssp_ndr.h"
30 #include "../lib/crypto/md5.h"
31 #include "../lib/crypto/arcfour.h"
32 #include "../lib/crypto/hmacmd5.h"
33 #include "../nsswitch/libwbclient/wbclient.h"
34
35 static NTSTATUS ntlmssp3_client_initial(struct ntlmssp_state *ntlmssp_state,
36                                        TALLOC_CTX *out_mem_ctx,
37                                        DATA_BLOB reply, DATA_BLOB *next_request);
38 static NTSTATUS ntlmssp3_client_challenge(struct ntlmssp_state *ntlmssp_state,
39                                          TALLOC_CTX *out_mem_ctx, /* Unused at this time */
40                                          const DATA_BLOB reply, DATA_BLOB *next_request);
41 /**
42  * Callbacks for NTLMSSP - for both client and server operating modes
43  *
44  */
45
46 static const struct ntlmssp_callbacks {
47         enum ntlmssp_role role;
48         enum ntlmssp_message_type ntlmssp_command;
49         NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state,
50                        TALLOC_CTX *out_mem_ctx,
51                        DATA_BLOB in, DATA_BLOB *out);
52 } ntlmssp_callbacks[] = {
53         {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp3_client_initial},
54         {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp3_client_challenge},
55         {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
56         {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
57 };
58
59 /**
60  * Set a username on an NTLMSSP context - ensures it is talloc()ed
61  *
62  */
63
64 NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user)
65 {
66         ntlmssp_state->user = talloc_strdup(ntlmssp_state, user ? user : "" );
67         if (!ntlmssp_state->user) {
68                 return NT_STATUS_NO_MEMORY;
69         }
70         return NT_STATUS_OK;
71 }
72
73 /**
74  * Converts a password to the hashes on an NTLMSSP context.
75  *
76  */
77 NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password)
78 {
79         uint8_t lm_hash[16];
80         uint8_t nt_hash[16];
81
82         TALLOC_FREE(ntlmssp_state->lm_hash);
83         TALLOC_FREE(ntlmssp_state->nt_hash);
84
85         if (password == NULL) {
86                 return NT_STATUS_OK;
87         }
88
89         if (E_deshash(password, lm_hash)) {
90                 ntlmssp_state->lm_hash = (uint8_t *)
91                         talloc_memdup(ntlmssp_state, lm_hash, 16);
92                 if (!ntlmssp_state->lm_hash) {
93                         return NT_STATUS_NO_MEMORY;
94                 }
95         }
96
97         E_md4hash(password, nt_hash);
98
99         ntlmssp_state->nt_hash = (uint8_t *)
100                 talloc_memdup(ntlmssp_state, nt_hash, 16);
101         if (!ntlmssp_state->nt_hash) {
102                 TALLOC_FREE(ntlmssp_state->lm_hash);
103                 return NT_STATUS_NO_MEMORY;
104         }
105
106         return NT_STATUS_OK;
107 }
108
109 /**
110  * Set a domain on an NTLMSSP context - ensures it is talloc()ed
111  *
112  */
113 NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain)
114 {
115         ntlmssp_state->domain = talloc_strdup(ntlmssp_state,
116                                               domain ? domain : "" );
117         if (!ntlmssp_state->domain) {
118                 return NT_STATUS_NO_MEMORY;
119         }
120         return NT_STATUS_OK;
121 }
122
123 /**
124  * Request features for the NTLMSSP negotiation
125  *
126  * @param ntlmssp_state NTLMSSP state
127  * @param feature_list List of space seperated features requested from NTLMSSP.
128  */
129 void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list)
130 {
131         /*
132          * We need to set this to allow a later SetPassword
133          * via the SAMR pipe to succeed. Strange.... We could
134          * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
135          */
136         if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) {
137                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
138         }
139         if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) {
140                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
141         }
142         if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) {
143                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
144         }
145         if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) {
146                 ntlmssp_state->use_ccache = true;
147         }
148 }
149
150 /**
151  * Request a feature for the NTLMSSP negotiation
152  *
153  * @param ntlmssp_state NTLMSSP state
154  * @param feature Bit flag specifying the requested feature
155  */
156 void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature)
157 {
158         /* As per JRA's comment above */
159         if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
160                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
161         }
162         if (feature & NTLMSSP_FEATURE_SIGN) {
163                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
164         }
165         if (feature & NTLMSSP_FEATURE_SEAL) {
166                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
167                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
168         }
169         if (feature & NTLMSSP_FEATURE_CCACHE) {
170                 ntlmssp_state->use_ccache = true;
171         }
172 }
173
174 /**
175  * Next state function for the NTLMSSP state machine
176  *
177  * @param ntlmssp_state NTLMSSP State
178  * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
179  * @param out The reply, as an allocated DATA_BLOB, caller to free.
180  * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK.
181  */
182
183 NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
184                         const DATA_BLOB input, DATA_BLOB *out)
185 {
186         uint32_t ntlmssp_command;
187         int i;
188
189         if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
190                 /* Called update after negotiations finished. */
191                 DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n"));
192                 return NT_STATUS_INVALID_PARAMETER;
193         }
194
195         *out = data_blob_null;
196
197         if (!input.length) {
198                 switch (ntlmssp_state->role) {
199                 case NTLMSSP_CLIENT:
200                         ntlmssp_command = NTLMSSP_INITIAL;
201                         break;
202                 case NTLMSSP_SERVER:
203                         /* 'datagram' mode - no neg packet */
204                         ntlmssp_command = NTLMSSP_NEGOTIATE;
205                         break;
206                 default:
207                         DEBUG(1, ("Invalid role: %d\n", ntlmssp_state->role));
208                         return NT_STATUS_INVALID_PARAMETER;
209                 }
210         } else {
211                 if (!msrpc_parse(ntlmssp_state, &input, "Cd",
212                                  "NTLMSSP",
213                                  &ntlmssp_command)) {
214                         DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
215                         dump_data(2, input.data, input.length);
216                         return NT_STATUS_INVALID_PARAMETER;
217                 }
218         }
219
220         if (ntlmssp_command != ntlmssp_state->expected_state) {
221                 DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
222                 return NT_STATUS_INVALID_PARAMETER;
223         }
224
225         for (i=0; ntlmssp_callbacks[i].fn; i++) {
226                 if (ntlmssp_callbacks[i].role == ntlmssp_state->role
227                     && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) {
228                         return ntlmssp_callbacks[i].fn(ntlmssp_state, ntlmssp_state, input, out);
229                 }
230         }
231
232         DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n",
233                   ntlmssp_state->role, ntlmssp_command));
234
235         return NT_STATUS_INVALID_PARAMETER;
236 }
237
238 /*********************************************************************
239  Client side NTLMSSP
240 *********************************************************************/
241
242 /**
243  * Next state function for the Initial packet
244  *
245  * @param ntlmssp_state NTLMSSP State
246  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
247  * @param request The reply, as an allocated DATA_BLOB, caller to free.
248  * @return Errors or NT_STATUS_OK.
249  */
250
251 static NTSTATUS ntlmssp3_client_initial(struct ntlmssp_state *ntlmssp_state,
252                                        TALLOC_CTX *out_mem_ctx,
253                                        DATA_BLOB in, DATA_BLOB *out)
254 {
255         const char *domain = ntlmssp_state->client.netbios_domain;
256         const char *workstation = ntlmssp_state->client.netbios_name;
257         NTSTATUS status;
258
259         /* These don't really matter in the initial packet, so don't panic if they are not set */
260         if (!domain) {
261                 domain = "";
262         }
263
264         if (!workstation) {
265                 workstation = "";
266         }
267
268         if (ntlmssp_state->unicode) {
269                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
270         } else {
271                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
272         }
273
274         if (ntlmssp_state->use_ntlmv2) {
275                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
276         }
277
278         /* generate the ntlmssp negotiate packet */
279         status = msrpc_gen(out_mem_ctx,
280                   out, "CddAA",
281                   "NTLMSSP",
282                   NTLMSSP_NEGOTIATE,
283                   ntlmssp_state->neg_flags,
284                   domain,
285                   workstation);
286
287         if (!NT_STATUS_IS_OK(status)) {
288                 DEBUG(0, ("ntlmssp_client_initial: failed to generate "
289                           "ntlmssp negotiate packet\n"));
290                 return status;
291         }
292
293         if (DEBUGLEVEL >= 10) {
294                 struct NEGOTIATE_MESSAGE *negotiate = talloc(
295                         talloc_tos(), struct NEGOTIATE_MESSAGE);
296                 if (negotiate != NULL) {
297                         status = ntlmssp_pull_NEGOTIATE_MESSAGE(
298                                 out, negotiate, negotiate);
299                         if (NT_STATUS_IS_OK(status)) {
300                                 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
301                                                 negotiate);
302                         }
303                         TALLOC_FREE(negotiate);
304                 }
305         }
306
307         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
308
309         return NT_STATUS_MORE_PROCESSING_REQUIRED;
310 }
311
312 bool ntlmssp_is_anonymous(struct ntlmssp_state *ntlmssp_state)
313 {
314         const char *user = ntlmssp_state->user;
315
316         if (ntlmssp_state->user == NULL) {
317                 return true;
318         }
319
320         if (strlen(ntlmssp_state->user) == 0) {
321                 return true;
322         }
323
324         return false;
325 }
326
327 /**
328  * Next state function for the Challenge Packet.  Generate an auth packet.
329  *
330  * @param ntlmssp_state NTLMSSP State
331  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
332  * @param request The reply, as an allocated DATA_BLOB, caller to free.
333  * @return Errors or NT_STATUS_OK.
334  */
335
336 static NTSTATUS ntlmssp3_client_challenge(struct ntlmssp_state *ntlmssp_state,
337                                          TALLOC_CTX *out_mem_ctx, /* Unused at this time */
338                                          const DATA_BLOB reply, DATA_BLOB *next_request)
339 {
340         uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
341         DATA_BLOB server_domain_blob;
342         DATA_BLOB challenge_blob;
343         DATA_BLOB struct_blob = data_blob_null;
344         char *server_domain;
345         const char *chal_parse_string;
346         const char *auth_gen_string;
347         DATA_BLOB lm_response = data_blob_null;
348         DATA_BLOB nt_response = data_blob_null;
349         DATA_BLOB session_key = data_blob_null;
350         DATA_BLOB encrypted_session_key = data_blob_null;
351         NTSTATUS nt_status = NT_STATUS_OK;
352
353         if (ntlmssp_state->use_ccache) {
354                 struct wbcCredentialCacheParams params;
355                 struct wbcCredentialCacheInfo *info = NULL;
356                 struct wbcAuthErrorInfo *error = NULL;
357                 struct wbcNamedBlob auth_blob;
358                 struct wbcBlob *wbc_next = NULL;
359                 struct wbcBlob *wbc_session_key = NULL;
360                 wbcErr wbc_status;
361                 int i;
362
363                 params.account_name = ntlmssp_state->user;
364                 params.domain_name = ntlmssp_state->domain;
365                 params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP;
366
367                 auth_blob.name = "challenge_blob";
368                 auth_blob.flags = 0;
369                 auth_blob.blob.data = reply.data;
370                 auth_blob.blob.length = reply.length;
371                 params.num_blobs = 1;
372                 params.blobs = &auth_blob;
373
374                 wbc_status = wbcCredentialCache(&params, &info, &error);
375                 wbcFreeMemory(error);
376                 if (!WBC_ERROR_IS_OK(wbc_status)) {
377                         goto noccache;
378                 }
379
380                 for (i=0; i<info->num_blobs; i++) {
381                         if (strequal(info->blobs[i].name, "auth_blob")) {
382                                 wbc_next = &info->blobs[i].blob;
383                         }
384                         if (strequal(info->blobs[i].name, "session_key")) {
385                                 wbc_session_key = &info->blobs[i].blob;
386                         }
387                 }
388                 if ((wbc_next == NULL) || (wbc_session_key == NULL)) {
389                         wbcFreeMemory(info);
390                         goto noccache;
391                 }
392
393                 *next_request = data_blob(wbc_next->data, wbc_next->length);
394                 ntlmssp_state->session_key = data_blob(
395                         wbc_session_key->data, wbc_session_key->length);
396
397                 wbcFreeMemory(info);
398                 goto done;
399         }
400
401 noccache:
402
403         if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
404                          "NTLMSSP",
405                          &ntlmssp_command,
406                          &server_domain_blob,
407                          &chal_flags)) {
408                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
409                 dump_data(2, reply.data, reply.length);
410
411                 return NT_STATUS_INVALID_PARAMETER;
412         }
413
414         if (DEBUGLEVEL >= 10) {
415                 struct CHALLENGE_MESSAGE *challenge = talloc(
416                         talloc_tos(), struct CHALLENGE_MESSAGE);
417                 if (challenge != NULL) {
418                         NTSTATUS status;
419                         challenge->NegotiateFlags = chal_flags;
420                         status = ntlmssp_pull_CHALLENGE_MESSAGE(
421                                 &reply, challenge, challenge);
422                         if (NT_STATUS_IS_OK(status)) {
423                                 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
424                                                 challenge);
425                         }
426                         TALLOC_FREE(challenge);
427                 }
428         }
429
430         data_blob_free(&server_domain_blob);
431
432         DEBUG(3, ("Got challenge flags:\n"));
433         debug_ntlmssp_flags(chal_flags);
434
435         ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
436
437         if (ntlmssp_state->unicode) {
438                 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
439                         chal_parse_string = "CdUdbddB";
440                 } else {
441                         chal_parse_string = "CdUdbdd";
442                 }
443                 auth_gen_string = "CdBBUUUBd";
444         } else {
445                 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
446                         chal_parse_string = "CdAdbddB";
447                 } else {
448                         chal_parse_string = "CdAdbdd";
449                 }
450
451                 auth_gen_string = "CdBBAAABd";
452         }
453
454         DEBUG(3, ("NTLMSSP: Set final flags:\n"));
455         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
456
457         if (!msrpc_parse(ntlmssp_state, &reply, chal_parse_string,
458                          "NTLMSSP",
459                          &ntlmssp_command,
460                          &server_domain,
461                          &chal_flags,
462                          &challenge_blob, 8,
463                          &unkn1, &unkn2,
464                          &struct_blob)) {
465                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
466                 dump_data(2, reply.data, reply.length);
467                 return NT_STATUS_INVALID_PARAMETER;
468         }
469
470         if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) {
471                 ntlmssp_state->server.is_standalone = true;
472         } else {
473                 ntlmssp_state->server.is_standalone = false;
474         }
475         /* TODO: parse struct_blob and fill in the rest */
476         ntlmssp_state->server.netbios_name = "";
477         ntlmssp_state->server.netbios_domain = server_domain;
478         ntlmssp_state->server.dns_name = "";
479         ntlmssp_state->server.dns_domain = "";
480
481         if (challenge_blob.length != 8) {
482                 data_blob_free(&struct_blob);
483                 return NT_STATUS_INVALID_PARAMETER;
484         }
485
486         if (!ntlmssp_state->nt_hash) {
487                 static const uint8_t zeros[16] = {0, };
488                 /* do nothing - blobs are zero length */
489
490                 /* session key is all zeros */
491                 session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
492
493                 /* not doing NLTM2 without a password */
494                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
495         } else if (ntlmssp_state->use_ntlmv2) {
496                 if (!struct_blob.length) {
497                         /* be lazy, match win2k - we can't do NTLMv2 without it */
498                         DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
499                         return NT_STATUS_INVALID_PARAMETER;
500                 }
501
502                 /* TODO: if the remote server is standalone, then we should replace 'domain'
503                    with the server name as supplied above */
504
505                 if (!SMBNTLMv2encrypt_hash(ntlmssp_state,
506                                            ntlmssp_state->user,
507                                            ntlmssp_state->domain,
508                                            ntlmssp_state->nt_hash, &challenge_blob,
509                                            &struct_blob,
510                                            &lm_response, &nt_response, NULL,
511                                            &session_key)) {
512                         data_blob_free(&challenge_blob);
513                         data_blob_free(&struct_blob);
514                         return NT_STATUS_NO_MEMORY;
515                 }
516         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
517                 struct MD5Context md5_session_nonce_ctx;
518                 uint8_t session_nonce[16];
519                 uint8_t session_nonce_hash[16];
520                 uint8_t user_session_key[16];
521
522                 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
523                 generate_random_buffer(lm_response.data, 8);
524                 memset(lm_response.data+8, 0, 16);
525
526                 memcpy(session_nonce, challenge_blob.data, 8);
527                 memcpy(&session_nonce[8], lm_response.data, 8);
528
529                 MD5Init(&md5_session_nonce_ctx);
530                 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
531                 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
532                 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
533
534                 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
535                 DEBUG(5, ("challenge is: \n"));
536                 dump_data(5, session_nonce_hash, 8);
537
538                 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
539                 SMBNTencrypt_hash(ntlmssp_state->nt_hash,
540                                   session_nonce_hash,
541                                   nt_response.data);
542
543                 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
544
545                 SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, user_session_key);
546                 hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
547                 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
548         } else {
549                 /* lanman auth is insecure, it may be disabled */
550                 if (lp_client_lanman_auth() && ntlmssp_state->lm_hash) {
551                         lm_response = data_blob_talloc(ntlmssp_state,
552                                                        NULL, 24);
553                         SMBencrypt_hash(ntlmssp_state->lm_hash,challenge_blob.data,
554                                    lm_response.data);
555                 }
556
557                 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
558                 SMBNTencrypt_hash(ntlmssp_state->nt_hash,challenge_blob.data,
559                              nt_response.data);
560
561                 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
562                 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
563                     && lp_client_lanman_auth() && ntlmssp_state->lm_hash) {
564                         SMBsesskeygen_lm_sess_key(ntlmssp_state->lm_hash, lm_response.data,
565                                         session_key.data);
566                         dump_data_pw("LM session key\n", session_key.data, session_key.length);
567                 } else {
568                         SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, session_key.data);
569                         dump_data_pw("NT session key:\n", session_key.data, session_key.length);
570                 }
571         }
572         data_blob_free(&struct_blob);
573
574         /* Key exchange encryptes a new client-generated session key with
575            the password-derived key */
576         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
577                 /* Make up a new session key */
578                 uint8_t client_session_key[16];
579                 generate_random_buffer(client_session_key, sizeof(client_session_key));
580
581                 /* Encrypt the new session key with the old one */
582                 encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
583                 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
584                 arcfour_crypt_blob(encrypted_session_key.data, encrypted_session_key.length, &session_key);
585                 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
586
587                 /* Mark the new session key as the 'real' session key */
588                 data_blob_free(&session_key);
589                 session_key = data_blob_talloc(ntlmssp_state,
590                                                client_session_key,
591                                                sizeof(client_session_key));
592         }
593
594         /* this generates the actual auth packet */
595         nt_status = msrpc_gen(ntlmssp_state, next_request, auth_gen_string,
596                        "NTLMSSP",
597                        NTLMSSP_AUTH,
598                        lm_response.data, lm_response.length,
599                        nt_response.data, nt_response.length,
600                        ntlmssp_state->domain,
601                        ntlmssp_state->user,
602                        ntlmssp_state->client.netbios_name,
603                        encrypted_session_key.data, encrypted_session_key.length,
604                        ntlmssp_state->neg_flags);
605
606         if (!NT_STATUS_IS_OK(nt_status)) {
607                 return NT_STATUS_NO_MEMORY;
608         }
609
610         if (DEBUGLEVEL >= 10) {
611                 struct AUTHENTICATE_MESSAGE *authenticate = talloc(
612                         talloc_tos(), struct AUTHENTICATE_MESSAGE);
613                 if (authenticate != NULL) {
614                         NTSTATUS status;
615                         authenticate->NegotiateFlags =
616                                 ntlmssp_state->neg_flags;
617                         status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
618                                 next_request, authenticate, authenticate);
619                         if (NT_STATUS_IS_OK(status)) {
620                                 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
621                                                 authenticate);
622                         }
623                         TALLOC_FREE(authenticate);
624                 }
625         }
626
627         data_blob_free(&encrypted_session_key);
628
629         data_blob_free(&ntlmssp_state->chal);
630
631         ntlmssp_state->session_key = session_key;
632
633         ntlmssp_state->chal = challenge_blob;
634         ntlmssp_state->lm_resp = lm_response;
635         ntlmssp_state->nt_resp = nt_response;
636
637 done:
638
639         ntlmssp_state->expected_state = NTLMSSP_DONE;
640
641         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
642                 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
643         }
644
645         return nt_status;
646 }
647
648 NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx,
649                               const char *netbios_name,
650                               const char *netbios_domain,
651                               bool use_ntlmv2,
652                               struct ntlmssp_state **_ntlmssp_state)
653 {
654         struct ntlmssp_state *ntlmssp_state;
655
656         if (!netbios_name) {
657                 netbios_name = "";
658         }
659
660         if (!netbios_domain) {
661                 netbios_domain = "";
662         }
663
664         ntlmssp_state = talloc_zero(mem_ctx, struct ntlmssp_state);
665         if (!ntlmssp_state) {
666                 return NT_STATUS_NO_MEMORY;
667         }
668
669         ntlmssp_state->role = NTLMSSP_CLIENT;
670
671         ntlmssp_state->unicode = True;
672
673         ntlmssp_state->use_ntlmv2 = use_ntlmv2;
674
675         ntlmssp_state->expected_state = NTLMSSP_INITIAL;
676
677         ntlmssp_state->neg_flags =
678                 NTLMSSP_NEGOTIATE_128 |
679                 NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
680                 NTLMSSP_NEGOTIATE_NTLM |
681                 NTLMSSP_NEGOTIATE_NTLM2 |
682                 NTLMSSP_NEGOTIATE_KEY_EXCH |
683                 NTLMSSP_REQUEST_TARGET;
684
685         ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
686         if (!ntlmssp_state->client.netbios_name) {
687                 talloc_free(ntlmssp_state);
688                 return NT_STATUS_NO_MEMORY;
689         }
690         ntlmssp_state->client.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain);
691         if (!ntlmssp_state->client.netbios_domain) {
692                 talloc_free(ntlmssp_state);
693                 return NT_STATUS_NO_MEMORY;
694         }
695
696         *_ntlmssp_state = ntlmssp_state;
697         return NT_STATUS_OK;
698 }