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