This patch corrects some errors in the NTLMSSP implementation, that
[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-2003
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25
26 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
27                                        DATA_BLOB reply, DATA_BLOB *next_request);
28 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
29                                          const DATA_BLOB in, DATA_BLOB *out);
30 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
31                                          const DATA_BLOB reply, DATA_BLOB *next_request);
32 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
33                                     const DATA_BLOB request, DATA_BLOB *reply);
34
35 /**
36  * Callbacks for NTLMSSP - for both client and server operating modes
37  * 
38  */
39
40 static const struct ntlmssp_callbacks {
41         enum NTLMSSP_ROLE role;
42         enum NTLM_MESSAGE_TYPE ntlmssp_command;
43         NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, 
44                        DATA_BLOB in, DATA_BLOB *out);
45 } ntlmssp_callbacks[] = {
46         {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},
47         {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},
48         {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},
49         {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},
50         {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
51         {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
52 };
53
54
55 /**
56  * Print out the NTLMSSP flags for debugging 
57  * @param neg_flags The flags from the packet
58  */
59
60 void debug_ntlmssp_flags(uint32 neg_flags)
61 {
62         DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
63         
64         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) 
65                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_UNICODE\n"));
66         if (neg_flags & NTLMSSP_NEGOTIATE_OEM) 
67                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM\n"));
68         if (neg_flags & NTLMSSP_REQUEST_TARGET) 
69                 DEBUGADD(4, ("  NTLMSSP_REQUEST_TARGET\n"));
70         if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) 
71                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SIGN\n"));
72         if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) 
73                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SEAL\n"));
74         if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
75                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_LM_KEY\n"));
76         if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) 
77                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NETWARE\n"));
78         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) 
79                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM\n"));
80         if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) 
81                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n"));
82         if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) 
83                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n"));
84         if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) 
85                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
86         if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) 
87                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
88         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) 
89                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM2\n"));
90         if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) 
91                 DEBUGADD(4, ("  NTLMSSP_CHAL_TARGET_INFO\n"));
92         if (neg_flags & NTLMSSP_NEGOTIATE_128) 
93                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_128\n"));
94         if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) 
95                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
96 }
97
98 /**
99  * Default challenge generation code.
100  *
101  */
102    
103 static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state)
104 {
105         static uchar chal[8];
106         generate_random_buffer(chal, sizeof(chal), False);
107
108         return chal;
109 }
110
111 /**
112  * Default 'we can set the challenge to anything we like' implementation
113  *
114  */
115    
116 static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
117 {
118         return True;
119 }
120
121 /**
122  * Default 'we can set the challenge to anything we like' implementation
123  *
124  * Does not actually do anything, as the value is always in the structure anyway.
125  *
126  */
127    
128 static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
129 {
130         SMB_ASSERT(challenge->length == 8);
131         return NT_STATUS_OK;
132 }
133
134 /** 
135  * Set a username on an NTLMSSP context - ensures it is talloc()ed 
136  *
137  */
138
139 NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) 
140 {
141         ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user);
142         if (!ntlmssp_state->user) {
143                 return NT_STATUS_NO_MEMORY;
144         }
145         return NT_STATUS_OK;
146 }
147
148 /** 
149  * Set a password on an NTLMSSP context - ensures it is talloc()ed 
150  *
151  */
152 NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) 
153 {
154         if (!password) {
155                 ntlmssp_state->password = NULL;
156         } else {
157                 ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password);
158                 if (!ntlmssp_state->password) {
159                         return NT_STATUS_NO_MEMORY;
160                 }
161         }
162         return NT_STATUS_OK;
163 }
164
165 /** 
166  * Set a domain on an NTLMSSP context - ensures it is talloc()ed 
167  *
168  */
169 NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) 
170 {
171         ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain);
172         if (!ntlmssp_state->domain) {
173                 return NT_STATUS_NO_MEMORY;
174         }
175         return NT_STATUS_OK;
176 }
177
178 /** 
179  * Set a workstation on an NTLMSSP context - ensures it is talloc()ed 
180  *
181  */
182 NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) 
183 {
184         ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation);
185         if (!ntlmssp_state->domain) {
186                 return NT_STATUS_NO_MEMORY;
187         }
188         return NT_STATUS_OK;
189 }
190
191 /**
192  *  Store a DATA_BLOB containing an NTLMSSP response, for use later.
193  *  This copies the data blob
194  */
195
196 NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,
197                                 DATA_BLOB response) 
198 {
199         ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx, 
200                                                           response.data, response.length);
201         return NT_STATUS_OK;
202 }
203
204 /**
205  * Next state function for the NTLMSSP state machine
206  * 
207  * @param ntlmssp_state NTLMSSP State
208  * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
209  * @param out The reply, as an allocated DATA_BLOB, caller to free.
210  * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. 
211  */
212
213 NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, 
214                         const DATA_BLOB in, DATA_BLOB *out) 
215 {
216         DATA_BLOB input;
217         uint32 ntlmssp_command;
218         int i;
219
220         *out = data_blob(NULL, 0);
221
222         if (!in.length && ntlmssp_state->stored_response.length) {
223                 input = ntlmssp_state->stored_response;
224                 
225                 /* we only want to read the stored response once - overwrite it */
226                 ntlmssp_state->stored_response = data_blob(NULL, 0);
227         } else {
228                 input = in;
229         }
230
231         if (!input.length) {
232                 switch (ntlmssp_state->role) {
233                 case NTLMSSP_CLIENT:
234                         ntlmssp_command = NTLMSSP_INITIAL;
235                         break;
236                 case NTLMSSP_SERVER:
237                         /* 'datagram' mode - no neg packet */
238                         ntlmssp_command = NTLMSSP_NEGOTIATE;
239                         break;
240                 }
241         } else {
242                 if (!msrpc_parse(&input, "Cd",
243                                  "NTLMSSP",
244                                  &ntlmssp_command)) {
245                         DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
246                         dump_data(2, (const char *)input.data, input.length);
247                         return NT_STATUS_INVALID_PARAMETER;
248                 }
249         }
250
251         if (ntlmssp_command != ntlmssp_state->expected_state) {
252                 DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
253                 return NT_STATUS_INVALID_PARAMETER;
254         }
255
256         for (i=0; ntlmssp_callbacks[i].fn; i++) {
257                 if (ntlmssp_callbacks[i].role == ntlmssp_state->role 
258                     && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) {
259                         return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out);
260                 }
261         }
262
263         DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", 
264                   ntlmssp_state->role, ntlmssp_command)); 
265
266         return NT_STATUS_INVALID_PARAMETER;
267 }
268
269 /**
270  * End an NTLMSSP state machine
271  * 
272  * @param ntlmssp_state NTLMSSP State, free()ed by this function
273  */
274
275 void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state)
276 {
277         TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;
278
279         (*ntlmssp_state)->ref_count--;
280
281         if ((*ntlmssp_state)->ref_count == 0) {
282                 data_blob_free(&(*ntlmssp_state)->chal);
283                 data_blob_free(&(*ntlmssp_state)->lm_resp);
284                 data_blob_free(&(*ntlmssp_state)->nt_resp);
285
286                 talloc_destroy(mem_ctx);
287         }
288
289         *ntlmssp_state = NULL;
290         return;
291 }
292
293 /**
294  * Determine correct target name flags for reply, given server role 
295  * and negotiated flags
296  * 
297  * @param ntlmssp_state NTLMSSP State
298  * @param neg_flags The flags from the packet
299  * @param chal_flags The flags to be set in the reply packet
300  * @return The 'target name' string.
301  */
302
303 static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
304                                        uint32 neg_flags, uint32 *chal_flags) 
305 {
306         if (neg_flags & NTLMSSP_REQUEST_TARGET) {
307                 *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
308                 *chal_flags |= NTLMSSP_REQUEST_TARGET;
309                 if (ntlmssp_state->server_role == ROLE_STANDALONE) {
310                         *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
311                         return ntlmssp_state->get_global_myname();
312                 } else {
313                         *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
314                         return ntlmssp_state->get_domain();
315                 };
316         } else {
317                 return "";
318         }
319 }
320
321 static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
322                                       uint32 neg_flags, BOOL allow_lm) {
323         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
324                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
325                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
326                 ntlmssp_state->unicode = True;
327         } else {
328                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
329                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
330                 ntlmssp_state->unicode = False;
331         }
332
333         if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) {
334                 /* other end forcing us to use LM */
335                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
336                 ntlmssp_state->use_ntlmv2 = False;
337         } else {
338                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
339         }
340
341         if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
342                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
343         }
344
345         if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
346                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
347         }
348
349         if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
350                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
351         }
352
353         if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
354                 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
355         }
356         
357 }
358
359
360 /**
361  * Next state function for the Negotiate packet
362  * 
363  * @param ntlmssp_state NTLMSSP State
364  * @param request The request, as a DATA_BLOB
365  * @param request The reply, as an allocated DATA_BLOB, caller to free.
366  * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. 
367  */
368
369 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
370                                          const DATA_BLOB request, DATA_BLOB *reply) 
371 {
372         DATA_BLOB struct_blob;
373         fstring dnsname, dnsdomname;
374         uint32 neg_flags = 0;
375         uint32 ntlmssp_command, chal_flags;
376         char *cliname=NULL, *domname=NULL;
377         const uint8 *cryptkey;
378         const char *target_name;
379
380         /* parse the NTLMSSP packet */
381 #if 0
382         file_save("ntlmssp_negotiate.dat", request.data, request.length);
383 #endif
384
385         if (request.length) {
386                 if (!msrpc_parse(&request, "CddAA",
387                                  "NTLMSSP",
388                                  &ntlmssp_command,
389                                  &neg_flags,
390                                  &cliname,
391                                  &domname)) {
392                         DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
393                         dump_data(2, (const char *)request.data, request.length);
394                         return NT_STATUS_INVALID_PARAMETER;
395                 }
396                 
397                 SAFE_FREE(cliname);
398                 SAFE_FREE(domname);
399                 
400                 debug_ntlmssp_flags(neg_flags);
401         }
402         
403         ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());
404
405         /* Ask our caller what challenge they would like in the packet */
406         cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
407
408         /* Check if we may set the challenge */
409         if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
410                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
411         }
412
413         /* The flags we send back are not just the negotiated flags,
414          * they are also 'what is in this packet'.  Therfore, we
415          * operate on 'chal_flags' from here on 
416          */
417
418         chal_flags = ntlmssp_state->neg_flags;
419
420         /* get the right name to fill in as 'target' */
421         target_name = ntlmssp_target_name(ntlmssp_state, 
422                                           neg_flags, &chal_flags); 
423         if (target_name == NULL) 
424                 return NT_STATUS_INVALID_PARAMETER;
425
426         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
427         ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
428         
429
430         /* This should be a 'netbios domain -> DNS domain' mapping */
431         dnsdomname[0] = '\0';
432         get_mydomname(dnsdomname);
433         strlower_m(dnsdomname);
434         
435         dnsname[0] = '\0';
436         get_myfullname(dnsname);
437         strlower_m(dnsname);
438         
439         /* This creates the 'blob' of names that appears at the end of the packet */
440         if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) 
441         {
442                 const char *target_name_dns = "";
443                 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
444                         target_name_dns = dnsdomname;
445                 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
446                         target_name_dns = dnsname;
447                 }
448
449                 msrpc_gen(&struct_blob, "aaaaa",
450                           NTLMSSP_NAME_TYPE_DOMAIN, target_name,
451                           NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
452                           NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
453                           NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
454                           0, "");
455         } else {
456                 struct_blob = data_blob(NULL, 0);
457         }
458
459         {
460                 /* Marshel the packet in the right format, be it unicode or ASCII */
461                 const char *gen_string;
462                 if (ntlmssp_state->unicode) {
463                         gen_string = "CdUdbddB";
464                 } else {
465                         gen_string = "CdAdbddB";
466                 }
467                 
468                 msrpc_gen(reply, gen_string,
469                           "NTLMSSP", 
470                           NTLMSSP_CHALLENGE,
471                           target_name,
472                           chal_flags,
473                           cryptkey, 8,
474                           0, 0,
475                           struct_blob.data, struct_blob.length);
476         }
477                 
478         data_blob_free(&struct_blob);
479
480         ntlmssp_state->expected_state = NTLMSSP_AUTH;
481
482         return NT_STATUS_MORE_PROCESSING_REQUIRED;
483 }
484
485 /**
486  * Next state function for the Authenticate packet
487  * 
488  * @param ntlmssp_state NTLMSSP State
489  * @param request The request, as a DATA_BLOB
490  * @param request The reply, as an allocated DATA_BLOB, caller to free.
491  * @return Errors or NT_STATUS_OK. 
492  */
493
494 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
495                                     const DATA_BLOB request, DATA_BLOB *reply) 
496 {
497         DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
498         DATA_BLOB nt_session_key = data_blob(NULL, 0);
499         DATA_BLOB lm_session_key = data_blob(NULL, 0);
500         DATA_BLOB session_key = data_blob(NULL, 0);
501         uint32 ntlmssp_command, auth_flags;
502         NTSTATUS nt_status;
503
504         /* used by NTLM2 */
505         BOOL doing_ntlm2 = False;
506
507         uchar session_nonce[16];
508         uchar session_nonce_hash[16];
509
510         const char *parse_string;
511         char *domain = NULL;
512         char *user = NULL;
513         char *workstation = NULL;
514
515         /* parse the NTLMSSP packet */
516         *reply = data_blob(NULL, 0);
517
518 #if 0
519         file_save("ntlmssp_auth.dat", request.data, request.length);
520 #endif
521
522         if (ntlmssp_state->unicode) {
523                 parse_string = "CdBBUUUBd";
524         } else {
525                 parse_string = "CdBBAAABd";
526         }
527
528         data_blob_free(&ntlmssp_state->lm_resp);
529         data_blob_free(&ntlmssp_state->nt_resp);
530
531         ntlmssp_state->user = NULL;
532         ntlmssp_state->domain = NULL;
533         ntlmssp_state->workstation = NULL;
534
535         /* now the NTLMSSP encoded auth hashes */
536         if (!msrpc_parse(&request, parse_string,
537                          "NTLMSSP", 
538                          &ntlmssp_command, 
539                          &ntlmssp_state->lm_resp,
540                          &ntlmssp_state->nt_resp,
541                          &domain, 
542                          &user, 
543                          &workstation,
544                          &encrypted_session_key,
545                          &auth_flags)) {
546                 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
547                 dump_data(2, (const char *)request.data, request.length);
548                 SAFE_FREE(domain);
549                 SAFE_FREE(user);
550                 SAFE_FREE(workstation);
551                 data_blob_free(&encrypted_session_key);
552                 auth_flags = 0;
553                 
554                 /* Try again with a shorter string (Win9X truncates this packet) */
555                 if (ntlmssp_state->unicode) {
556                         parse_string = "CdBBUUU";
557                 } else {
558                         parse_string = "CdBBAAA";
559                 }
560
561                 /* now the NTLMSSP encoded auth hashes */
562                 if (!msrpc_parse(&request, parse_string,
563                                  "NTLMSSP", 
564                                  &ntlmssp_command, 
565                                  &ntlmssp_state->lm_resp,
566                                  &ntlmssp_state->nt_resp,
567                                  &domain, 
568                                  &user, 
569                                  &workstation)) {
570                         DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
571                         dump_data(2, (const char *)request.data, request.length);
572                         SAFE_FREE(domain);
573                         SAFE_FREE(user);
574                         SAFE_FREE(workstation);
575
576                         return NT_STATUS_INVALID_PARAMETER;
577                 }
578         }
579
580         if (auth_flags)
581                 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth());
582
583         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
584                 SAFE_FREE(domain);
585                 SAFE_FREE(user);
586                 SAFE_FREE(workstation);
587                 data_blob_free(&encrypted_session_key);
588                 return nt_status;
589         }
590
591         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
592                 SAFE_FREE(domain);
593                 SAFE_FREE(user);
594                 SAFE_FREE(workstation);
595                 data_blob_free(&encrypted_session_key);
596                 return nt_status;
597         }
598
599         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
600                 SAFE_FREE(domain);
601                 SAFE_FREE(user);
602                 SAFE_FREE(workstation);
603                 data_blob_free(&encrypted_session_key);
604                 return nt_status;
605         }
606
607         SAFE_FREE(domain);
608         SAFE_FREE(user);
609         SAFE_FREE(workstation);
610
611         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
612                  ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
613
614 #if 0
615         file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
616         file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
617 #endif
618
619         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a 
620            client challenge 
621         
622            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
623         */
624         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
625                 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
626                         struct MD5Context md5_session_nonce_ctx;
627                         SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
628                         
629                         doing_ntlm2 = True;
630
631                         memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
632                         memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
633                         
634                         MD5Init(&md5_session_nonce_ctx);
635                         MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
636                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
637                         
638                         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8);
639
640                         /* LM response is no longer useful */
641                         data_blob_free(&ntlmssp_state->lm_resp);
642
643                         /* We changed the effective challenge - set it */
644                         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
645                                 data_blob_free(&encrypted_session_key);
646                                 return nt_status;
647                         }
648                 }
649         }
650
651         /*
652          * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
653          * is required (by "ntlm auth = no" and "lm auth = no" being set in the
654          * smb.conf file) and no NTLMv2 response was sent then the password check
655          * will fail here. JRA.
656          */
657
658         /* Finally, actually ask if the password is OK */
659
660         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) {
661                 data_blob_free(&encrypted_session_key);
662                 return nt_status;
663         }
664
665         dump_data_pw("NT session key:\n", nt_session_key.data, nt_session_key.length);
666         dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
667
668         /* Handle the different session key derivation for NTLM2 */
669         if (doing_ntlm2) {
670                 if (nt_session_key.data && nt_session_key.length == 16) {
671                         session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
672                         hmac_md5(nt_session_key.data, session_nonce, 
673                                  sizeof(session_nonce), session_key.data);
674                         DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
675                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
676                         
677                 } else {
678                         data_blob_free(&encrypted_session_key);
679                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
680                         return NT_STATUS_INVALID_PARAMETER;
681                 }
682         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
683                 if (lm_session_key.data && lm_session_key.length >= 8) {
684                         if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
685                                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
686                                 SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, 
687                                                           session_key.data);
688                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
689                                 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
690                         } else {
691                                 /* use the key unmodified - it's
692                                  * probably a NULL key from the guest
693                                  * login */
694                                 session_key = lm_session_key;
695                         }
696                 } else {
697                         data_blob_free(&encrypted_session_key);
698                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
699                         return NT_STATUS_INVALID_PARAMETER;
700                 }
701         } else if (nt_session_key.data) {
702                 session_key = nt_session_key;
703                 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
704                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
705         } else if (lm_session_key.data) {
706                 session_key = lm_session_key;
707                 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
708                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
709         } else {
710                 data_blob_free(&encrypted_session_key);
711                 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
712                 return NT_STATUS_INVALID_PARAMETER;
713         }
714
715         /* With KEY_EXCH, the client supplies the proposed session key, 
716            but encrypts it with the long-term key */
717         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
718                 if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
719                         data_blob_free(&encrypted_session_key);
720                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", 
721                                   encrypted_session_key.length));
722                         return NT_STATUS_INVALID_PARAMETER;
723                 } else if (!session_key.data || session_key.length != 16) {
724                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", 
725                                   session_key.length));
726                 } else {
727                         dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
728                         SamOEMhash(encrypted_session_key.data, 
729                                    session_key.data, 
730                                    encrypted_session_key.length);
731                         ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, 
732                                                                       encrypted_session_key.data, 
733                                                                       encrypted_session_key.length);
734                         dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, 
735                                 encrypted_session_key.length);
736                 }
737         } else {
738                 ntlmssp_state->session_key = session_key;
739         }
740
741         data_blob_free(&encrypted_session_key);
742         
743         /* allow arbitarily many authentications */
744         ntlmssp_state->expected_state = NTLMSSP_AUTH;
745
746         return nt_status;
747 }
748
749 /**
750  * Create an NTLMSSP state machine
751  * 
752  * @param ntlmssp_state NTLMSSP State, allocated by this function
753  */
754
755 NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
756 {
757         TALLOC_CTX *mem_ctx;
758
759         mem_ctx = talloc_init("NTLMSSP context");
760         
761         *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
762         if (!*ntlmssp_state) {
763                 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
764                 talloc_destroy(mem_ctx);
765                 return NT_STATUS_NO_MEMORY;
766         }
767
768         (*ntlmssp_state)->role = NTLMSSP_SERVER;
769
770         (*ntlmssp_state)->mem_ctx = mem_ctx;
771         (*ntlmssp_state)->get_challenge = get_challenge;
772         (*ntlmssp_state)->set_challenge = set_challenge;
773         (*ntlmssp_state)->may_set_challenge = may_set_challenge;
774
775         (*ntlmssp_state)->get_global_myname = global_myname;
776         (*ntlmssp_state)->get_domain = lp_workgroup;
777         (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
778
779         (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
780
781         (*ntlmssp_state)->ref_count = 1;
782
783         (*ntlmssp_state)->neg_flags = 
784                 NTLMSSP_NEGOTIATE_128 |
785                 NTLMSSP_NEGOTIATE_NTLM |
786                 NTLMSSP_NEGOTIATE_NTLM2 |
787                 NTLMSSP_NEGOTIATE_KEY_EXCH |
788                 NTLMSSP_NEGOTIATE_SIGN;
789
790         return NT_STATUS_OK;
791 }
792
793 /*********************************************************************
794  Client side NTLMSSP
795 *********************************************************************/
796
797 /**
798  * Next state function for the Initial packet
799  * 
800  * @param ntlmssp_state NTLMSSP State
801  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
802  * @param request The reply, as an allocated DATA_BLOB, caller to free.
803  * @return Errors or NT_STATUS_OK. 
804  */
805
806 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
807                                   DATA_BLOB reply, DATA_BLOB *next_request) 
808 {
809         if (ntlmssp_state->unicode) {
810                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
811         } else {
812                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
813         }
814         
815         if (ntlmssp_state->use_ntlmv2) {
816                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
817         }
818
819         /* generate the ntlmssp negotiate packet */
820         msrpc_gen(next_request, "CddAA",
821                   "NTLMSSP",
822                   NTLMSSP_NEGOTIATE,
823                   ntlmssp_state->neg_flags,
824                   ntlmssp_state->get_domain(), 
825                   ntlmssp_state->get_global_myname());
826
827         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
828
829         return NT_STATUS_MORE_PROCESSING_REQUIRED;
830 }
831
832 /**
833  * Next state function for the Challenge Packet.  Generate an auth packet.
834  * 
835  * @param ntlmssp_state NTLMSSP State
836  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
837  * @param request The reply, as an allocated DATA_BLOB, caller to free.
838  * @return Errors or NT_STATUS_OK. 
839  */
840
841 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
842                                          const DATA_BLOB reply, DATA_BLOB *next_request) 
843 {
844         uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
845         DATA_BLOB server_domain_blob;
846         DATA_BLOB challenge_blob;
847         DATA_BLOB struct_blob = data_blob(NULL, 0);
848         char *server_domain;
849         const char *chal_parse_string;
850         const char *auth_gen_string;
851         DATA_BLOB lm_response = data_blob(NULL, 0);
852         DATA_BLOB nt_response = data_blob(NULL, 0);
853         DATA_BLOB session_key = data_blob(NULL, 0);
854         DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
855         NTSTATUS nt_status;
856
857         if (!msrpc_parse(&reply, "CdBd",
858                          "NTLMSSP",
859                          &ntlmssp_command, 
860                          &server_domain_blob,
861                          &chal_flags)) {
862                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
863                 dump_data(2, (const char *)reply.data, reply.length);
864
865                 return NT_STATUS_INVALID_PARAMETER;
866         }
867         
868         data_blob_free(&server_domain_blob);
869
870         DEBUG(3, ("Got challenge flags:\n"));
871         debug_ntlmssp_flags(chal_flags);
872
873         ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
874
875         if (ntlmssp_state->unicode) {
876                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
877                         chal_parse_string = "CdUdbddB";
878                 } else {
879                         chal_parse_string = "CdUdbdd";
880                 }
881                 auth_gen_string = "CdBBUUUBd";
882         } else {
883                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
884                         chal_parse_string = "CdAdbddB";
885                 } else {
886                         chal_parse_string = "CdAdbdd";
887                 }
888
889                 auth_gen_string = "CdBBAAABd";
890         }
891
892         DEBUG(3, ("NTLMSSP: Set final flags:\n"));
893         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
894
895         if (!msrpc_parse(&reply, chal_parse_string,
896                          "NTLMSSP",
897                          &ntlmssp_command, 
898                          &server_domain,
899                          &chal_flags,
900                          &challenge_blob, 8,
901                          &unkn1, &unkn2,
902                          &struct_blob)) {
903                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
904                 dump_data(2, (const char *)reply.data, reply.length);
905                 return NT_STATUS_INVALID_PARAMETER;
906         }
907
908         ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx,
909                                                      server_domain);
910
911         SAFE_FREE(server_domain);
912         if (challenge_blob.length != 8) {
913                 data_blob_free(&struct_blob);
914                 return NT_STATUS_INVALID_PARAMETER;
915         }
916
917         if (!ntlmssp_state->password) {
918                 /* do nothing - blobs are zero length */
919         } else if (ntlmssp_state->use_ntlmv2) {
920
921                 if (!struct_blob.length) {
922                         /* be lazy, match win2k - we can't do NTLMv2 without it */
923                         DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
924                         return NT_STATUS_INVALID_PARAMETER;
925                 }
926
927                 /* TODO: if the remote server is standalone, then we should replace 'domain'
928                    with the server name as supplied above */
929                 
930                 if (!SMBNTLMv2encrypt(ntlmssp_state->user, 
931                                       ntlmssp_state->domain, 
932                                       ntlmssp_state->password, &challenge_blob, 
933                                       &struct_blob, 
934                                       &lm_response, &nt_response, &session_key)) {
935                         data_blob_free(&challenge_blob);
936                         data_blob_free(&struct_blob);
937                         return NT_STATUS_NO_MEMORY;
938                 }
939         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
940                 struct MD5Context md5_session_nonce_ctx;
941                 uchar nt_hash[16];
942                 uchar session_nonce[16];
943                 uchar session_nonce_hash[16];
944                 uchar nt_session_key[16];
945                 E_md4hash(ntlmssp_state->password, nt_hash);
946                 
947                 lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
948                 generate_random_buffer(lm_response.data, 8, False);
949                 memset(lm_response.data+8, 0, 16);
950
951                 memcpy(session_nonce, challenge_blob.data, 8);
952                 memcpy(&session_nonce[8], lm_response.data, 8);
953         
954                 MD5Init(&md5_session_nonce_ctx);
955                 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
956                 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
957                 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
958
959                 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
960                 DEBUG(5, ("challenge is: \n"));
961                 dump_data(5, session_nonce_hash, 8);
962                 
963                 nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
964                 SMBNTencrypt(ntlmssp_state->password,
965                              session_nonce_hash,
966                              nt_response.data);
967
968                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
969
970                 SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key);
971                 hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data);
972                 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
973         } else {
974                 
975                 
976                 uchar lm_hash[16];
977                 uchar nt_hash[16];
978                 E_deshash(ntlmssp_state->password, lm_hash);
979                 E_md4hash(ntlmssp_state->password, nt_hash);
980                 
981                 /* lanman auth is insecure, it may be disabled */
982                 if (lp_client_lanman_auth()) {
983                         lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
984                         SMBencrypt(ntlmssp_state->password,challenge_blob.data,
985                                    lm_response.data);
986                 }
987                 
988                 nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
989                 SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
990                              nt_response.data);
991                 
992                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
993                 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
994                     && lp_client_lanman_auth()) {
995                         SMBsesskeygen_lmv1(lm_hash, lm_response.data, 
996                                            session_key.data);
997                         dump_data_pw("LM session key\n", session_key.data, session_key.length);
998                 } else {
999                         SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
1000                         dump_data_pw("NT session key:\n", session_key.data, session_key.length);
1001                 }
1002         }
1003         data_blob_free(&struct_blob);
1004
1005         /* Key exchange encryptes a new client-generated session key with
1006            the password-derived key */
1007         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1008                 uint8 client_session_key[16];
1009                 
1010                 generate_random_buffer(client_session_key, sizeof(client_session_key), False);  
1011                 encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
1012                 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
1013
1014                 SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
1015                 data_blob_free(&session_key);
1016                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key));
1017                 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
1018         }
1019
1020         /* this generates the actual auth packet */
1021         if (!msrpc_gen(next_request, auth_gen_string, 
1022                        "NTLMSSP", 
1023                        NTLMSSP_AUTH, 
1024                        lm_response.data, lm_response.length,
1025                        nt_response.data, nt_response.length,
1026                        ntlmssp_state->domain, 
1027                        ntlmssp_state->user, 
1028                        ntlmssp_state->get_global_myname(), 
1029                        encrypted_session_key.data, encrypted_session_key.length,
1030                        ntlmssp_state->neg_flags)) {
1031                 
1032                 return NT_STATUS_NO_MEMORY;
1033         }
1034
1035         data_blob_free(&encrypted_session_key);
1036
1037         data_blob_free(&ntlmssp_state->chal);
1038
1039         ntlmssp_state->chal = challenge_blob;
1040         ntlmssp_state->lm_resp = lm_response;
1041         ntlmssp_state->nt_resp = nt_response;
1042         ntlmssp_state->session_key = session_key;
1043
1044         ntlmssp_state->expected_state = NTLMSSP_UNKNOWN;
1045
1046         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
1047                 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
1048                 return nt_status;
1049         }
1050
1051         return NT_STATUS_MORE_PROCESSING_REQUIRED;
1052 }
1053
1054 NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
1055 {
1056         TALLOC_CTX *mem_ctx;
1057
1058         mem_ctx = talloc_init("NTLMSSP Client context");
1059         
1060         *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
1061         if (!*ntlmssp_state) {
1062                 DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
1063                 talloc_destroy(mem_ctx);
1064                 return NT_STATUS_NO_MEMORY;
1065         }
1066
1067         (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1068
1069         (*ntlmssp_state)->mem_ctx = mem_ctx;
1070
1071         (*ntlmssp_state)->get_global_myname = global_myname;
1072         (*ntlmssp_state)->get_domain = lp_workgroup;
1073
1074         (*ntlmssp_state)->unicode = True;
1075
1076         (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1077
1078         (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1079
1080         (*ntlmssp_state)->ref_count = 1;
1081
1082         (*ntlmssp_state)->neg_flags = 
1083                 NTLMSSP_NEGOTIATE_128 |
1084                 NTLMSSP_NEGOTIATE_NTLM |
1085                 NTLMSSP_NEGOTIATE_NTLM2 |
1086                 NTLMSSP_NEGOTIATE_KEY_EXCH |
1087                 /*
1088                  * We need to set this to allow a later SetPassword
1089                  * via the SAMR pipe to succeed. Strange.... We could
1090                  * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
1091                  * */
1092                 NTLMSSP_NEGOTIATE_SIGN |
1093                 NTLMSSP_REQUEST_TARGET;
1094
1095         return NT_STATUS_OK;
1096 }
1097