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