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