Merge from 3.0:
[kai/samba.git] / source3 / libsmb / ntlmssp.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    handle NLTMSSP, server side
5
6    Copyright (C) Andrew Tridgell      2001
7    Copyright (C) Andrew Bartlett 2001-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 (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
581                 SAFE_FREE(domain);
582                 SAFE_FREE(user);
583                 SAFE_FREE(workstation);
584                 data_blob_free(&encrypted_session_key);
585                 return nt_status;
586         }
587
588         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
589                 SAFE_FREE(domain);
590                 SAFE_FREE(user);
591                 SAFE_FREE(workstation);
592                 data_blob_free(&encrypted_session_key);
593                 return nt_status;
594         }
595
596         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
597                 SAFE_FREE(domain);
598                 SAFE_FREE(user);
599                 SAFE_FREE(workstation);
600                 data_blob_free(&encrypted_session_key);
601                 return nt_status;
602         }
603
604         SAFE_FREE(domain);
605         SAFE_FREE(user);
606         SAFE_FREE(workstation);
607
608         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
609                  ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
610
611 #if 0
612         file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
613         file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
614 #endif
615
616         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a 
617            client challenge 
618         
619            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
620         */
621         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
622                 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
623                         struct MD5Context md5_session_nonce_ctx;
624                         SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
625                         
626                         doing_ntlm2 = True;
627
628                         memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
629                         memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
630                         
631                         MD5Init(&md5_session_nonce_ctx);
632                         MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
633                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
634                         
635                         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8);
636
637                         /* LM response is no longer useful */
638                         data_blob_free(&ntlmssp_state->lm_resp);
639
640                         /* We changed the effective challenge - set it */
641                         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
642                                 data_blob_free(&encrypted_session_key);
643                                 return nt_status;
644                         }
645                 }
646         }
647
648         /* Finally, actually ask if the password is OK */
649         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) {
650                 data_blob_free(&encrypted_session_key);
651                 return nt_status;
652         }
653
654         dump_data_pw("NT session key:\n", nt_session_key.data, nt_session_key.length);
655         dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
656
657         /* Handle the different session key derivation for NTLM2 */
658         if (doing_ntlm2) {
659                 if (nt_session_key.data && nt_session_key.length == 16) {
660                         session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
661                         hmac_md5(nt_session_key.data, session_nonce, 
662                                  sizeof(session_nonce), session_key.data);
663                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
664
665                 }
666         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
667                 if (lm_session_key.data && lm_session_key.length >= 8 && 
668                     ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
669                         session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
670                         SMBsesskeygen_lmv1(lm_session_key.data, ntlmssp_state->lm_resp.data, 
671                                            session_key.data);
672                         dump_data_pw("LM session key:\n", session_key.data, session_key.length);
673                 }
674         } else if (nt_session_key.data) {
675                 session_key = nt_session_key;
676                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
677         }
678
679         /* With KEY_EXCH, the client supplies the proposed session key, 
680            but encrypts it with the long-term key */
681         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
682                 if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
683                         data_blob_free(&encrypted_session_key);
684                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", 
685                                   encrypted_session_key.length));
686                         return NT_STATUS_INVALID_PARAMETER;
687                 } else if (!session_key.data || session_key.length != 16) {
688                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", 
689                                   session_key.length));
690                 } else {
691                         dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
692                         SamOEMhash(encrypted_session_key.data, 
693                                    session_key.data, 
694                                    encrypted_session_key.length);
695                         ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, 
696                                                                       encrypted_session_key.data, 
697                                                                       encrypted_session_key.length);
698                         dump_data_pw("KEY_EXCH session key:\n", session_key.data, session_key.length);
699                 }
700         } else {
701                 ntlmssp_state->session_key = session_key;
702         }
703
704         data_blob_free(&encrypted_session_key);
705         
706         /* allow arbitarily many authentications */
707         ntlmssp_state->expected_state = NTLMSSP_AUTH;
708
709         return nt_status;
710 }
711
712 /**
713  * Create an NTLMSSP state machine
714  * 
715  * @param ntlmssp_state NTLMSSP State, allocated by this function
716  */
717
718 NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
719 {
720         TALLOC_CTX *mem_ctx;
721
722         mem_ctx = talloc_init("NTLMSSP context");
723         
724         *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
725         if (!*ntlmssp_state) {
726                 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
727                 talloc_destroy(mem_ctx);
728                 return NT_STATUS_NO_MEMORY;
729         }
730
731         (*ntlmssp_state)->role = NTLMSSP_SERVER;
732
733         (*ntlmssp_state)->mem_ctx = mem_ctx;
734         (*ntlmssp_state)->get_challenge = get_challenge;
735         (*ntlmssp_state)->set_challenge = set_challenge;
736         (*ntlmssp_state)->may_set_challenge = may_set_challenge;
737
738         (*ntlmssp_state)->get_global_myname = global_myname;
739         (*ntlmssp_state)->get_domain = lp_workgroup;
740         (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
741
742         (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
743
744         (*ntlmssp_state)->ref_count = 1;
745
746         (*ntlmssp_state)->neg_flags = 
747                 NTLMSSP_NEGOTIATE_128 |
748                 NTLMSSP_NEGOTIATE_NTLM |
749                 NTLMSSP_NEGOTIATE_NTLM2 |
750                 NTLMSSP_NEGOTIATE_KEY_EXCH |
751                 NTLMSSP_NEGOTIATE_SIGN;
752
753         return NT_STATUS_OK;
754 }
755
756 /*********************************************************************
757  Client side NTLMSSP
758 *********************************************************************/
759
760 /**
761  * Next state function for the Initial packet
762  * 
763  * @param ntlmssp_state NTLMSSP State
764  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
765  * @param request The reply, as an allocated DATA_BLOB, caller to free.
766  * @return Errors or NT_STATUS_OK. 
767  */
768
769 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
770                                   DATA_BLOB reply, DATA_BLOB *next_request) 
771 {
772         if (ntlmssp_state->unicode) {
773                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
774         } else {
775                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
776         }
777         
778         if (ntlmssp_state->use_ntlmv2) {
779                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
780         }
781
782         /* generate the ntlmssp negotiate packet */
783         msrpc_gen(next_request, "CddAA",
784                   "NTLMSSP",
785                   NTLMSSP_NEGOTIATE,
786                   ntlmssp_state->neg_flags,
787                   ntlmssp_state->get_domain(), 
788                   ntlmssp_state->get_global_myname());
789
790         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
791
792         return NT_STATUS_MORE_PROCESSING_REQUIRED;
793 }
794
795 /**
796  * Next state function for the Challenge Packet.  Generate an auth packet.
797  * 
798  * @param ntlmssp_state NTLMSSP State
799  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
800  * @param request The reply, as an allocated DATA_BLOB, caller to free.
801  * @return Errors or NT_STATUS_OK. 
802  */
803
804 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
805                                          const DATA_BLOB reply, DATA_BLOB *next_request) 
806 {
807         uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
808         DATA_BLOB server_domain_blob;
809         DATA_BLOB challenge_blob;
810         DATA_BLOB struct_blob = data_blob(NULL, 0);
811         char *server_domain;
812         const char *chal_parse_string;
813         const char *auth_gen_string;
814         DATA_BLOB lm_response = data_blob(NULL, 0);
815         DATA_BLOB nt_response = data_blob(NULL, 0);
816         DATA_BLOB session_key = data_blob(NULL, 0);
817         DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
818         NTSTATUS nt_status;
819
820         if (!msrpc_parse(&reply, "CdBd",
821                          "NTLMSSP",
822                          &ntlmssp_command, 
823                          &server_domain_blob,
824                          &chal_flags)) {
825                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
826                 dump_data(2, (const char *)reply.data, reply.length);
827
828                 return NT_STATUS_INVALID_PARAMETER;
829         }
830         
831         data_blob_free(&server_domain_blob);
832
833         DEBUG(3, ("Got challenge flags:\n"));
834         debug_ntlmssp_flags(chal_flags);
835
836         ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
837
838         if (ntlmssp_state->unicode) {
839                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
840                         chal_parse_string = "CdUdbddB";
841                 } else {
842                         chal_parse_string = "CdUdbdd";
843                 }
844                 auth_gen_string = "CdBBUUUBd";
845         } else {
846                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
847                         chal_parse_string = "CdAdbddB";
848                 } else {
849                         chal_parse_string = "CdAdbdd";
850                 }
851
852                 auth_gen_string = "CdBBAAABd";
853         }
854
855         DEBUG(3, ("NTLMSSP: Set final flags:\n"));
856         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
857
858         if (!msrpc_parse(&reply, chal_parse_string,
859                          "NTLMSSP",
860                          &ntlmssp_command, 
861                          &server_domain,
862                          &chal_flags,
863                          &challenge_blob, 8,
864                          &unkn1, &unkn2,
865                          &struct_blob)) {
866                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
867                 dump_data(2, (const char *)reply.data, reply.length);
868                 return NT_STATUS_INVALID_PARAMETER;
869         }
870
871         ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx,
872                                                      server_domain);
873
874         SAFE_FREE(server_domain);
875         if (challenge_blob.length != 8) {
876                 data_blob_free(&struct_blob);
877                 return NT_STATUS_INVALID_PARAMETER;
878         }
879
880         if (!ntlmssp_state->password) {
881                 /* do nothing - blobs are zero length */
882         } else if (ntlmssp_state->use_ntlmv2) {
883
884                 if (!struct_blob.length) {
885                         /* be lazy, match win2k - we can't do NTLMv2 without it */
886                         DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
887                         return NT_STATUS_INVALID_PARAMETER;
888                 }
889
890                 /* TODO: if the remote server is standalone, then we should replace 'domain'
891                    with the server name as supplied above */
892                 
893                 if (!SMBNTLMv2encrypt(ntlmssp_state->user, 
894                                       ntlmssp_state->domain, 
895                                       ntlmssp_state->password, &challenge_blob, 
896                                       &struct_blob, 
897                                       &lm_response, &nt_response, &session_key)) {
898                         data_blob_free(&challenge_blob);
899                         data_blob_free(&struct_blob);
900                         return NT_STATUS_NO_MEMORY;
901                 }
902         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
903                 struct MD5Context md5_session_nonce_ctx;
904                 uchar nt_hash[16];
905                 uchar session_nonce[16];
906                 uchar session_nonce_hash[16];
907                 uchar nt_session_key[16];
908                 E_md4hash(ntlmssp_state->password, nt_hash);
909                 
910                 lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
911                 generate_random_buffer(lm_response.data, 8, False);
912                 memset(lm_response.data+8, 0, 16);
913
914                 memcpy(session_nonce, challenge_blob.data, 8);
915                 memcpy(&session_nonce[8], lm_response.data, 8);
916         
917                 MD5Init(&md5_session_nonce_ctx);
918                 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
919                 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
920                 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
921
922                 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
923                 DEBUG(5, ("challenge is: \n"));
924                 dump_data(5, session_nonce_hash, 8);
925                 
926                 nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
927                 SMBNTencrypt(ntlmssp_state->password,
928                              session_nonce_hash,
929                              nt_response.data);
930
931                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
932
933                 SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key);
934                 hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data);
935                 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
936         } else {
937                 
938                 
939                 uchar lm_hash[16];
940                 uchar nt_hash[16];
941                 E_deshash(ntlmssp_state->password, lm_hash);
942                 E_md4hash(ntlmssp_state->password, nt_hash);
943                 
944                 /* lanman auth is insecure, it may be disabled */
945                 if (lp_client_lanman_auth()) {
946                         lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
947                         SMBencrypt(ntlmssp_state->password,challenge_blob.data,
948                                    lm_response.data);
949                 }
950                 
951                 nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
952                 SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
953                              nt_response.data);
954                 
955                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
956                 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
957                     && lp_client_lanman_auth()) {
958                         SMBsesskeygen_lmv1(lm_hash, lm_response.data, 
959                                            session_key.data);
960                         dump_data_pw("LM session key\n", session_key.data, session_key.length);
961                 } else {
962                         SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
963                         dump_data_pw("NT session key:\n", session_key.data, session_key.length);
964                 }
965         }
966         data_blob_free(&struct_blob);
967
968         /* Key exchange encryptes a new client-generated session key with
969            the password-derived key */
970         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
971                 uint8 client_session_key[16];
972                 
973                 generate_random_buffer(client_session_key, sizeof(client_session_key), False);  
974                 encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
975                 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
976
977                 SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
978                 data_blob_free(&session_key);
979                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key));
980                 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
981         }
982
983         /* this generates the actual auth packet */
984         if (!msrpc_gen(next_request, auth_gen_string, 
985                        "NTLMSSP", 
986                        NTLMSSP_AUTH, 
987                        lm_response.data, lm_response.length,
988                        nt_response.data, nt_response.length,
989                        ntlmssp_state->domain, 
990                        ntlmssp_state->user, 
991                        ntlmssp_state->get_global_myname(), 
992                        encrypted_session_key.data, encrypted_session_key.length,
993                        ntlmssp_state->neg_flags)) {
994                 
995                 return NT_STATUS_NO_MEMORY;
996         }
997
998         data_blob_free(&encrypted_session_key);
999
1000         data_blob_free(&ntlmssp_state->chal);
1001
1002         ntlmssp_state->chal = challenge_blob;
1003         ntlmssp_state->lm_resp = lm_response;
1004         ntlmssp_state->nt_resp = nt_response;
1005         ntlmssp_state->session_key = session_key;
1006
1007         ntlmssp_state->expected_state = NTLMSSP_UNKNOWN;
1008
1009         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
1010                 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
1011                 return nt_status;
1012         }
1013
1014         return NT_STATUS_MORE_PROCESSING_REQUIRED;
1015 }
1016
1017 NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
1018 {
1019         TALLOC_CTX *mem_ctx;
1020
1021         mem_ctx = talloc_init("NTLMSSP Client context");
1022         
1023         *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
1024         if (!*ntlmssp_state) {
1025                 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
1026                 talloc_destroy(mem_ctx);
1027                 return NT_STATUS_NO_MEMORY;
1028         }
1029
1030         (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1031
1032         (*ntlmssp_state)->mem_ctx = mem_ctx;
1033
1034         (*ntlmssp_state)->get_global_myname = global_myname;
1035         (*ntlmssp_state)->get_domain = lp_workgroup;
1036
1037         (*ntlmssp_state)->unicode = True;
1038
1039         (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1040
1041         (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1042
1043         (*ntlmssp_state)->ref_count = 1;
1044
1045         (*ntlmssp_state)->neg_flags = 
1046                 NTLMSSP_NEGOTIATE_128 |
1047                 NTLMSSP_NEGOTIATE_NTLM |
1048                 NTLMSSP_NEGOTIATE_NTLM2 |
1049                 NTLMSSP_NEGOTIATE_KEY_EXCH |
1050                 /*
1051                  * We need to set this to allow a later SetPassword
1052                  * via the SAMR pipe to succeed. Strange.... We could
1053                  * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
1054                  * */
1055                 NTLMSSP_NEGOTIATE_SIGN |
1056                 NTLMSSP_REQUEST_TARGET;
1057
1058         return NT_STATUS_OK;
1059 }
1060