(merge from 3.0)
[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                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
344         }
345
346         if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
347                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
348         }
349
350         if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
351                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
352         }
353
354         if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
355                 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
356         }
357         
358 }
359
360
361 /**
362  * Next state function for the Negotiate packet
363  * 
364  * @param ntlmssp_state NTLMSSP State
365  * @param request The request, as a DATA_BLOB
366  * @param request The reply, as an allocated DATA_BLOB, caller to free.
367  * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. 
368  */
369
370 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
371                                          const DATA_BLOB request, DATA_BLOB *reply) 
372 {
373         DATA_BLOB struct_blob;
374         fstring dnsname, dnsdomname;
375         uint32 neg_flags = 0;
376         uint32 ntlmssp_command, chal_flags;
377         char *cliname=NULL, *domname=NULL;
378         const uint8 *cryptkey;
379         const char *target_name;
380
381         /* parse the NTLMSSP packet */
382 #if 0
383         file_save("ntlmssp_negotiate.dat", request.data, request.length);
384 #endif
385
386         if (request.length) {
387                 if (!msrpc_parse(&request, "CddAA",
388                                  "NTLMSSP",
389                                  &ntlmssp_command,
390                                  &neg_flags,
391                                  &cliname,
392                                  &domname)) {
393                         DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
394                         dump_data(2, (const char *)request.data, request.length);
395                         return NT_STATUS_INVALID_PARAMETER;
396                 }
397                 
398                 SAFE_FREE(cliname);
399                 SAFE_FREE(domname);
400                 
401                 debug_ntlmssp_flags(neg_flags);
402         }
403         
404         ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());
405
406         chal_flags = ntlmssp_state->neg_flags;
407
408         target_name = ntlmssp_target_name(ntlmssp_state, 
409                                           neg_flags, &chal_flags); 
410         if (target_name == NULL) 
411                 return NT_STATUS_INVALID_PARAMETER;
412
413         /* Ask our caller what challenge they would like in the packet */
414         cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
415
416         /* Check if we may set the challenge */
417         if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
418                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
419         }
420
421         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
422         ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
423         
424
425         /* This should be a 'netbios domain -> DNS domain' mapping */
426         dnsdomname[0] = '\0';
427         get_mydomname(dnsdomname);
428         strlower_m(dnsdomname);
429         
430         dnsname[0] = '\0';
431         get_myfullname(dnsname);
432         strlower_m(dnsname);
433         
434         /* This creates the 'blob' of names that appears at the end of the packet */
435         if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) 
436         {
437                 const char *target_name_dns = "";
438                 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
439                         target_name_dns = dnsdomname;
440                 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
441                         target_name_dns = dnsname;
442                 }
443
444                 msrpc_gen(&struct_blob, "aaaaa",
445                           NTLMSSP_NAME_TYPE_DOMAIN, target_name,
446                           NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
447                           NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
448                           NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
449                           0, "");
450         } else {
451                 struct_blob = data_blob(NULL, 0);
452         }
453
454         {
455                 /* Marshel the packet in the right format, be it unicode or ASCII */
456                 const char *gen_string;
457                 if (ntlmssp_state->unicode) {
458                         gen_string = "CdUdbddB";
459                 } else {
460                         gen_string = "CdAdbddB";
461                 }
462                 
463                 msrpc_gen(reply, gen_string,
464                           "NTLMSSP", 
465                           NTLMSSP_CHALLENGE,
466                           target_name,
467                           chal_flags,
468                           cryptkey, 8,
469                           0, 0,
470                           struct_blob.data, struct_blob.length);
471         }
472                 
473         data_blob_free(&struct_blob);
474
475         ntlmssp_state->expected_state = NTLMSSP_AUTH;
476
477         return NT_STATUS_MORE_PROCESSING_REQUIRED;
478 }
479
480 /**
481  * Next state function for the Authenticate packet
482  * 
483  * @param ntlmssp_state NTLMSSP State
484  * @param request The request, as a DATA_BLOB
485  * @param request The reply, as an allocated DATA_BLOB, caller to free.
486  * @return Errors or NT_STATUS_OK. 
487  */
488
489 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
490                                     const DATA_BLOB request, DATA_BLOB *reply) 
491 {
492         DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
493         DATA_BLOB nt_session_key = data_blob(NULL, 0);
494         DATA_BLOB lm_session_key = data_blob(NULL, 0);
495         DATA_BLOB session_key = data_blob(NULL, 0);
496         uint32 ntlmssp_command, auth_flags;
497         NTSTATUS nt_status;
498
499         /* used by NTLM2 */
500         BOOL doing_ntlm2 = False;
501
502         uchar session_nonce[16];
503         uchar session_nonce_hash[16];
504
505         const char *parse_string;
506         char *domain = NULL;
507         char *user = NULL;
508         char *workstation = NULL;
509
510         /* parse the NTLMSSP packet */
511         *reply = data_blob(NULL, 0);
512
513 #if 0
514         file_save("ntlmssp_auth.dat", request.data, request.length);
515 #endif
516
517         if (ntlmssp_state->unicode) {
518                 parse_string = "CdBBUUUBd";
519         } else {
520                 parse_string = "CdBBAAABd";
521         }
522
523         data_blob_free(&ntlmssp_state->lm_resp);
524         data_blob_free(&ntlmssp_state->nt_resp);
525
526         ntlmssp_state->user = NULL;
527         ntlmssp_state->domain = NULL;
528         ntlmssp_state->workstation = NULL;
529
530         /* now the NTLMSSP encoded auth hashes */
531         if (!msrpc_parse(&request, parse_string,
532                          "NTLMSSP", 
533                          &ntlmssp_command, 
534                          &ntlmssp_state->lm_resp,
535                          &ntlmssp_state->nt_resp,
536                          &domain, 
537                          &user, 
538                          &workstation,
539                          &encrypted_session_key,
540                          &auth_flags)) {
541                 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
542                 dump_data(2, (const char *)request.data, request.length);
543                 SAFE_FREE(domain);
544                 SAFE_FREE(user);
545                 SAFE_FREE(workstation);
546                 data_blob_free(&encrypted_session_key);
547                 auth_flags = 0;
548                 
549                 /* Try again with a shorter string (Win9X truncates this packet) */
550                 if (ntlmssp_state->unicode) {
551                         parse_string = "CdBBUUU";
552                 } else {
553                         parse_string = "CdBBAAA";
554                 }
555
556                 /* now the NTLMSSP encoded auth hashes */
557                 if (!msrpc_parse(&request, parse_string,
558                                  "NTLMSSP", 
559                                  &ntlmssp_command, 
560                                  &ntlmssp_state->lm_resp,
561                                  &ntlmssp_state->nt_resp,
562                                  &domain, 
563                                  &user, 
564                                  &workstation)) {
565                         DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
566                         dump_data(2, (const char *)request.data, request.length);
567                         SAFE_FREE(domain);
568                         SAFE_FREE(user);
569                         SAFE_FREE(workstation);
570
571                         return NT_STATUS_INVALID_PARAMETER;
572                 }
573         }
574
575         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
576                 SAFE_FREE(domain);
577                 SAFE_FREE(user);
578                 SAFE_FREE(workstation);
579                 data_blob_free(&encrypted_session_key);
580                 return nt_status;
581         }
582
583         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
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_workstation(ntlmssp_state, workstation))) {
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         SAFE_FREE(domain);
600         SAFE_FREE(user);
601         SAFE_FREE(workstation);
602
603         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
604                  ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
605
606 #if 0
607         file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
608         file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
609 #endif
610
611         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a 
612            client challenge 
613         
614            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
615         */
616         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
617                 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
618                         struct MD5Context md5_session_nonce_ctx;
619                         SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
620                         
621                         doing_ntlm2 = True;
622
623                         memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
624                         memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
625                         
626                         MD5Init(&md5_session_nonce_ctx);
627                         MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
628                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
629                         
630                         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8);
631
632                         /* LM response is no longer useful */
633                         data_blob_free(&ntlmssp_state->lm_resp);
634
635                         /* We changed the effective challenge - set it */
636                         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
637                                 data_blob_free(&encrypted_session_key);
638                                 return nt_status;
639                         }
640                 }
641         }
642
643         /* Finally, actually ask if the password is OK */
644         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) {
645                 data_blob_free(&encrypted_session_key);
646                 return nt_status;
647         }
648
649         dump_data_pw("NT session key:\n", nt_session_key.data, nt_session_key.length);
650         dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
651
652         /* Handle the different session key derivation for NTLM2 */
653         if (doing_ntlm2) {
654                 if (nt_session_key.data && nt_session_key.length == 16) {
655                         session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
656                         hmac_md5(nt_session_key.data, session_nonce, 
657                                  sizeof(session_nonce), session_key.data);
658                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
659
660                 }
661         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
662                 if (lm_session_key.data && lm_session_key.length >= 8 && 
663                     ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
664                         session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
665                         SMBsesskeygen_lmv1(lm_session_key.data, ntlmssp_state->lm_resp.data, 
666                                            session_key.data);
667                         dump_data_pw("LM session key:\n", session_key.data, session_key.length);
668                 }
669         } else if (nt_session_key.data) {
670                 session_key = nt_session_key;
671                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
672         }
673
674         /* With KEY_EXCH, the client supplies the proposed session key, 
675            but encrypts it with the long-term key */
676         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
677                 if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
678                         data_blob_free(&encrypted_session_key);
679                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", 
680                                   encrypted_session_key.length));
681                         return NT_STATUS_INVALID_PARAMETER;
682                 } else if (!session_key.data || session_key.length != 16) {
683                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", 
684                                   session_key.length));
685                 } else {
686                         dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
687                         SamOEMhash(encrypted_session_key.data, 
688                                    session_key.data, 
689                                    encrypted_session_key.length);
690                         ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, 
691                                                                       encrypted_session_key.data, 
692                                                                       encrypted_session_key.length);
693                         dump_data_pw("KEY_EXCH session key:\n", session_key.data, session_key.length);
694                 }
695         } else {
696                 ntlmssp_state->session_key = session_key;
697         }
698
699         data_blob_free(&encrypted_session_key);
700         
701         /* allow arbitarily many authentications */
702         ntlmssp_state->expected_state = NTLMSSP_AUTH;
703
704         return nt_status;
705 }
706
707 /**
708  * Create an NTLMSSP state machine
709  * 
710  * @param ntlmssp_state NTLMSSP State, allocated by this function
711  */
712
713 NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
714 {
715         TALLOC_CTX *mem_ctx;
716
717         mem_ctx = talloc_init("NTLMSSP context");
718         
719         *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
720         if (!*ntlmssp_state) {
721                 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
722                 talloc_destroy(mem_ctx);
723                 return NT_STATUS_NO_MEMORY;
724         }
725
726         (*ntlmssp_state)->role = NTLMSSP_SERVER;
727
728         (*ntlmssp_state)->mem_ctx = mem_ctx;
729         (*ntlmssp_state)->get_challenge = get_challenge;
730         (*ntlmssp_state)->set_challenge = set_challenge;
731         (*ntlmssp_state)->may_set_challenge = may_set_challenge;
732
733         (*ntlmssp_state)->get_global_myname = global_myname;
734         (*ntlmssp_state)->get_domain = lp_workgroup;
735         (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
736
737         (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
738
739         (*ntlmssp_state)->ref_count = 1;
740
741         (*ntlmssp_state)->neg_flags = 
742                 NTLMSSP_NEGOTIATE_128 |
743                 NTLMSSP_NEGOTIATE_NTLM |
744                 NTLMSSP_NEGOTIATE_NTLM2 |
745                 NTLMSSP_NEGOTIATE_KEY_EXCH |
746                 NTLMSSP_NEGOTIATE_SIGN;
747
748         return NT_STATUS_OK;
749 }
750
751 /*********************************************************************
752  Client side NTLMSSP
753 *********************************************************************/
754
755 /**
756  * Next state function for the Initial packet
757  * 
758  * @param ntlmssp_state NTLMSSP State
759  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
760  * @param request The reply, as an allocated DATA_BLOB, caller to free.
761  * @return Errors or NT_STATUS_OK. 
762  */
763
764 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
765                                   DATA_BLOB reply, DATA_BLOB *next_request) 
766 {
767         if (ntlmssp_state->unicode) {
768                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
769         } else {
770                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
771         }
772         
773         if (ntlmssp_state->use_ntlmv2) {
774                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
775         }
776
777         ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
778         
779         /* generate the ntlmssp negotiate packet */
780         msrpc_gen(next_request, "CddAA",
781                   "NTLMSSP",
782                   NTLMSSP_NEGOTIATE,
783                   ntlmssp_state->neg_flags,
784                   ntlmssp_state->get_domain(), 
785                   ntlmssp_state->get_global_myname());
786
787         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
788
789         return NT_STATUS_MORE_PROCESSING_REQUIRED;
790 }
791
792 /**
793  * Next state function for the Challenge Packet.  Generate an auth packet.
794  * 
795  * @param ntlmssp_state NTLMSSP State
796  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
797  * @param request The reply, as an allocated DATA_BLOB, caller to free.
798  * @return Errors or NT_STATUS_OK. 
799  */
800
801 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
802                                          const DATA_BLOB reply, DATA_BLOB *next_request) 
803 {
804         uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
805         DATA_BLOB server_domain_blob;
806         DATA_BLOB challenge_blob;
807         DATA_BLOB struct_blob = data_blob(NULL, 0);
808         char *server_domain;
809         const char *chal_parse_string;
810         const char *auth_gen_string;
811         DATA_BLOB lm_response = data_blob(NULL, 0);
812         DATA_BLOB nt_response = data_blob(NULL, 0);
813         DATA_BLOB session_key = data_blob(NULL, 0);
814         DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
815
816         if (!msrpc_parse(&reply, "CdBd",
817                          "NTLMSSP",
818                          &ntlmssp_command, 
819                          &server_domain_blob,
820                          &chal_flags)) {
821                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
822                 dump_data(2, (const char *)reply.data, reply.length);
823
824                 return NT_STATUS_INVALID_PARAMETER;
825         }
826         
827         data_blob_free(&server_domain_blob);
828
829         DEBUG(3, ("Got challenge flags:\n"));
830         debug_ntlmssp_flags(chal_flags);
831
832         ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
833
834         if (ntlmssp_state->unicode) {
835                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
836                         chal_parse_string = "CdUdbddB";
837                 } else {
838                         chal_parse_string = "CdUdbdd";
839                 }
840                 auth_gen_string = "CdBBUUUBd";
841         } else {
842                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
843                         chal_parse_string = "CdAdbddB";
844                 } else {
845                         chal_parse_string = "CdAdbdd";
846                 }
847
848                 auth_gen_string = "CdBBAAABd";
849         }
850
851         DEBUG(3, ("NTLMSSP: Set final flags:\n"));
852         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
853
854         if (!msrpc_parse(&reply, chal_parse_string,
855                          "NTLMSSP",
856                          &ntlmssp_command, 
857                          &server_domain,
858                          &chal_flags,
859                          &challenge_blob, 8,
860                          &unkn1, &unkn2,
861                          &struct_blob)) {
862                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
863                 dump_data(2, (const char *)reply.data, reply.length);
864                 return NT_STATUS_INVALID_PARAMETER;
865         }
866
867         ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx,
868                                                      server_domain);
869
870         SAFE_FREE(server_domain);
871         if (challenge_blob.length != 8) {
872                 data_blob_free(&struct_blob);
873                 return NT_STATUS_INVALID_PARAMETER;
874         }
875
876         if (!ntlmssp_state->password) {
877                 /* do nothing - blobs are zero length */
878         } else if (ntlmssp_state->use_ntlmv2) {
879
880                 if (!struct_blob.length) {
881                         /* be lazy, match win2k - we can't do NTLMv2 without it */
882                         DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
883                         return NT_STATUS_INVALID_PARAMETER;
884                 }
885
886                 /* TODO: if the remote server is standalone, then we should replace 'domain'
887                    with the server name as supplied above */
888                 
889                 if (!SMBNTLMv2encrypt(ntlmssp_state->user, 
890                                       ntlmssp_state->domain, 
891                                       ntlmssp_state->password, &challenge_blob, 
892                                       &struct_blob, 
893                                       &lm_response, &nt_response, &session_key)) {
894                         data_blob_free(&challenge_blob);
895                         data_blob_free(&struct_blob);
896                         return NT_STATUS_NO_MEMORY;
897                 }
898         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
899                 struct MD5Context md5_session_nonce_ctx;
900                 uchar nt_hash[16];
901                 uchar session_nonce[16];
902                 uchar session_nonce_hash[16];
903                 uchar nt_session_key[16];
904                 E_md4hash(ntlmssp_state->password, nt_hash);
905                 
906                 lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
907                 generate_random_buffer(lm_response.data, 8, False);
908                 memset(lm_response.data+8, 0, 16);
909
910                 memcpy(session_nonce, challenge_blob.data, 8);
911                 memcpy(&session_nonce[8], lm_response.data, 8);
912         
913                 MD5Init(&md5_session_nonce_ctx);
914                 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
915                 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
916                 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
917
918                 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
919                 DEBUG(5, ("challenge is: \n"));
920                 dump_data(5, session_nonce_hash, 8);
921                 
922                 nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
923                 SMBNTencrypt(ntlmssp_state->password,
924                              session_nonce_hash,
925                              nt_response.data);
926
927                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
928
929                 SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key);
930                 hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data);
931                 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
932         } else {
933                 
934                 
935                 uchar lm_hash[16];
936                 uchar nt_hash[16];
937                 E_deshash(ntlmssp_state->password, lm_hash);
938                 E_md4hash(ntlmssp_state->password, nt_hash);
939                 
940                 /* lanman auth is insecure, it may be disabled */
941                 if (lp_client_lanman_auth()) {
942                         lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
943                         SMBencrypt(ntlmssp_state->password,challenge_blob.data,
944                                    lm_response.data);
945                 }
946                 
947                 nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
948                 SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
949                              nt_response.data);
950                 
951                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
952                 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
953                     && lp_client_lanman_auth()) {
954                         SMBsesskeygen_lmv1(lm_hash, lm_response.data, 
955                                            session_key.data);
956                         dump_data_pw("LM session key\n", session_key.data, session_key.length);
957                 } else {
958                         SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
959                         dump_data_pw("NT session key:\n", session_key.data, session_key.length);
960                 }
961         }
962         data_blob_free(&struct_blob);
963
964         /* Key exchange encryptes a new client-generated session key with
965            the password-derived key */
966         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
967                 uint8 client_session_key[16];
968                 
969                 generate_random_buffer(client_session_key, sizeof(client_session_key), False);  
970                 encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
971                 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
972
973                 SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
974                 data_blob_free(&session_key);
975                 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key));
976                 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
977         }
978
979         /* this generates the actual auth packet */
980         if (!msrpc_gen(next_request, auth_gen_string, 
981                        "NTLMSSP", 
982                        NTLMSSP_AUTH, 
983                        lm_response.data, lm_response.length,
984                        nt_response.data, nt_response.length,
985                        ntlmssp_state->domain, 
986                        ntlmssp_state->user, 
987                        ntlmssp_state->get_global_myname(), 
988                        encrypted_session_key.data, encrypted_session_key.length,
989                        ntlmssp_state->neg_flags)) {
990                 
991                 return NT_STATUS_NO_MEMORY;
992         }
993
994         data_blob_free(&encrypted_session_key);
995
996         data_blob_free(&ntlmssp_state->chal);
997
998         ntlmssp_state->chal = challenge_blob;
999         ntlmssp_state->lm_resp = lm_response;
1000         ntlmssp_state->nt_resp = nt_response;
1001         ntlmssp_state->session_key = session_key;
1002
1003         ntlmssp_state->expected_state = NTLMSSP_UNKNOWN;
1004
1005         return NT_STATUS_MORE_PROCESSING_REQUIRED;
1006 }
1007
1008 NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
1009 {
1010         TALLOC_CTX *mem_ctx;
1011
1012         mem_ctx = talloc_init("NTLMSSP Client context");
1013         
1014         *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
1015         if (!*ntlmssp_state) {
1016                 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
1017                 talloc_destroy(mem_ctx);
1018                 return NT_STATUS_NO_MEMORY;
1019         }
1020
1021         (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1022
1023         (*ntlmssp_state)->mem_ctx = mem_ctx;
1024
1025         (*ntlmssp_state)->get_global_myname = global_myname;
1026         (*ntlmssp_state)->get_domain = lp_workgroup;
1027
1028         (*ntlmssp_state)->unicode = True;
1029
1030         (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1031
1032         (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1033
1034         (*ntlmssp_state)->ref_count = 1;
1035
1036         (*ntlmssp_state)->neg_flags = 
1037                 NTLMSSP_NEGOTIATE_128 |
1038                 NTLMSSP_NEGOTIATE_NTLM |
1039                 NTLMSSP_NEGOTIATE_NTLM2 |
1040                 NTLMSSP_NEGOTIATE_KEY_EXCH |
1041                 /*
1042                  * We need to set this to allow a later SetPassword
1043                  * via the SAMR pipe to succeed. Strange.... We could
1044                  * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
1045                  * */
1046                 NTLMSSP_NEGOTIATE_SIGN |
1047                 NTLMSSP_REQUEST_TARGET;
1048
1049         return NT_STATUS_OK;
1050 }
1051