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