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