2 Unix SMB/Netbios implementation.
4 handle NLTMSSP, server side
6 Copyright (C) Andrew Tridgell 2001
7 Copyright (C) Andrew Bartlett 2001-2003
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "auth/auth.h"
26 #include "lib/crypto/crypto.h"
29 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
30 TALLOC_CTX *out_mem_ctx,
31 DATA_BLOB in, DATA_BLOB *out);
32 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
33 TALLOC_CTX *out_mem_ctx,
34 const DATA_BLOB in, DATA_BLOB *out);
35 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
36 TALLOC_CTX *out_mem_ctx,
37 const DATA_BLOB in, DATA_BLOB *out);
38 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
39 TALLOC_CTX *out_mem_ctx,
40 const DATA_BLOB in, DATA_BLOB *out);
43 * Callbacks for NTLMSSP - for both client and server operating modes
47 static const struct ntlmssp_callbacks {
48 enum ntlmssp_role role;
49 enum ntlmssp_message_type ntlmssp_command;
50 NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state,
51 TALLOC_CTX *out_mem_ctx,
52 DATA_BLOB in, DATA_BLOB *out);
53 } ntlmssp_callbacks[] = {
54 {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},
55 {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},
56 {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},
57 {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},
58 {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
59 {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
64 * Print out the NTLMSSP flags for debugging
65 * @param neg_flags The flags from the packet
68 void debug_ntlmssp_flags(uint32_t neg_flags)
70 DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
72 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)
73 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n"));
74 if (neg_flags & NTLMSSP_NEGOTIATE_OEM)
75 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n"));
76 if (neg_flags & NTLMSSP_REQUEST_TARGET)
77 DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n"));
78 if (neg_flags & NTLMSSP_NEGOTIATE_SIGN)
79 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n"));
80 if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)
81 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n"));
82 if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
83 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n"));
84 if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)
85 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n"));
86 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM)
87 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n"));
88 if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED)
89 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n"));
90 if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED)
91 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n"));
92 if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL)
93 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
94 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
95 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
96 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
97 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n"));
98 if (neg_flags & NTLMSSP_CHAL_TARGET_INFO)
99 DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n"));
100 if (neg_flags & NTLMSSP_NEGOTIATE_128)
101 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n"));
102 if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
103 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
107 * Default challenge generation code.
111 static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state)
113 uint8_t *chal = talloc_size(ntlmssp_state, 8);
114 generate_random_buffer(chal, 8);
120 * Default 'we can set the challenge to anything we like' implementation
124 static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
130 * Default 'we can set the challenge to anything we like' implementation
132 * Does not actually do anything, as the value is always in the structure anyway.
136 static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
138 SMB_ASSERT(challenge->length == 8);
143 * Set a username on an NTLMSSP context - ensures it is talloc()ed
147 NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user)
150 /* it should be at least "" */
151 return NT_STATUS_INVALID_PARAMETER;
153 ntlmssp_state->user = talloc_strdup(ntlmssp_state, user);
154 if (!ntlmssp_state->user) {
155 return NT_STATUS_NO_MEMORY;
161 * Set a password on an NTLMSSP context - ensures it is talloc()ed
164 NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password)
167 ntlmssp_state->password = NULL;
169 ntlmssp_state->password = talloc_strdup(ntlmssp_state, password);
170 if (!ntlmssp_state->password) {
171 return NT_STATUS_NO_MEMORY;
178 * Set a domain on an NTLMSSP context - ensures it is talloc()ed
181 NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain)
183 ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain);
184 if (!ntlmssp_state->domain) {
185 return NT_STATUS_NO_MEMORY;
191 * Set a workstation on an NTLMSSP context - ensures it is talloc()ed
194 NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation)
196 ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
197 if (!ntlmssp_state->workstation) {
198 return NT_STATUS_NO_MEMORY;
204 * Store a DATA_BLOB containing an NTLMSSP response, for use later.
205 * This copies the data blob
208 NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state,
211 ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state,
212 response.data, response.length);
217 * Next state function for the NTLMSSP state machine
219 * @param ntlmssp_state NTLMSSP State
220 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
221 * @param in The request, as a DATA_BLOB
222 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
223 * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,
224 * or NT_STATUS_OK if the user is authenticated.
227 NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
228 TALLOC_CTX *out_mem_ctx,
229 const DATA_BLOB in, DATA_BLOB *out)
232 uint32_t ntlmssp_command;
235 *out = data_blob(NULL, 0);
237 if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
242 /* if the caller doesn't want to manage/own the memory,
243 we can put it on our context */
244 out_mem_ctx = ntlmssp_state;
247 if (!in.length && ntlmssp_state->stored_response.length) {
248 input = ntlmssp_state->stored_response;
250 /* we only want to read the stored response once - overwrite it */
251 ntlmssp_state->stored_response = data_blob(NULL, 0);
257 switch (ntlmssp_state->role) {
259 ntlmssp_command = NTLMSSP_INITIAL;
262 /* 'datagram' mode - no neg packet */
263 ntlmssp_command = NTLMSSP_NEGOTIATE;
267 if (!msrpc_parse(ntlmssp_state,
271 DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
272 dump_data(2, input.data, input.length);
273 return NT_STATUS_INVALID_PARAMETER;
277 if (ntlmssp_command != ntlmssp_state->expected_state) {
278 DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
279 return NT_STATUS_INVALID_PARAMETER;
282 for (i=0; ntlmssp_callbacks[i].fn; i++) {
283 if (ntlmssp_callbacks[i].role == ntlmssp_state->role
284 && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command
285 && ntlmssp_callbacks[i].fn) {
286 return ntlmssp_callbacks[i].fn(ntlmssp_state, out_mem_ctx, input, out);
290 DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n",
291 ntlmssp_state->role, ntlmssp_command));
293 return NT_STATUS_INVALID_PARAMETER;
297 * Return the NTLMSSP master session key
299 * @param ntlmssp_state NTLMSSP State
302 NTSTATUS ntlmssp_session_key(struct ntlmssp_state *ntlmssp_state,
303 DATA_BLOB *session_key)
305 if (!ntlmssp_state->session_key.data) {
306 return NT_STATUS_NO_USER_SESSION_KEY;
308 *session_key = ntlmssp_state->session_key;
314 * End an NTLMSSP state machine
316 * @param ntlmssp_state NTLMSSP State, free()ed by this function
319 void ntlmssp_end(struct ntlmssp_state **ntlmssp_state)
321 (*ntlmssp_state)->ref_count--;
323 if ((*ntlmssp_state)->ref_count == 0) {
324 talloc_free(*ntlmssp_state);
327 *ntlmssp_state = NULL;
332 * Determine correct target name flags for reply, given server role
333 * and negotiated flags
335 * @param ntlmssp_state NTLMSSP State
336 * @param neg_flags The flags from the packet
337 * @param chal_flags The flags to be set in the reply packet
338 * @return The 'target name' string.
341 static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
342 uint32_t neg_flags, uint32_t *chal_flags)
344 if (neg_flags & NTLMSSP_REQUEST_TARGET) {
345 *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
346 *chal_flags |= NTLMSSP_REQUEST_TARGET;
347 if (ntlmssp_state->server_role == ROLE_STANDALONE) {
348 *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
349 return ntlmssp_state->server_name;
351 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
352 return ntlmssp_state->get_domain();
359 static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
360 uint32_t neg_flags, BOOL allow_lm) {
361 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
362 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
363 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
364 ntlmssp_state->unicode = True;
366 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
367 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
368 ntlmssp_state->unicode = False;
371 if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !ntlmssp_state->use_ntlmv2) {
372 /* other end forcing us to use LM */
373 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
374 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
376 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
379 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) {
380 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
383 if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
384 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
387 if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
388 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
391 if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
392 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
395 if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
396 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
397 if (neg_flags & NTLMSSP_NEGOTIATE_56) {
398 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
402 if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
403 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
406 if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
407 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
410 if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
411 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
417 Weaken NTLMSSP keys to cope with down-level clients and servers.
419 We probably should have some parameters to control this, but as
420 it only occours for LM_KEY connections, and this is controlled
421 by the client lanman auth/lanman auth parameters, it isn't too bad.
424 static void ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state) {
425 /* Key weakening not performed on the master key for NTLM2
426 and does not occour for NTLM1. Therefore we only need
427 to do this for the LM_KEY.
430 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
431 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
433 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
434 ntlmssp_state->session_key.data[7] = 0xa0;
435 } else { /* forty bits */
436 ntlmssp_state->session_key.data[5] = 0xe5;
437 ntlmssp_state->session_key.data[6] = 0x38;
438 ntlmssp_state->session_key.data[7] = 0xb0;
440 ntlmssp_state->session_key.length = 8;
445 * Next state function for the Negotiate packet
447 * @param ntlmssp_state NTLMSSP State
448 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
449 * @param in The request, as a DATA_BLOB
450 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
451 * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent.
454 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
455 TALLOC_CTX *out_mem_ctx,
456 const DATA_BLOB in, DATA_BLOB *out)
458 DATA_BLOB struct_blob;
459 fstring dnsname, dnsdomname;
460 uint32_t neg_flags = 0;
461 uint32_t ntlmssp_command, chal_flags;
462 char *cliname=NULL, *domname=NULL;
463 const uint8_t *cryptkey;
464 const char *target_name;
466 /* parse the NTLMSSP packet */
468 file_save("ntlmssp_negotiate.dat", request.data, request.length);
472 if (!msrpc_parse(ntlmssp_state,
479 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
480 dump_data(2, in.data, in.length);
481 return NT_STATUS_INVALID_PARAMETER;
484 debug_ntlmssp_flags(neg_flags);
487 ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key);
489 /* Ask our caller what challenge they would like in the packet */
490 cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
492 /* Check if we may set the challenge */
493 if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
494 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
497 /* The flags we send back are not just the negotiated flags,
498 * they are also 'what is in this packet'. Therfore, we
499 * operate on 'chal_flags' from here on
502 chal_flags = ntlmssp_state->neg_flags;
504 /* get the right name to fill in as 'target' */
505 target_name = ntlmssp_target_name(ntlmssp_state,
506 neg_flags, &chal_flags);
507 if (target_name == NULL)
508 return NT_STATUS_INVALID_PARAMETER;
510 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
511 ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
513 /* This should be a 'netbios domain -> DNS domain' mapping */
514 dnsdomname[0] = '\0';
515 get_mydomname(dnsdomname);
516 strlower_m(dnsdomname);
519 get_myfullname(dnsname);
521 /* This creates the 'blob' of names that appears at the end of the packet */
522 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO)
524 const char *target_name_dns = "";
525 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
526 target_name_dns = dnsdomname;
527 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
528 target_name_dns = dnsname;
531 msrpc_gen(out_mem_ctx,
532 &struct_blob, "aaaaa",
533 NTLMSSP_NAME_TYPE_DOMAIN, target_name,
534 NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->server_name,
535 NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
536 NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
539 struct_blob = data_blob(NULL, 0);
543 /* Marshel the packet in the right format, be it unicode or ASCII */
544 const char *gen_string;
545 if (ntlmssp_state->unicode) {
546 gen_string = "CdUdbddB";
548 gen_string = "CdAdbddB";
551 msrpc_gen(out_mem_ctx,
559 struct_blob.data, struct_blob.length);
562 ntlmssp_state->expected_state = NTLMSSP_AUTH;
564 return NT_STATUS_MORE_PROCESSING_REQUIRED;
568 * Next state function for the Authenticate packet
570 * @param ntlmssp_state NTLMSSP State
571 * @param request The request, as a DATA_BLOB
572 * @return Errors or NT_STATUS_OK.
575 static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state,
576 const DATA_BLOB request)
578 uint32_t ntlmssp_command, auth_flags;
581 uint8_t session_nonce_hash[16];
583 const char *parse_string;
586 char *workstation = NULL;
589 file_save("ntlmssp_auth.dat", request.data, request.length);
592 if (ntlmssp_state->unicode) {
593 parse_string = "CdBBUUUBd";
595 parse_string = "CdBBAAABd";
599 data_blob_free(&ntlmssp_state->lm_resp);
600 data_blob_free(&ntlmssp_state->nt_resp);
602 ntlmssp_state->user = NULL;
603 ntlmssp_state->domain = NULL;
604 ntlmssp_state->workstation = NULL;
606 /* now the NTLMSSP encoded auth hashes */
607 if (!msrpc_parse(ntlmssp_state,
608 &request, parse_string,
611 &ntlmssp_state->lm_resp,
612 &ntlmssp_state->nt_resp,
616 &ntlmssp_state->encrypted_session_key,
618 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
619 dump_data(10, request.data, request.length);
622 data_blob_free(&ntlmssp_state->encrypted_session_key);
625 /* Try again with a shorter string (Win9X truncates this packet) */
626 if (ntlmssp_state->unicode) {
627 parse_string = "CdBBUUU";
629 parse_string = "CdBBAAA";
632 /* now the NTLMSSP encoded auth hashes */
633 if (!msrpc_parse(ntlmssp_state,
634 &request, parse_string,
637 &ntlmssp_state->lm_resp,
638 &ntlmssp_state->nt_resp,
642 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
643 dump_data(2, request.data, request.length);
645 return NT_STATUS_INVALID_PARAMETER;
650 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key);
652 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
654 data_blob_free(&ntlmssp_state->encrypted_session_key);
658 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
660 data_blob_free(&ntlmssp_state->encrypted_session_key);
664 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
666 data_blob_free(&ntlmssp_state->encrypted_session_key);
670 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
671 ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
674 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);
675 file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length);
678 /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
681 However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
683 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
684 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
685 struct MD5Context md5_session_nonce_ctx;
686 SMB_ASSERT(ntlmssp_state->internal_chal.data
687 && ntlmssp_state->internal_chal.length == 8);
689 ntlmssp_state->doing_ntlm2 = True;
691 memcpy(ntlmssp_state->session_nonce, ntlmssp_state->internal_chal.data, 8);
692 memcpy(&ntlmssp_state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
694 MD5Init(&md5_session_nonce_ctx);
695 MD5Update(&md5_session_nonce_ctx, ntlmssp_state->session_nonce, 16);
696 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
698 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state,
699 session_nonce_hash, 8);
701 /* LM response is no longer useful, zero it out */
702 data_blob_free(&ntlmssp_state->lm_resp);
704 /* We changed the effective challenge - set it */
705 if (!NT_STATUS_IS_OK(nt_status =
706 ntlmssp_state->set_challenge(ntlmssp_state,
707 &ntlmssp_state->chal))) {
709 data_blob_free(&ntlmssp_state->encrypted_session_key);
713 /* LM Key is incompatible... */
714 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
721 * Next state function for the Authenticate packet
722 * (after authentication - figures out the session keys etc)
724 * @param ntlmssp_state NTLMSSP State
725 * @return Errors or NT_STATUS_OK.
728 static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
729 DATA_BLOB *user_session_key,
730 DATA_BLOB *lm_session_key)
733 DATA_BLOB session_key = data_blob(NULL, 0);
735 if (user_session_key)
736 dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length);
739 dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length);
741 /* Handle the different session key derivation for NTLM2 */
742 if (ntlmssp_state->doing_ntlm2) {
743 if (user_session_key && user_session_key->data && user_session_key->length == 16) {
744 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
745 hmac_md5(user_session_key->data, ntlmssp_state->session_nonce,
746 sizeof(ntlmssp_state->session_nonce), session_key.data);
747 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
748 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
751 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
752 session_key = data_blob(NULL, 0);
754 } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
755 /* Ensure we can never get here on NTLMv2 */
756 && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
758 if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
759 if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
760 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
761 SMBsesskeygen_lm_sess_key(lm_session_key->data, ntlmssp_state->lm_resp.data,
763 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
764 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
767 /* When there is no LM response, just use zeros */
768 static const uint8_t zeros[24];
769 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
770 SMBsesskeygen_lm_sess_key(zeros, zeros,
772 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
773 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
776 /* LM Key not selected */
777 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
779 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
780 session_key = data_blob(NULL, 0);
783 } else if (user_session_key && user_session_key->data) {
784 session_key = *user_session_key;
785 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
786 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
788 /* LM Key not selected */
789 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
791 } else if (lm_session_key && lm_session_key->data) {
792 /* Very weird to have LM key, but no user session key, but anyway.. */
793 session_key = *lm_session_key;
794 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
795 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
797 /* LM Key not selected */
798 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
801 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
802 session_key = data_blob(NULL, 0);
804 /* LM Key not selected */
805 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
808 /* With KEY_EXCH, the client supplies the proposed session key,
809 but encrypts it with the long-term key */
810 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
811 if (!ntlmssp_state->encrypted_session_key.data
812 || ntlmssp_state->encrypted_session_key.length != 16) {
813 data_blob_free(&ntlmssp_state->encrypted_session_key);
814 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
815 ntlmssp_state->encrypted_session_key.length));
816 return NT_STATUS_INVALID_PARAMETER;
817 } else if (!session_key.data || session_key.length != 16) {
818 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
819 session_key.length));
820 ntlmssp_state->session_key = session_key;
822 dump_data_pw("KEY_EXCH session key (enc):\n",
823 ntlmssp_state->encrypted_session_key.data,
824 ntlmssp_state->encrypted_session_key.length);
825 arcfour_crypt(ntlmssp_state->encrypted_session_key.data,
827 ntlmssp_state->encrypted_session_key.length);
828 ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
829 ntlmssp_state->encrypted_session_key.data,
830 ntlmssp_state->encrypted_session_key.length);
831 dump_data_pw("KEY_EXCH session key:\n", ntlmssp_state->encrypted_session_key.data,
832 ntlmssp_state->encrypted_session_key.length);
835 ntlmssp_state->session_key = session_key;
838 /* The server might need us to use a partial-strength session key */
839 ntlmssp_weaken_keys(ntlmssp_state);
841 nt_status = ntlmssp_sign_init(ntlmssp_state);
843 data_blob_free(&ntlmssp_state->encrypted_session_key);
845 /* allow arbitarily many authentications, but watch that this will cause a
846 memory leak, until the ntlmssp_state is shutdown
849 if (ntlmssp_state->server_multiple_authentications) {
850 ntlmssp_state->expected_state = NTLMSSP_AUTH;
852 ntlmssp_state->expected_state = NTLMSSP_DONE;
860 * Next state function for the Authenticate packet
862 * @param ntlmssp_state NTLMSSP State
863 * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
864 * @param out The reply, as an allocated DATA_BLOB, caller to free.
865 * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK.
868 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
869 TALLOC_CTX *out_mem_ctx,
870 const DATA_BLOB in, DATA_BLOB *out)
872 DATA_BLOB user_session_key = data_blob(NULL, 0);
873 DATA_BLOB lm_session_key = data_blob(NULL, 0);
876 /* zero the outbound NTLMSSP packet */
877 *out = data_blob_talloc(out_mem_ctx, NULL, 0);
879 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(ntlmssp_state, in))) {
884 * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
885 * is required (by "ntlm auth = no" and "lm auth = no" being set in the
886 * smb.conf file) and no NTLMv2 response was sent then the password check
887 * will fail here. JRA.
890 /* Finally, actually ask if the password is OK */
892 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state,
893 &user_session_key, &lm_session_key))) {
897 if (ntlmssp_state->server_use_session_keys) {
898 return ntlmssp_server_postauth(ntlmssp_state, &user_session_key, &lm_session_key);
900 ntlmssp_state->session_key = data_blob(NULL, 0);
906 * Create an NTLMSSP state machine
908 * @param ntlmssp_state NTLMSSP State, allocated by this function
911 NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
913 *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state);
914 if (!*ntlmssp_state) {
915 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
916 return NT_STATUS_NO_MEMORY;
918 ZERO_STRUCTP(*ntlmssp_state);
920 (*ntlmssp_state)->role = NTLMSSP_SERVER;
922 (*ntlmssp_state)->get_challenge = get_challenge;
923 (*ntlmssp_state)->set_challenge = set_challenge;
924 (*ntlmssp_state)->may_set_challenge = may_set_challenge;
926 (*ntlmssp_state)->workstation = NULL;
927 (*ntlmssp_state)->server_name = lp_netbios_name();
929 (*ntlmssp_state)->get_domain = lp_workgroup;
930 (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
932 (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
934 (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
935 && lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False));
937 (*ntlmssp_state)->server_use_session_keys = True;
938 (*ntlmssp_state)->server_multiple_authentications = False;
940 (*ntlmssp_state)->ref_count = 1;
942 (*ntlmssp_state)->neg_flags =
943 NTLMSSP_NEGOTIATE_NTLM;
945 if (lp_parm_bool(-1, "ntlmssp_server", "128bit", True)) {
946 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
949 if (lp_parm_bool(-1, "ntlmssp_server", "keyexchange", True)) {
950 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
953 if (lp_parm_bool(-1, "ntlmssp_server", "ntlm2", True)) {
954 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
960 /*********************************************************************
962 *********************************************************************/
965 * Next state function for the Initial packet
967 * @param ntlmssp_state NTLMSSP State
968 * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context
969 * @param in The request, as a DATA_BLOB. reply.data must be NULL
970 * @param out The reply, as an talloc()ed DATA_BLOB, on out_mem_ctx
971 * @return Errors or NT_STATUS_OK.
974 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
975 TALLOC_CTX *out_mem_ctx,
976 DATA_BLOB in, DATA_BLOB *out)
978 if (ntlmssp_state->unicode) {
979 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
981 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
984 if (ntlmssp_state->use_ntlmv2) {
985 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
988 /* generate the ntlmssp negotiate packet */
989 msrpc_gen(out_mem_ctx,
993 ntlmssp_state->neg_flags,
994 ntlmssp_state->get_domain(),
995 ntlmssp_state->workstation);
997 ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
999 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1003 * Next state function for the Challenge Packet. Generate an auth packet.
1005 * @param ntlmssp_state NTLMSSP State
1006 * @param request The request, as a DATA_BLOB. reply.data must be NULL
1007 * @param request The reply, as an allocated DATA_BLOB, caller to free.
1008 * @return Errors or NT_STATUS_OK.
1011 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
1012 TALLOC_CTX *out_mem_ctx,
1013 const DATA_BLOB in, DATA_BLOB *out)
1015 uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
1016 DATA_BLOB server_domain_blob;
1017 DATA_BLOB challenge_blob;
1018 DATA_BLOB struct_blob = data_blob(NULL, 0);
1019 char *server_domain;
1020 const char *chal_parse_string;
1021 const char *auth_gen_string;
1022 uint8_t lm_hash[16];
1023 DATA_BLOB lm_response = data_blob(NULL, 0);
1024 DATA_BLOB nt_response = data_blob(NULL, 0);
1025 DATA_BLOB session_key = data_blob(NULL, 0);
1026 DATA_BLOB lm_session_key = data_blob(NULL, 0);
1027 DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
1030 if (!msrpc_parse(ntlmssp_state,
1034 &server_domain_blob,
1036 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
1037 dump_data(2, in.data, in.length);
1039 return NT_STATUS_INVALID_PARAMETER;
1042 data_blob_free(&server_domain_blob);
1044 DEBUG(3, ("Got challenge flags:\n"));
1045 debug_ntlmssp_flags(chal_flags);
1047 ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key);
1049 if (ntlmssp_state->unicode) {
1050 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1051 chal_parse_string = "CdUdbddB";
1053 chal_parse_string = "CdUdbdd";
1055 auth_gen_string = "CdBBUUUBd";
1057 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1058 chal_parse_string = "CdAdbddB";
1060 chal_parse_string = "CdAdbdd";
1063 auth_gen_string = "CdBBAAABd";
1066 DEBUG(3, ("NTLMSSP: Set final flags:\n"));
1067 debug_ntlmssp_flags(ntlmssp_state->neg_flags);
1069 if (!msrpc_parse(ntlmssp_state,
1070 &in, chal_parse_string,
1078 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
1079 dump_data(2, in.data, in.length);
1080 return NT_STATUS_INVALID_PARAMETER;
1083 ntlmssp_state->server_domain = server_domain;
1085 if (challenge_blob.length != 8) {
1086 return NT_STATUS_INVALID_PARAMETER;
1089 if (!ntlmssp_state->password) {
1090 static const uint8_t zeros[16];
1091 /* do nothing - blobs are zero length */
1093 /* session key is all zeros */
1094 session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1095 lm_session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1097 /* not doing NLTM2 without a password */
1098 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
1099 } else if (ntlmssp_state->use_ntlmv2) {
1101 if (!struct_blob.length) {
1102 /* be lazy, match win2k - we can't do NTLMv2 without it */
1103 DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
1104 return NT_STATUS_INVALID_PARAMETER;
1107 /* TODO: if the remote server is standalone, then we should replace 'domain'
1108 with the server name as supplied above */
1110 if (!SMBNTLMv2encrypt(ntlmssp_state->user,
1111 ntlmssp_state->domain,
1112 ntlmssp_state->password, &challenge_blob,
1114 &lm_response, &nt_response,
1115 NULL, &session_key)) {
1116 data_blob_free(&challenge_blob);
1117 data_blob_free(&struct_blob);
1118 return NT_STATUS_NO_MEMORY;
1121 /* LM Key is incompatible... */
1122 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1124 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
1125 struct MD5Context md5_session_nonce_ctx;
1126 uint8_t nt_hash[16];
1127 uint8_t session_nonce[16];
1128 uint8_t session_nonce_hash[16];
1129 uint8_t user_session_key[16];
1130 E_md4hash(ntlmssp_state->password, nt_hash);
1132 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1133 generate_random_buffer(lm_response.data, 8);
1134 memset(lm_response.data+8, 0, 16);
1136 memcpy(session_nonce, challenge_blob.data, 8);
1137 memcpy(&session_nonce[8], lm_response.data, 8);
1139 MD5Init(&md5_session_nonce_ctx);
1140 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
1141 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
1142 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
1144 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
1145 DEBUG(5, ("challenge is: \n"));
1146 dump_data(5, session_nonce_hash, 8);
1148 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1149 SMBNTencrypt(ntlmssp_state->password,
1153 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1155 SMBsesskeygen_ntv1(nt_hash, user_session_key);
1156 hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
1157 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
1159 /* LM Key is incompatible... */
1160 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1162 uint8_t nt_hash[16];
1164 if (ntlmssp_state->use_nt_response) {
1165 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1166 SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
1168 E_md4hash(ntlmssp_state->password, nt_hash);
1169 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1170 SMBsesskeygen_ntv1(nt_hash, session_key.data);
1171 dump_data_pw("NT session key:\n", session_key.data, session_key.length);
1174 /* lanman auth is insecure, it may be disabled */
1175 if (lp_client_lanman_auth()) {
1176 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1177 if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data,
1178 lm_response.data)) {
1179 /* If the LM password was too long (and therefore the LM hash being
1180 of the first 14 chars only), don't send it */
1181 data_blob_free(&lm_response);
1183 /* LM Key is incompatible with 'long' passwords */
1184 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1186 E_deshash(ntlmssp_state->password, lm_hash);
1187 lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1188 memcpy(lm_session_key.data, lm_hash, 8);
1189 memset(&lm_session_key.data[8], '\0', 8);
1191 if (!ntlmssp_state->use_nt_response) {
1192 session_key = lm_session_key;
1196 /* LM Key is incompatible... */
1197 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1201 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
1202 && lp_client_lanman_auth() && lm_session_key.length == 16) {
1203 DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1204 if (lm_response.length == 24) {
1205 SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data,
1206 new_session_key.data);
1208 static const uint8_t zeros[24];
1209 SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros,
1210 new_session_key.data);
1212 new_session_key.length = 16;
1213 session_key = new_session_key;
1214 dump_data_pw("LM session key\n", session_key.data, session_key.length);
1218 /* Key exchange encryptes a new client-generated session key with
1219 the password-derived key */
1220 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1221 /* Make up a new session key */
1222 uint8_t client_session_key[16];
1223 generate_random_buffer(client_session_key, sizeof(client_session_key));
1225 /* Encrypt the new session key with the old one */
1226 encrypted_session_key = data_blob_talloc(ntlmssp_state,
1227 client_session_key, sizeof(client_session_key));
1228 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
1229 arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
1230 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
1232 /* Mark the new session key as the 'real' session key */
1233 session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key));
1236 /* this generates the actual auth packet */
1237 if (!msrpc_gen(out_mem_ctx,
1238 out, auth_gen_string,
1241 lm_response.data, lm_response.length,
1242 nt_response.data, nt_response.length,
1243 ntlmssp_state->domain,
1244 ntlmssp_state->user,
1245 ntlmssp_state->workstation,
1246 encrypted_session_key.data, encrypted_session_key.length,
1247 ntlmssp_state->neg_flags)) {
1249 return NT_STATUS_NO_MEMORY;
1252 ntlmssp_state->session_key = session_key;
1254 /* The client might be using 56 or 40 bit weakened keys */
1255 ntlmssp_weaken_keys(ntlmssp_state);
1257 ntlmssp_state->chal = challenge_blob;
1258 ntlmssp_state->lm_resp = lm_response;
1259 ntlmssp_state->nt_resp = nt_response;
1261 ntlmssp_state->expected_state = NTLMSSP_DONE;
1263 nt_status = ntlmssp_sign_init(ntlmssp_state);
1264 if (!NT_STATUS_IS_OK(nt_status)) {
1265 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
1266 nt_errstr(nt_status)));
1273 NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
1275 *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state);
1276 if (!*ntlmssp_state) {
1277 DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
1278 return NT_STATUS_NO_MEMORY;
1280 ZERO_STRUCTP(*ntlmssp_state);
1282 (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1284 (*ntlmssp_state)->workstation = lp_netbios_name();
1285 (*ntlmssp_state)->get_domain = lp_workgroup;
1287 (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True);
1289 (*ntlmssp_state)->use_nt_response = lp_parm_bool(-1, "ntlmssp_client", "send_nt_reponse", True);
1291 (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
1292 && lp_parm_bool(-1, "ntlmssp_client", "allow_lm_key", False));
1294 (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1296 (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1298 (*ntlmssp_state)->ref_count = 1;
1300 (*ntlmssp_state)->neg_flags =
1301 NTLMSSP_NEGOTIATE_NTLM |
1302 NTLMSSP_REQUEST_TARGET;
1304 if (lp_parm_bool(-1, "ntlmssp_client", "128bit", True)) {
1305 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
1308 if (lp_parm_bool(-1, "ntlmssp_client", "keyexchange", True)) {
1309 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
1312 if (lp_parm_bool(-1, "ntlmssp_client", "ntlm2", True)) {
1313 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
1315 /* apparently we can't do ntlmv2 if we don't do ntlm2 */
1316 (*ntlmssp_state)->use_ntlmv2 = False;
1319 return NT_STATUS_OK;