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