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