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