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"
28 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
29 TALLOC_CTX *out_mem_ctx,
30 DATA_BLOB in, DATA_BLOB *out);
31 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
32 TALLOC_CTX *out_mem_ctx,
33 const DATA_BLOB in, DATA_BLOB *out);
34 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
35 TALLOC_CTX *out_mem_ctx,
36 const DATA_BLOB in, DATA_BLOB *out);
37 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
38 TALLOC_CTX *out_mem_ctx,
39 const DATA_BLOB in, DATA_BLOB *out);
42 * Callbacks for NTLMSSP - for both client and server operating modes
46 static const struct ntlmssp_callbacks {
47 enum ntlmssp_role role;
48 enum ntlmssp_message_type ntlmssp_command;
49 NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state,
50 TALLOC_CTX *out_mem_ctx,
51 DATA_BLOB in, DATA_BLOB *out);
52 } ntlmssp_callbacks[] = {
53 {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},
54 {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},
55 {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},
56 {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},
57 {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
58 {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
63 * Print out the NTLMSSP flags for debugging
64 * @param neg_flags The flags from the packet
67 void debug_ntlmssp_flags(uint32_t neg_flags)
69 DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
71 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)
72 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n"));
73 if (neg_flags & NTLMSSP_NEGOTIATE_OEM)
74 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n"));
75 if (neg_flags & NTLMSSP_REQUEST_TARGET)
76 DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n"));
77 if (neg_flags & NTLMSSP_NEGOTIATE_SIGN)
78 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n"));
79 if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)
80 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n"));
81 if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
82 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n"));
83 if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)
84 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n"));
85 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM)
86 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n"));
87 if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED)
88 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n"));
89 if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED)
90 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n"));
91 if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL)
92 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
93 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
94 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
95 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
96 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n"));
97 if (neg_flags & NTLMSSP_CHAL_TARGET_INFO)
98 DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n"));
99 if (neg_flags & NTLMSSP_NEGOTIATE_128)
100 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n"));
101 if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
102 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
106 * Default challenge generation code.
110 static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state)
112 uint8_t *chal = talloc_size(ntlmssp_state, 8);
113 generate_random_buffer(chal, 8);
119 * Default 'we can set the challenge to anything we like' implementation
123 static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
129 * Default 'we can set the challenge to anything we like' implementation
131 * Does not actually do anything, as the value is always in the structure anyway.
135 static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
137 SMB_ASSERT(challenge->length == 8);
142 * Set a username on an NTLMSSP context - ensures it is talloc()ed
146 NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user)
149 /* it should be at least "" */
150 return NT_STATUS_INVALID_PARAMETER;
152 ntlmssp_state->user = talloc_strdup(ntlmssp_state, user);
153 if (!ntlmssp_state->user) {
154 return NT_STATUS_NO_MEMORY;
160 * Set a password on an NTLMSSP context - ensures it is talloc()ed
163 NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password)
166 ntlmssp_state->password = NULL;
168 ntlmssp_state->password = talloc_strdup(ntlmssp_state, password);
169 if (!ntlmssp_state->password) {
170 return NT_STATUS_NO_MEMORY;
177 * Set a domain on an NTLMSSP context - ensures it is talloc()ed
180 NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain)
182 ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain);
183 if (!ntlmssp_state->domain) {
184 return NT_STATUS_NO_MEMORY;
190 * Set a workstation on an NTLMSSP context - ensures it is talloc()ed
193 NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation)
195 ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
196 if (!ntlmssp_state->domain) {
197 return NT_STATUS_NO_MEMORY;
203 * Store a DATA_BLOB containing an NTLMSSP response, for use later.
204 * This copies the data blob
207 NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state,
210 ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state,
211 response.data, response.length);
216 * Next state function for the NTLMSSP state machine
218 * @param ntlmssp_state NTLMSSP State
219 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
220 * @param in The request, as a DATA_BLOB
221 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
222 * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,
223 * or NT_STATUS_OK if the user is authenticated.
226 NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
227 TALLOC_CTX *out_mem_ctx,
228 const DATA_BLOB in, DATA_BLOB *out)
231 uint32_t ntlmssp_command;
234 *out = data_blob(NULL, 0);
236 if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
241 /* if the caller doesn't want to manage/own the memory,
242 we can put it on our context */
243 out_mem_ctx = ntlmssp_state;
246 if (!in.length && ntlmssp_state->stored_response.length) {
247 input = ntlmssp_state->stored_response;
249 /* we only want to read the stored response once - overwrite it */
250 ntlmssp_state->stored_response = data_blob(NULL, 0);
256 switch (ntlmssp_state->role) {
258 ntlmssp_command = NTLMSSP_INITIAL;
261 /* 'datagram' mode - no neg packet */
262 ntlmssp_command = NTLMSSP_NEGOTIATE;
266 if (!msrpc_parse(ntlmssp_state,
270 DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
271 dump_data(2, input.data, input.length);
272 return NT_STATUS_INVALID_PARAMETER;
276 if (ntlmssp_command != ntlmssp_state->expected_state) {
277 DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
278 return NT_STATUS_INVALID_PARAMETER;
281 for (i=0; ntlmssp_callbacks[i].fn; i++) {
282 if (ntlmssp_callbacks[i].role == ntlmssp_state->role
283 && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command
284 && ntlmssp_callbacks[i].fn) {
285 return ntlmssp_callbacks[i].fn(ntlmssp_state, out_mem_ctx, input, out);
289 DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n",
290 ntlmssp_state->role, ntlmssp_command));
292 return NT_STATUS_INVALID_PARAMETER;
296 * Return the NTLMSSP master session key
298 * @param ntlmssp_state NTLMSSP State
301 NTSTATUS ntlmssp_session_key(struct ntlmssp_state *ntlmssp_state,
302 DATA_BLOB *session_key)
304 if (!ntlmssp_state->session_key.data) {
305 return NT_STATUS_NO_USER_SESSION_KEY;
307 *session_key = ntlmssp_state->session_key;
313 * End an NTLMSSP state machine
315 * @param ntlmssp_state NTLMSSP State, free()ed by this function
318 void ntlmssp_end(struct ntlmssp_state **ntlmssp_state)
320 (*ntlmssp_state)->ref_count--;
322 if ((*ntlmssp_state)->ref_count == 0) {
323 talloc_free(*ntlmssp_state);
326 *ntlmssp_state = NULL;
331 * Determine correct target name flags for reply, given server role
332 * and negotiated flags
334 * @param ntlmssp_state NTLMSSP State
335 * @param neg_flags The flags from the packet
336 * @param chal_flags The flags to be set in the reply packet
337 * @return The 'target name' string.
340 static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
341 uint32_t neg_flags, uint32_t *chal_flags)
343 if (neg_flags & NTLMSSP_REQUEST_TARGET) {
344 *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
345 *chal_flags |= NTLMSSP_REQUEST_TARGET;
346 if (ntlmssp_state->server_role == ROLE_STANDALONE) {
347 *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
348 return ntlmssp_state->get_global_myname();
350 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
351 return ntlmssp_state->get_domain();
358 static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
359 uint32_t neg_flags, BOOL allow_lm) {
360 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
361 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
362 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
363 ntlmssp_state->unicode = True;
365 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
366 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
367 ntlmssp_state->unicode = False;
370 if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !ntlmssp_state->use_ntlmv2) {
371 /* other end forcing us to use LM */
372 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
373 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
375 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
378 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) {
379 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
382 if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
383 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
386 if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
387 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
390 if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
391 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
394 if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
395 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
396 if (neg_flags & NTLMSSP_NEGOTIATE_56) {
397 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
401 if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
402 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
405 if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
406 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
409 if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
410 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
416 Weaken NTLMSSP keys to cope with down-level clients and servers.
418 We probably should have some parameters to control this, but as
419 it only occours for LM_KEY connections, and this is controlled
420 by the client lanman auth/lanman auth parameters, it isn't too bad.
423 static void ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state) {
424 /* Key weakening not performed on the master key for NTLM2
425 and does not occour for NTLM1. Therefore we only need
426 to do this for the LM_KEY.
429 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
430 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
432 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
433 ntlmssp_state->session_key.data[7] = 0xa0;
434 } else { /* forty bits */
435 ntlmssp_state->session_key.data[5] = 0xe5;
436 ntlmssp_state->session_key.data[6] = 0x38;
437 ntlmssp_state->session_key.data[7] = 0xb0;
439 ntlmssp_state->session_key.length = 8;
444 * Next state function for the Negotiate packet
446 * @param ntlmssp_state NTLMSSP State
447 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
448 * @param in The request, as a DATA_BLOB
449 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
450 * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent.
453 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
454 TALLOC_CTX *out_mem_ctx,
455 const DATA_BLOB in, DATA_BLOB *out)
457 DATA_BLOB struct_blob;
458 fstring dnsname, dnsdomname;
459 uint32_t neg_flags = 0;
460 uint32_t ntlmssp_command, chal_flags;
461 char *cliname=NULL, *domname=NULL;
462 const uint8_t *cryptkey;
463 const char *target_name;
465 /* parse the NTLMSSP packet */
467 file_save("ntlmssp_negotiate.dat", request.data, request.length);
471 if (!msrpc_parse(ntlmssp_state,
478 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
479 dump_data(2, in.data, in.length);
480 return NT_STATUS_INVALID_PARAMETER;
483 debug_ntlmssp_flags(neg_flags);
486 ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key);
488 /* Ask our caller what challenge they would like in the packet */
489 cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
491 /* Check if we may set the challenge */
492 if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
493 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
496 /* The flags we send back are not just the negotiated flags,
497 * they are also 'what is in this packet'. Therfore, we
498 * operate on 'chal_flags' from here on
501 chal_flags = ntlmssp_state->neg_flags;
503 /* get the right name to fill in as 'target' */
504 target_name = ntlmssp_target_name(ntlmssp_state,
505 neg_flags, &chal_flags);
506 if (target_name == NULL)
507 return NT_STATUS_INVALID_PARAMETER;
509 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
510 ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
512 /* This should be a 'netbios domain -> DNS domain' mapping */
513 dnsdomname[0] = '\0';
514 get_mydomname(dnsdomname);
515 strlower_m(dnsdomname);
518 get_myfullname(dnsname);
520 /* This creates the 'blob' of names that appears at the end of the packet */
521 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO)
523 const char *target_name_dns = "";
524 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
525 target_name_dns = dnsdomname;
526 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
527 target_name_dns = dnsname;
530 msrpc_gen(out_mem_ctx,
531 &struct_blob, "aaaaa",
532 NTLMSSP_NAME_TYPE_DOMAIN, target_name,
533 NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
534 NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
535 NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
538 struct_blob = data_blob(NULL, 0);
542 /* Marshel the packet in the right format, be it unicode or ASCII */
543 const char *gen_string;
544 if (ntlmssp_state->unicode) {
545 gen_string = "CdUdbddB";
547 gen_string = "CdAdbddB";
550 msrpc_gen(out_mem_ctx,
558 struct_blob.data, struct_blob.length);
561 ntlmssp_state->expected_state = NTLMSSP_AUTH;
563 return NT_STATUS_MORE_PROCESSING_REQUIRED;
567 * Next state function for the Authenticate packet
569 * @param ntlmssp_state NTLMSSP State
570 * @param request The request, as a DATA_BLOB
571 * @return Errors or NT_STATUS_OK.
574 static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state,
575 const DATA_BLOB request)
577 uint32_t ntlmssp_command, auth_flags;
580 uint8_t session_nonce_hash[16];
582 const char *parse_string;
585 char *workstation = NULL;
588 file_save("ntlmssp_auth.dat", request.data, request.length);
591 if (ntlmssp_state->unicode) {
592 parse_string = "CdBBUUUBd";
594 parse_string = "CdBBAAABd";
598 data_blob_free(&ntlmssp_state->lm_resp);
599 data_blob_free(&ntlmssp_state->nt_resp);
601 ntlmssp_state->user = NULL;
602 ntlmssp_state->domain = NULL;
603 ntlmssp_state->workstation = NULL;
605 /* now the NTLMSSP encoded auth hashes */
606 if (!msrpc_parse(ntlmssp_state,
607 &request, parse_string,
610 &ntlmssp_state->lm_resp,
611 &ntlmssp_state->nt_resp,
615 &ntlmssp_state->encrypted_session_key,
617 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
618 dump_data(10, request.data, request.length);
621 data_blob_free(&ntlmssp_state->encrypted_session_key);
624 /* Try again with a shorter string (Win9X truncates this packet) */
625 if (ntlmssp_state->unicode) {
626 parse_string = "CdBBUUU";
628 parse_string = "CdBBAAA";
631 /* now the NTLMSSP encoded auth hashes */
632 if (!msrpc_parse(ntlmssp_state,
633 &request, parse_string,
636 &ntlmssp_state->lm_resp,
637 &ntlmssp_state->nt_resp,
641 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
642 dump_data(2, request.data, request.length);
644 return NT_STATUS_INVALID_PARAMETER;
649 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key);
651 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
653 data_blob_free(&ntlmssp_state->encrypted_session_key);
657 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
659 data_blob_free(&ntlmssp_state->encrypted_session_key);
663 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
665 data_blob_free(&ntlmssp_state->encrypted_session_key);
669 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
670 ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
673 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);
674 file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length);
677 /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
680 However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
682 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
683 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
684 struct MD5Context md5_session_nonce_ctx;
685 SMB_ASSERT(ntlmssp_state->internal_chal.data
686 && ntlmssp_state->internal_chal.length == 8);
688 ntlmssp_state->doing_ntlm2 = True;
690 memcpy(ntlmssp_state->session_nonce, ntlmssp_state->internal_chal.data, 8);
691 memcpy(&ntlmssp_state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
693 MD5Init(&md5_session_nonce_ctx);
694 MD5Update(&md5_session_nonce_ctx, ntlmssp_state->session_nonce, 16);
695 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
697 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state,
698 session_nonce_hash, 8);
700 /* LM response is no longer useful, zero it out */
701 data_blob_free(&ntlmssp_state->lm_resp);
703 /* We changed the effective challenge - set it */
704 if (!NT_STATUS_IS_OK(nt_status =
705 ntlmssp_state->set_challenge(ntlmssp_state,
706 &ntlmssp_state->chal))) {
708 data_blob_free(&ntlmssp_state->encrypted_session_key);
712 /* LM Key is incompatible... */
713 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
720 * Next state function for the Authenticate packet
721 * (after authentication - figures out the session keys etc)
723 * @param ntlmssp_state NTLMSSP State
724 * @return Errors or NT_STATUS_OK.
727 static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
728 DATA_BLOB *user_session_key,
729 DATA_BLOB *lm_session_key)
732 DATA_BLOB session_key = data_blob(NULL, 0);
734 if (user_session_key)
735 dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length);
738 dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length);
740 /* Handle the different session key derivation for NTLM2 */
741 if (ntlmssp_state->doing_ntlm2) {
742 if (user_session_key && user_session_key->data && user_session_key->length == 16) {
743 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
744 hmac_md5(user_session_key->data, ntlmssp_state->session_nonce,
745 sizeof(ntlmssp_state->session_nonce), session_key.data);
746 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
747 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
750 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
751 session_key = data_blob(NULL, 0);
753 } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
754 /* Ensure we can never get here on NTLMv2 */
755 && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
757 if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
758 if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
759 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
760 SMBsesskeygen_lm_sess_key(lm_session_key->data, ntlmssp_state->lm_resp.data,
762 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
763 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
766 /* When there is no LM response, just use zeros */
767 static const uint8_t zeros[24];
768 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
769 SMBsesskeygen_lm_sess_key(zeros, zeros,
771 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
772 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
775 /* LM Key not selected */
776 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
778 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
779 session_key = data_blob(NULL, 0);
782 } else if (user_session_key && user_session_key->data) {
783 session_key = *user_session_key;
784 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
785 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
787 /* LM Key not selected */
788 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
790 } else if (lm_session_key && lm_session_key->data) {
791 /* Very weird to have LM key, but no user session key, but anyway.. */
792 session_key = *lm_session_key;
793 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
794 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
796 /* LM Key not selected */
797 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
800 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
801 session_key = data_blob(NULL, 0);
803 /* LM Key not selected */
804 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
807 /* With KEY_EXCH, the client supplies the proposed session key,
808 but encrypts it with the long-term key */
809 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
810 if (!ntlmssp_state->encrypted_session_key.data
811 || ntlmssp_state->encrypted_session_key.length != 16) {
812 data_blob_free(&ntlmssp_state->encrypted_session_key);
813 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
814 ntlmssp_state->encrypted_session_key.length));
815 return NT_STATUS_INVALID_PARAMETER;
816 } else if (!session_key.data || session_key.length != 16) {
817 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
818 session_key.length));
819 ntlmssp_state->session_key = session_key;
821 dump_data_pw("KEY_EXCH session key (enc):\n",
822 ntlmssp_state->encrypted_session_key.data,
823 ntlmssp_state->encrypted_session_key.length);
824 arcfour_crypt(ntlmssp_state->encrypted_session_key.data,
826 ntlmssp_state->encrypted_session_key.length);
827 ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
828 ntlmssp_state->encrypted_session_key.data,
829 ntlmssp_state->encrypted_session_key.length);
830 dump_data_pw("KEY_EXCH session key:\n", ntlmssp_state->encrypted_session_key.data,
831 ntlmssp_state->encrypted_session_key.length);
834 ntlmssp_state->session_key = session_key;
837 /* The server might need us to use a partial-strength session key */
838 ntlmssp_weaken_keys(ntlmssp_state);
840 nt_status = ntlmssp_sign_init(ntlmssp_state);
842 data_blob_free(&ntlmssp_state->encrypted_session_key);
844 /* allow arbitarily many authentications, but watch that this will cause a
845 memory leak, until the ntlmssp_state is shutdown
848 if (ntlmssp_state->server_multiple_authentications) {
849 ntlmssp_state->expected_state = NTLMSSP_AUTH;
851 ntlmssp_state->expected_state = NTLMSSP_DONE;
859 * Next state function for the Authenticate packet
861 * @param ntlmssp_state NTLMSSP State
862 * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
863 * @param out The reply, as an allocated DATA_BLOB, caller to free.
864 * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK.
867 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
868 TALLOC_CTX *out_mem_ctx,
869 const DATA_BLOB in, DATA_BLOB *out)
871 DATA_BLOB user_session_key = data_blob(NULL, 0);
872 DATA_BLOB lm_session_key = data_blob(NULL, 0);
875 /* zero the outbound NTLMSSP packet */
876 *out = data_blob_talloc(out_mem_ctx, NULL, 0);
878 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(ntlmssp_state, in))) {
883 * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
884 * is required (by "ntlm auth = no" and "lm auth = no" being set in the
885 * smb.conf file) and no NTLMv2 response was sent then the password check
886 * will fail here. JRA.
889 /* Finally, actually ask if the password is OK */
891 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state,
892 &user_session_key, &lm_session_key))) {
896 if (ntlmssp_state->server_use_session_keys) {
897 return ntlmssp_server_postauth(ntlmssp_state, &user_session_key, &lm_session_key);
899 ntlmssp_state->session_key = data_blob(NULL, 0);
905 * Create an NTLMSSP state machine
907 * @param ntlmssp_state NTLMSSP State, allocated by this function
910 NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
912 *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state);
913 if (!*ntlmssp_state) {
914 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
915 return NT_STATUS_NO_MEMORY;
917 ZERO_STRUCTP(*ntlmssp_state);
919 (*ntlmssp_state)->role = NTLMSSP_SERVER;
921 (*ntlmssp_state)->get_challenge = get_challenge;
922 (*ntlmssp_state)->set_challenge = set_challenge;
923 (*ntlmssp_state)->may_set_challenge = may_set_challenge;
925 (*ntlmssp_state)->get_global_myname = lp_netbios_name;
926 (*ntlmssp_state)->get_domain = lp_workgroup;
927 (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
929 (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
931 (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
932 && lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False));
934 (*ntlmssp_state)->server_use_session_keys = True;
935 (*ntlmssp_state)->server_multiple_authentications = False;
937 (*ntlmssp_state)->ref_count = 1;
939 (*ntlmssp_state)->neg_flags =
940 NTLMSSP_NEGOTIATE_NTLM;
942 if (lp_parm_bool(-1, "ntlmssp_server", "128bit", True)) {
943 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
946 if (lp_parm_bool(-1, "ntlmssp_server", "keyexchange", True)) {
947 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
950 if (lp_parm_bool(-1, "ntlmssp_server", "ntlm2", True)) {
951 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
957 /*********************************************************************
959 *********************************************************************/
962 * Next state function for the Initial packet
964 * @param ntlmssp_state NTLMSSP State
965 * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context
966 * @param in The request, as a DATA_BLOB. reply.data must be NULL
967 * @param out The reply, as an talloc()ed DATA_BLOB, on out_mem_ctx
968 * @return Errors or NT_STATUS_OK.
971 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
972 TALLOC_CTX *out_mem_ctx,
973 DATA_BLOB in, DATA_BLOB *out)
975 if (ntlmssp_state->unicode) {
976 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
978 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
981 if (ntlmssp_state->use_ntlmv2) {
982 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
985 /* generate the ntlmssp negotiate packet */
986 msrpc_gen(out_mem_ctx,
990 ntlmssp_state->neg_flags,
991 ntlmssp_state->get_domain(),
992 ntlmssp_state->get_global_myname());
994 ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
996 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1000 * Next state function for the Challenge Packet. Generate an auth packet.
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.
1008 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
1009 TALLOC_CTX *out_mem_ctx,
1010 const DATA_BLOB in, DATA_BLOB *out)
1012 uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
1013 DATA_BLOB server_domain_blob;
1014 DATA_BLOB challenge_blob;
1015 DATA_BLOB struct_blob = data_blob(NULL, 0);
1016 char *server_domain;
1017 const char *chal_parse_string;
1018 const char *auth_gen_string;
1019 uint8_t lm_hash[16];
1020 DATA_BLOB lm_response = data_blob(NULL, 0);
1021 DATA_BLOB nt_response = data_blob(NULL, 0);
1022 DATA_BLOB session_key = data_blob(NULL, 0);
1023 DATA_BLOB lm_session_key = data_blob(NULL, 0);
1024 DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
1027 if (!msrpc_parse(ntlmssp_state,
1031 &server_domain_blob,
1033 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
1034 dump_data(2, in.data, in.length);
1036 return NT_STATUS_INVALID_PARAMETER;
1039 data_blob_free(&server_domain_blob);
1041 DEBUG(3, ("Got challenge flags:\n"));
1042 debug_ntlmssp_flags(chal_flags);
1044 ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key);
1046 if (ntlmssp_state->unicode) {
1047 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1048 chal_parse_string = "CdUdbddB";
1050 chal_parse_string = "CdUdbdd";
1052 auth_gen_string = "CdBBUUUBd";
1054 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1055 chal_parse_string = "CdAdbddB";
1057 chal_parse_string = "CdAdbdd";
1060 auth_gen_string = "CdBBAAABd";
1063 DEBUG(3, ("NTLMSSP: Set final flags:\n"));
1064 debug_ntlmssp_flags(ntlmssp_state->neg_flags);
1066 if (!msrpc_parse(ntlmssp_state,
1067 &in, chal_parse_string,
1075 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
1076 dump_data(2, in.data, in.length);
1077 return NT_STATUS_INVALID_PARAMETER;
1080 ntlmssp_state->server_domain = server_domain;
1082 if (challenge_blob.length != 8) {
1083 return NT_STATUS_INVALID_PARAMETER;
1086 if (!ntlmssp_state->password) {
1087 static const uint8_t zeros[16];
1088 /* do nothing - blobs are zero length */
1090 /* session key is all zeros */
1091 session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1092 lm_session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1094 /* not doing NLTM2 without a password */
1095 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
1096 } else if (ntlmssp_state->use_ntlmv2) {
1098 if (!struct_blob.length) {
1099 /* be lazy, match win2k - we can't do NTLMv2 without it */
1100 DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
1101 return NT_STATUS_INVALID_PARAMETER;
1104 /* TODO: if the remote server is standalone, then we should replace 'domain'
1105 with the server name as supplied above */
1107 if (!SMBNTLMv2encrypt(ntlmssp_state->user,
1108 ntlmssp_state->domain,
1109 ntlmssp_state->password, &challenge_blob,
1111 &lm_response, &nt_response,
1112 NULL, &session_key)) {
1113 data_blob_free(&challenge_blob);
1114 data_blob_free(&struct_blob);
1115 return NT_STATUS_NO_MEMORY;
1118 /* LM Key is incompatible... */
1119 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1121 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
1122 struct MD5Context md5_session_nonce_ctx;
1123 uint8_t nt_hash[16];
1124 uint8_t session_nonce[16];
1125 uint8_t session_nonce_hash[16];
1126 uint8_t user_session_key[16];
1127 E_md4hash(ntlmssp_state->password, nt_hash);
1129 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1130 generate_random_buffer(lm_response.data, 8);
1131 memset(lm_response.data+8, 0, 16);
1133 memcpy(session_nonce, challenge_blob.data, 8);
1134 memcpy(&session_nonce[8], lm_response.data, 8);
1136 MD5Init(&md5_session_nonce_ctx);
1137 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
1138 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
1139 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
1141 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
1142 DEBUG(5, ("challenge is: \n"));
1143 dump_data(5, session_nonce_hash, 8);
1145 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1146 SMBNTencrypt(ntlmssp_state->password,
1150 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1152 SMBsesskeygen_ntv1(nt_hash, user_session_key);
1153 hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
1154 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
1156 /* LM Key is incompatible... */
1157 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1159 uint8_t nt_hash[16];
1161 if (ntlmssp_state->use_nt_response) {
1162 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1163 SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
1165 E_md4hash(ntlmssp_state->password, nt_hash);
1166 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1167 SMBsesskeygen_ntv1(nt_hash, session_key.data);
1168 dump_data_pw("NT session key:\n", session_key.data, session_key.length);
1171 /* lanman auth is insecure, it may be disabled */
1172 if (lp_client_lanman_auth()) {
1173 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1174 if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data,
1175 lm_response.data)) {
1176 /* If the LM password was too long (and therefore the LM hash being
1177 of the first 14 chars only), don't send it */
1178 data_blob_free(&lm_response);
1180 /* LM Key is incompatible with 'long' passwords */
1181 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1183 E_deshash(ntlmssp_state->password, lm_hash);
1184 lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1185 memcpy(lm_session_key.data, lm_hash, 8);
1186 memset(&lm_session_key.data[8], '\0', 8);
1188 if (!ntlmssp_state->use_nt_response) {
1189 session_key = lm_session_key;
1193 /* LM Key is incompatible... */
1194 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1198 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
1199 && lp_client_lanman_auth() && lm_session_key.length == 16) {
1200 DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1201 if (lm_response.length == 24) {
1202 SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data,
1203 new_session_key.data);
1205 static const uint8_t zeros[24];
1206 SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros,
1207 new_session_key.data);
1209 new_session_key.length = 16;
1210 session_key = new_session_key;
1211 dump_data_pw("LM session key\n", session_key.data, session_key.length);
1215 /* Key exchange encryptes a new client-generated session key with
1216 the password-derived key */
1217 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1218 /* Make up a new session key */
1219 uint8_t client_session_key[16];
1220 generate_random_buffer(client_session_key, sizeof(client_session_key));
1222 /* Encrypt the new session key with the old one */
1223 encrypted_session_key = data_blob_talloc(ntlmssp_state,
1224 client_session_key, sizeof(client_session_key));
1225 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
1226 arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
1227 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
1229 /* Mark the new session key as the 'real' session key */
1230 session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key));
1233 /* this generates the actual auth packet */
1234 if (!msrpc_gen(out_mem_ctx,
1235 out, auth_gen_string,
1238 lm_response.data, lm_response.length,
1239 nt_response.data, nt_response.length,
1240 ntlmssp_state->domain,
1241 ntlmssp_state->user,
1242 ntlmssp_state->get_global_myname(),
1243 encrypted_session_key.data, encrypted_session_key.length,
1244 ntlmssp_state->neg_flags)) {
1246 return NT_STATUS_NO_MEMORY;
1249 ntlmssp_state->session_key = session_key;
1251 /* The client might be using 56 or 40 bit weakened keys */
1252 ntlmssp_weaken_keys(ntlmssp_state);
1254 ntlmssp_state->chal = challenge_blob;
1255 ntlmssp_state->lm_resp = lm_response;
1256 ntlmssp_state->nt_resp = nt_response;
1258 ntlmssp_state->expected_state = NTLMSSP_DONE;
1260 nt_status = ntlmssp_sign_init(ntlmssp_state);
1261 if (!NT_STATUS_IS_OK(nt_status)) {
1262 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
1263 nt_errstr(nt_status)));
1270 NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
1272 *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state);
1273 if (!*ntlmssp_state) {
1274 DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
1275 return NT_STATUS_NO_MEMORY;
1277 ZERO_STRUCTP(*ntlmssp_state);
1279 (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1281 (*ntlmssp_state)->get_global_myname = lp_netbios_name;
1282 (*ntlmssp_state)->get_domain = lp_workgroup;
1284 (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True);
1286 (*ntlmssp_state)->use_nt_response = lp_parm_bool(-1, "ntlmssp_client", "send_nt_reponse", True);
1288 (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
1289 && lp_parm_bool(-1, "ntlmssp_client", "allow_lm_key", False));
1291 (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1293 (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1295 (*ntlmssp_state)->ref_count = 1;
1297 (*ntlmssp_state)->neg_flags =
1298 NTLMSSP_NEGOTIATE_NTLM |
1299 NTLMSSP_REQUEST_TARGET;
1301 if (lp_parm_bool(-1, "ntlmssp_client", "128bit", True)) {
1302 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
1305 if (lp_parm_bool(-1, "ntlmssp_client", "keyexchange", True)) {
1306 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
1309 if (lp_parm_bool(-1, "ntlmssp_client", "ntlm2", True)) {
1310 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
1312 /* apparently we can't do ntlmv2 if we don't do ntlm2 */
1313 (*ntlmssp_state)->use_ntlmv2 = False;
1316 return NT_STATUS_OK;