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