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(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)
148 ntlmssp_state->user = talloc_strdup(ntlmssp_state, user);
149 if (!ntlmssp_state->user) {
150 return NT_STATUS_NO_MEMORY;
156 * Set a password on an NTLMSSP context - ensures it is talloc()ed
159 NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password)
162 ntlmssp_state->password = NULL;
164 ntlmssp_state->password = talloc_strdup(ntlmssp_state, password);
165 if (!ntlmssp_state->password) {
166 return NT_STATUS_NO_MEMORY;
173 * Set a domain on an NTLMSSP context - ensures it is talloc()ed
176 NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain)
178 ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain);
179 if (!ntlmssp_state->domain) {
180 return NT_STATUS_NO_MEMORY;
186 * Set a workstation on an NTLMSSP context - ensures it is talloc()ed
189 NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation)
191 ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
192 if (!ntlmssp_state->domain) {
193 return NT_STATUS_NO_MEMORY;
199 * Store a DATA_BLOB containing an NTLMSSP response, for use later.
200 * This copies the data blob
203 NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state,
206 ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state,
207 response.data, response.length);
212 * Next state function for the NTLMSSP state machine
214 * @param ntlmssp_state NTLMSSP State
215 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
216 * @param in The request, as a DATA_BLOB
217 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
218 * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,
219 * or NT_STATUS_OK if the user is authenticated.
222 NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
223 TALLOC_CTX *out_mem_ctx,
224 const DATA_BLOB in, DATA_BLOB *out)
227 uint32_t ntlmssp_command;
230 *out = data_blob(NULL, 0);
232 if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
237 /* if the caller doesn't want to manage/own the memory,
238 we can put it on our context */
239 out_mem_ctx = ntlmssp_state;
242 if (!in.length && ntlmssp_state->stored_response.length) {
243 input = ntlmssp_state->stored_response;
245 /* we only want to read the stored response once - overwrite it */
246 ntlmssp_state->stored_response = data_blob(NULL, 0);
252 switch (ntlmssp_state->role) {
254 ntlmssp_command = NTLMSSP_INITIAL;
257 /* 'datagram' mode - no neg packet */
258 ntlmssp_command = NTLMSSP_NEGOTIATE;
262 if (!msrpc_parse(ntlmssp_state,
266 DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
267 dump_data(2, input.data, input.length);
268 return NT_STATUS_INVALID_PARAMETER;
272 if (ntlmssp_command != ntlmssp_state->expected_state) {
273 DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
274 return NT_STATUS_INVALID_PARAMETER;
277 for (i=0; ntlmssp_callbacks[i].fn; i++) {
278 if (ntlmssp_callbacks[i].role == ntlmssp_state->role
279 && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command
280 && ntlmssp_callbacks[i].fn) {
281 return ntlmssp_callbacks[i].fn(ntlmssp_state, out_mem_ctx, input, out);
285 DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n",
286 ntlmssp_state->role, ntlmssp_command));
288 return NT_STATUS_INVALID_PARAMETER;
292 * Return the NTLMSSP master session key
294 * @param ntlmssp_state NTLMSSP State
297 NTSTATUS ntlmssp_session_key(struct ntlmssp_state *ntlmssp_state,
298 DATA_BLOB *session_key)
300 if (!ntlmssp_state->session_key.data) {
301 return NT_STATUS_NO_USER_SESSION_KEY;
303 *session_key = ntlmssp_state->session_key;
309 * End an NTLMSSP state machine
311 * @param ntlmssp_state NTLMSSP State, free()ed by this function
314 void ntlmssp_end(struct ntlmssp_state **ntlmssp_state)
316 (*ntlmssp_state)->ref_count--;
318 if ((*ntlmssp_state)->ref_count == 0) {
319 talloc_free(*ntlmssp_state);
322 *ntlmssp_state = NULL;
327 * Determine correct target name flags for reply, given server role
328 * and negotiated flags
330 * @param ntlmssp_state NTLMSSP State
331 * @param neg_flags The flags from the packet
332 * @param chal_flags The flags to be set in the reply packet
333 * @return The 'target name' string.
336 static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
337 uint32_t neg_flags, uint32_t *chal_flags)
339 if (neg_flags & NTLMSSP_REQUEST_TARGET) {
340 *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
341 *chal_flags |= NTLMSSP_REQUEST_TARGET;
342 if (ntlmssp_state->server_role == ROLE_STANDALONE) {
343 *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
344 return ntlmssp_state->get_global_myname();
346 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
347 return ntlmssp_state->get_domain();
354 static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
355 uint32_t neg_flags, BOOL allow_lm) {
356 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
357 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
358 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
359 ntlmssp_state->unicode = True;
361 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
362 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
363 ntlmssp_state->unicode = False;
366 if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !ntlmssp_state->use_ntlmv2) {
367 /* other end forcing us to use LM */
368 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
369 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
371 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
374 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) {
375 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
378 if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
379 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
382 if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
383 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
386 if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
387 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
390 if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
391 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
392 if (neg_flags & NTLMSSP_NEGOTIATE_56) {
393 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
397 if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
398 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
401 if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
402 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
405 if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
406 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
412 Weaken NTLMSSP keys to cope with down-level clients and servers.
414 We probably should have some parameters to control this, but as
415 it only occours for LM_KEY connections, and this is controlled
416 by the client lanman auth/lanman auth parameters, it isn't too bad.
419 static void ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state) {
420 /* Key weakening not performed on the master key for NTLM2
421 and does not occour for NTLM1. Therefore we only need
422 to do this for the LM_KEY.
425 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
426 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
428 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
429 ntlmssp_state->session_key.data[7] = 0xa0;
430 } else { /* forty bits */
431 ntlmssp_state->session_key.data[5] = 0xe5;
432 ntlmssp_state->session_key.data[6] = 0x38;
433 ntlmssp_state->session_key.data[7] = 0xb0;
435 ntlmssp_state->session_key.length = 8;
440 * Next state function for the Negotiate packet
442 * @param ntlmssp_state NTLMSSP State
443 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
444 * @param in The request, as a DATA_BLOB
445 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
446 * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent.
449 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
450 TALLOC_CTX *out_mem_ctx,
451 const DATA_BLOB in, DATA_BLOB *out)
453 DATA_BLOB struct_blob;
454 fstring dnsname, dnsdomname;
455 uint32_t neg_flags = 0;
456 uint32_t ntlmssp_command, chal_flags;
457 char *cliname=NULL, *domname=NULL;
458 const uint8_t *cryptkey;
459 const char *target_name;
461 /* parse the NTLMSSP packet */
463 file_save("ntlmssp_negotiate.dat", request.data, request.length);
467 if (!msrpc_parse(ntlmssp_state,
474 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
475 dump_data(2, in.data, in.length);
476 return NT_STATUS_INVALID_PARAMETER;
479 debug_ntlmssp_flags(neg_flags);
482 ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key);
484 /* Ask our caller what challenge they would like in the packet */
485 cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
487 /* Check if we may set the challenge */
488 if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
489 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
492 /* The flags we send back are not just the negotiated flags,
493 * they are also 'what is in this packet'. Therfore, we
494 * operate on 'chal_flags' from here on
497 chal_flags = ntlmssp_state->neg_flags;
499 /* get the right name to fill in as 'target' */
500 target_name = ntlmssp_target_name(ntlmssp_state,
501 neg_flags, &chal_flags);
502 if (target_name == NULL)
503 return NT_STATUS_INVALID_PARAMETER;
505 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
506 ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
508 /* This should be a 'netbios domain -> DNS domain' mapping */
509 dnsdomname[0] = '\0';
510 get_mydomname(dnsdomname);
511 strlower_m(dnsdomname);
514 get_myfullname(dnsname);
516 /* This creates the 'blob' of names that appears at the end of the packet */
517 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO)
519 const char *target_name_dns = "";
520 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
521 target_name_dns = dnsdomname;
522 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
523 target_name_dns = dnsname;
526 msrpc_gen(out_mem_ctx,
527 &struct_blob, "aaaaa",
528 NTLMSSP_NAME_TYPE_DOMAIN, target_name,
529 NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
530 NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
531 NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
534 struct_blob = data_blob(NULL, 0);
538 /* Marshel the packet in the right format, be it unicode or ASCII */
539 const char *gen_string;
540 if (ntlmssp_state->unicode) {
541 gen_string = "CdUdbddB";
543 gen_string = "CdAdbddB";
546 msrpc_gen(out_mem_ctx,
554 struct_blob.data, struct_blob.length);
557 ntlmssp_state->expected_state = NTLMSSP_AUTH;
559 return NT_STATUS_MORE_PROCESSING_REQUIRED;
563 * Next state function for the Authenticate packet
565 * @param ntlmssp_state NTLMSSP State
566 * @param request The request, as a DATA_BLOB
567 * @return Errors or NT_STATUS_OK.
570 static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state,
571 const DATA_BLOB request)
573 uint32_t ntlmssp_command, auth_flags;
576 uint8_t session_nonce_hash[16];
578 const char *parse_string;
581 char *workstation = NULL;
584 file_save("ntlmssp_auth.dat", request.data, request.length);
587 if (ntlmssp_state->unicode) {
588 parse_string = "CdBBUUUBd";
590 parse_string = "CdBBAAABd";
594 data_blob_free(&ntlmssp_state->lm_resp);
595 data_blob_free(&ntlmssp_state->nt_resp);
597 ntlmssp_state->user = NULL;
598 ntlmssp_state->domain = NULL;
599 ntlmssp_state->workstation = NULL;
601 /* now the NTLMSSP encoded auth hashes */
602 if (!msrpc_parse(ntlmssp_state,
603 &request, parse_string,
606 &ntlmssp_state->lm_resp,
607 &ntlmssp_state->nt_resp,
611 &ntlmssp_state->encrypted_session_key,
613 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
614 dump_data(10, request.data, request.length);
617 data_blob_free(&ntlmssp_state->encrypted_session_key);
620 /* Try again with a shorter string (Win9X truncates this packet) */
621 if (ntlmssp_state->unicode) {
622 parse_string = "CdBBUUU";
624 parse_string = "CdBBAAA";
627 /* now the NTLMSSP encoded auth hashes */
628 if (!msrpc_parse(ntlmssp_state,
629 &request, parse_string,
632 &ntlmssp_state->lm_resp,
633 &ntlmssp_state->nt_resp,
637 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
638 dump_data(2, request.data, request.length);
640 return NT_STATUS_INVALID_PARAMETER;
645 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key);
647 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
649 data_blob_free(&ntlmssp_state->encrypted_session_key);
653 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
655 data_blob_free(&ntlmssp_state->encrypted_session_key);
659 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
661 data_blob_free(&ntlmssp_state->encrypted_session_key);
665 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
666 ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
669 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);
670 file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length);
673 /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
676 However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
678 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
679 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
680 struct MD5Context md5_session_nonce_ctx;
681 SMB_ASSERT(ntlmssp_state->internal_chal.data
682 && ntlmssp_state->internal_chal.length == 8);
684 ntlmssp_state->doing_ntlm2 = True;
686 memcpy(ntlmssp_state->session_nonce, ntlmssp_state->internal_chal.data, 8);
687 memcpy(&ntlmssp_state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
689 MD5Init(&md5_session_nonce_ctx);
690 MD5Update(&md5_session_nonce_ctx, ntlmssp_state->session_nonce, 16);
691 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
693 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state,
694 session_nonce_hash, 8);
696 /* LM response is no longer useful, zero it out */
697 data_blob_free(&ntlmssp_state->lm_resp);
699 /* We changed the effective challenge - set it */
700 if (!NT_STATUS_IS_OK(nt_status =
701 ntlmssp_state->set_challenge(ntlmssp_state,
702 &ntlmssp_state->chal))) {
704 data_blob_free(&ntlmssp_state->encrypted_session_key);
708 /* LM Key is incompatible... */
709 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
716 * Next state function for the Authenticate packet
717 * (after authentication - figures out the session keys etc)
719 * @param ntlmssp_state NTLMSSP State
720 * @return Errors or NT_STATUS_OK.
723 static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
724 DATA_BLOB *user_session_key,
725 DATA_BLOB *lm_session_key)
728 DATA_BLOB session_key = data_blob(NULL, 0);
730 if (user_session_key)
731 dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length);
734 dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length);
736 /* Handle the different session key derivation for NTLM2 */
737 if (ntlmssp_state->doing_ntlm2) {
738 if (user_session_key && user_session_key->data && user_session_key->length == 16) {
739 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
740 hmac_md5(user_session_key->data, ntlmssp_state->session_nonce,
741 sizeof(ntlmssp_state->session_nonce), session_key.data);
742 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
743 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
746 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
747 session_key = data_blob(NULL, 0);
749 } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
750 /* Ensure we can never get here on NTLMv2 */
751 && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
753 if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
754 if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
755 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
756 SMBsesskeygen_lm_sess_key(lm_session_key->data, ntlmssp_state->lm_resp.data,
758 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
759 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
762 /* When there is no LM response, just use zeros */
763 static const uint8_t zeros[24];
764 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
765 SMBsesskeygen_lm_sess_key(zeros, zeros,
767 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
768 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
771 /* LM Key not selected */
772 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
774 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
775 session_key = data_blob(NULL, 0);
778 } else if (user_session_key && user_session_key->data) {
779 session_key = *user_session_key;
780 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
781 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
783 /* LM Key not selected */
784 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
786 } else if (lm_session_key && lm_session_key->data) {
787 /* Very weird to have LM key, but no user session key, but anyway.. */
788 session_key = *lm_session_key;
789 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
790 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
792 /* LM Key not selected */
793 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
796 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
797 session_key = data_blob(NULL, 0);
799 /* LM Key not selected */
800 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
803 /* With KEY_EXCH, the client supplies the proposed session key,
804 but encrypts it with the long-term key */
805 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
806 if (!ntlmssp_state->encrypted_session_key.data
807 || ntlmssp_state->encrypted_session_key.length != 16) {
808 data_blob_free(&ntlmssp_state->encrypted_session_key);
809 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
810 ntlmssp_state->encrypted_session_key.length));
811 return NT_STATUS_INVALID_PARAMETER;
812 } else if (!session_key.data || session_key.length != 16) {
813 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
814 session_key.length));
815 ntlmssp_state->session_key = session_key;
817 dump_data_pw("KEY_EXCH session key (enc):\n",
818 ntlmssp_state->encrypted_session_key.data,
819 ntlmssp_state->encrypted_session_key.length);
820 arcfour_crypt(ntlmssp_state->encrypted_session_key.data,
822 ntlmssp_state->encrypted_session_key.length);
823 ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
824 ntlmssp_state->encrypted_session_key.data,
825 ntlmssp_state->encrypted_session_key.length);
826 dump_data_pw("KEY_EXCH session key:\n", ntlmssp_state->encrypted_session_key.data,
827 ntlmssp_state->encrypted_session_key.length);
830 ntlmssp_state->session_key = session_key;
833 /* The server might need us to use a partial-strength session key */
834 ntlmssp_weaken_keys(ntlmssp_state);
836 nt_status = ntlmssp_sign_init(ntlmssp_state);
838 data_blob_free(&ntlmssp_state->encrypted_session_key);
840 /* allow arbitarily many authentications, but watch that this will cause a
841 memory leak, until the ntlmssp_state is shutdown
844 if (ntlmssp_state->server_multiple_authentications) {
845 ntlmssp_state->expected_state = NTLMSSP_AUTH;
847 ntlmssp_state->expected_state = NTLMSSP_DONE;
855 * Next state function for the Authenticate packet
857 * @param ntlmssp_state NTLMSSP State
858 * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
859 * @param out The reply, as an allocated DATA_BLOB, caller to free.
860 * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK.
863 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
864 TALLOC_CTX *out_mem_ctx,
865 const DATA_BLOB in, DATA_BLOB *out)
867 DATA_BLOB user_session_key = data_blob(NULL, 0);
868 DATA_BLOB lm_session_key = data_blob(NULL, 0);
871 /* zero the outbound NTLMSSP packet */
872 *out = data_blob_talloc(out_mem_ctx, NULL, 0);
874 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(ntlmssp_state, in))) {
879 * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
880 * is required (by "ntlm auth = no" and "lm auth = no" being set in the
881 * smb.conf file) and no NTLMv2 response was sent then the password check
882 * will fail here. JRA.
885 /* Finally, actually ask if the password is OK */
887 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state,
888 &user_session_key, &lm_session_key))) {
892 if (ntlmssp_state->server_use_session_keys) {
893 return ntlmssp_server_postauth(ntlmssp_state, &user_session_key, &lm_session_key);
895 ntlmssp_state->session_key = data_blob(NULL, 0);
901 * Create an NTLMSSP state machine
903 * @param ntlmssp_state NTLMSSP State, allocated by this function
906 NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
908 *ntlmssp_state = talloc_p(mem_ctx, struct ntlmssp_state);
909 if (!*ntlmssp_state) {
910 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
911 return NT_STATUS_NO_MEMORY;
913 ZERO_STRUCTP(*ntlmssp_state);
915 (*ntlmssp_state)->role = NTLMSSP_SERVER;
917 (*ntlmssp_state)->get_challenge = get_challenge;
918 (*ntlmssp_state)->set_challenge = set_challenge;
919 (*ntlmssp_state)->may_set_challenge = may_set_challenge;
921 (*ntlmssp_state)->get_global_myname = lp_netbios_name;
922 (*ntlmssp_state)->get_domain = lp_workgroup;
923 (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
925 (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
927 (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
928 && lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False));
930 (*ntlmssp_state)->server_use_session_keys = True;
931 (*ntlmssp_state)->server_multiple_authentications = False;
933 (*ntlmssp_state)->ref_count = 1;
935 (*ntlmssp_state)->neg_flags =
936 NTLMSSP_NEGOTIATE_NTLM;
938 if (lp_parm_bool(-1, "ntlmssp_server", "128bit", True)) {
939 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
942 if (lp_parm_bool(-1, "ntlmssp_server", "keyexchange", True)) {
943 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
946 if (lp_parm_bool(-1, "ntlmssp_server", "ntlm2", True)) {
947 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
953 /*********************************************************************
955 *********************************************************************/
958 * Next state function for the Initial packet
960 * @param ntlmssp_state NTLMSSP State
961 * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context
962 * @param in The request, as a DATA_BLOB. reply.data must be NULL
963 * @param out The reply, as an talloc()ed DATA_BLOB, on out_mem_ctx
964 * @return Errors or NT_STATUS_OK.
967 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
968 TALLOC_CTX *out_mem_ctx,
969 DATA_BLOB in, DATA_BLOB *out)
971 if (ntlmssp_state->unicode) {
972 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
974 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
977 if (ntlmssp_state->use_ntlmv2) {
978 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
981 /* generate the ntlmssp negotiate packet */
982 msrpc_gen(out_mem_ctx,
986 ntlmssp_state->neg_flags,
987 ntlmssp_state->get_domain(),
988 ntlmssp_state->get_global_myname());
990 ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
992 return NT_STATUS_MORE_PROCESSING_REQUIRED;
996 * Next state function for the Challenge Packet. Generate an auth packet.
998 * @param ntlmssp_state NTLMSSP State
999 * @param request The request, as a DATA_BLOB. reply.data must be NULL
1000 * @param request The reply, as an allocated DATA_BLOB, caller to free.
1001 * @return Errors or NT_STATUS_OK.
1004 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
1005 TALLOC_CTX *out_mem_ctx,
1006 const DATA_BLOB in, DATA_BLOB *out)
1008 uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
1009 DATA_BLOB server_domain_blob;
1010 DATA_BLOB challenge_blob;
1011 DATA_BLOB struct_blob = data_blob(NULL, 0);
1012 char *server_domain;
1013 const char *chal_parse_string;
1014 const char *auth_gen_string;
1015 uint8_t lm_hash[16];
1016 DATA_BLOB lm_response = data_blob(NULL, 0);
1017 DATA_BLOB nt_response = data_blob(NULL, 0);
1018 DATA_BLOB session_key = data_blob(NULL, 0);
1019 DATA_BLOB lm_session_key = data_blob(NULL, 0);
1020 DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
1023 if (!msrpc_parse(ntlmssp_state,
1027 &server_domain_blob,
1029 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
1030 dump_data(2, in.data, in.length);
1032 return NT_STATUS_INVALID_PARAMETER;
1035 data_blob_free(&server_domain_blob);
1037 DEBUG(3, ("Got challenge flags:\n"));
1038 debug_ntlmssp_flags(chal_flags);
1040 ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key);
1042 if (ntlmssp_state->unicode) {
1043 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1044 chal_parse_string = "CdUdbddB";
1046 chal_parse_string = "CdUdbdd";
1048 auth_gen_string = "CdBBUUUBd";
1050 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1051 chal_parse_string = "CdAdbddB";
1053 chal_parse_string = "CdAdbdd";
1056 auth_gen_string = "CdBBAAABd";
1059 DEBUG(3, ("NTLMSSP: Set final flags:\n"));
1060 debug_ntlmssp_flags(ntlmssp_state->neg_flags);
1062 if (!msrpc_parse(ntlmssp_state,
1063 &in, chal_parse_string,
1071 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
1072 dump_data(2, in.data, in.length);
1073 return NT_STATUS_INVALID_PARAMETER;
1076 ntlmssp_state->server_domain = server_domain;
1078 if (challenge_blob.length != 8) {
1079 return NT_STATUS_INVALID_PARAMETER;
1082 if (!ntlmssp_state->password) {
1083 static const uint8_t zeros[16];
1084 /* do nothing - blobs are zero length */
1086 /* session key is all zeros */
1087 session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1088 lm_session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1090 /* not doing NLTM2 without a password */
1091 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
1092 } else if (ntlmssp_state->use_ntlmv2) {
1094 if (!struct_blob.length) {
1095 /* be lazy, match win2k - we can't do NTLMv2 without it */
1096 DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
1097 return NT_STATUS_INVALID_PARAMETER;
1100 /* TODO: if the remote server is standalone, then we should replace 'domain'
1101 with the server name as supplied above */
1103 if (!SMBNTLMv2encrypt(ntlmssp_state->user,
1104 ntlmssp_state->domain,
1105 ntlmssp_state->password, &challenge_blob,
1107 &lm_response, &nt_response,
1108 NULL, &session_key)) {
1109 data_blob_free(&challenge_blob);
1110 data_blob_free(&struct_blob);
1111 return NT_STATUS_NO_MEMORY;
1114 /* LM Key is incompatible... */
1115 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1117 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
1118 struct MD5Context md5_session_nonce_ctx;
1119 uint8_t nt_hash[16];
1120 uint8_t session_nonce[16];
1121 uint8_t session_nonce_hash[16];
1122 uint8_t user_session_key[16];
1123 E_md4hash(ntlmssp_state->password, nt_hash);
1125 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1126 generate_random_buffer(lm_response.data, 8);
1127 memset(lm_response.data+8, 0, 16);
1129 memcpy(session_nonce, challenge_blob.data, 8);
1130 memcpy(&session_nonce[8], lm_response.data, 8);
1132 MD5Init(&md5_session_nonce_ctx);
1133 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
1134 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
1135 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
1137 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
1138 DEBUG(5, ("challenge is: \n"));
1139 dump_data(5, session_nonce_hash, 8);
1141 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1142 SMBNTencrypt(ntlmssp_state->password,
1146 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1148 SMBsesskeygen_ntv1(nt_hash, user_session_key);
1149 hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
1150 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
1152 /* LM Key is incompatible... */
1153 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1155 uint8_t nt_hash[16];
1157 if (ntlmssp_state->use_nt_response) {
1158 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1159 SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
1161 E_md4hash(ntlmssp_state->password, nt_hash);
1162 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1163 SMBsesskeygen_ntv1(nt_hash, session_key.data);
1164 dump_data_pw("NT session key:\n", session_key.data, session_key.length);
1167 /* lanman auth is insecure, it may be disabled */
1168 if (lp_client_lanman_auth()) {
1169 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1170 if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data,
1171 lm_response.data)) {
1172 /* If the LM password was too long (and therefore the LM hash being
1173 of the first 14 chars only), don't send it */
1174 data_blob_free(&lm_response);
1176 /* LM Key is incompatible with 'long' passwords */
1177 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1179 E_deshash(ntlmssp_state->password, lm_hash);
1180 lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1181 memcpy(lm_session_key.data, lm_hash, 8);
1182 memset(&lm_session_key.data[8], '\0', 8);
1184 if (!ntlmssp_state->use_nt_response) {
1185 session_key = lm_session_key;
1189 /* LM Key is incompatible... */
1190 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1194 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
1195 && lp_client_lanman_auth() && lm_session_key.length == 16) {
1196 DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1197 if (lm_response.length == 24) {
1198 SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data,
1199 new_session_key.data);
1201 static const uint8_t zeros[24];
1202 SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros,
1203 new_session_key.data);
1205 new_session_key.length = 16;
1206 session_key = new_session_key;
1207 dump_data_pw("LM session key\n", session_key.data, session_key.length);
1211 /* Key exchange encryptes a new client-generated session key with
1212 the password-derived key */
1213 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1214 /* Make up a new session key */
1215 uint8_t client_session_key[16];
1216 generate_random_buffer(client_session_key, sizeof(client_session_key));
1218 /* Encrypt the new session key with the old one */
1219 encrypted_session_key = data_blob_talloc(ntlmssp_state,
1220 client_session_key, sizeof(client_session_key));
1221 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
1222 arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
1223 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
1225 /* Mark the new session key as the 'real' session key */
1226 session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key));
1229 /* this generates the actual auth packet */
1230 if (!msrpc_gen(out_mem_ctx,
1231 out, auth_gen_string,
1234 lm_response.data, lm_response.length,
1235 nt_response.data, nt_response.length,
1236 ntlmssp_state->domain,
1237 ntlmssp_state->user,
1238 ntlmssp_state->get_global_myname(),
1239 encrypted_session_key.data, encrypted_session_key.length,
1240 ntlmssp_state->neg_flags)) {
1242 return NT_STATUS_NO_MEMORY;
1245 ntlmssp_state->session_key = session_key;
1247 /* The client might be using 56 or 40 bit weakened keys */
1248 ntlmssp_weaken_keys(ntlmssp_state);
1250 ntlmssp_state->chal = challenge_blob;
1251 ntlmssp_state->lm_resp = lm_response;
1252 ntlmssp_state->nt_resp = nt_response;
1254 ntlmssp_state->expected_state = NTLMSSP_DONE;
1256 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
1257 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
1258 nt_errstr(nt_status)));
1262 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1265 NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
1267 *ntlmssp_state = talloc_p(mem_ctx, struct ntlmssp_state);
1268 if (!*ntlmssp_state) {
1269 DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
1270 return NT_STATUS_NO_MEMORY;
1272 ZERO_STRUCTP(*ntlmssp_state);
1274 (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1276 (*ntlmssp_state)->get_global_myname = lp_netbios_name;
1277 (*ntlmssp_state)->get_domain = lp_workgroup;
1279 (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True);
1281 (*ntlmssp_state)->use_nt_response = lp_parm_bool(-1, "ntlmssp_client", "send_nt_reponse", True);
1283 (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
1284 && lp_parm_bool(-1, "ntlmssp_client", "allow_lm_key", False));
1286 (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1288 (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1290 (*ntlmssp_state)->ref_count = 1;
1292 (*ntlmssp_state)->neg_flags =
1293 NTLMSSP_NEGOTIATE_NTLM |
1294 NTLMSSP_REQUEST_TARGET;
1296 if (lp_parm_bool(-1, "ntlmssp_client", "128bit", True)) {
1297 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
1300 if (lp_parm_bool(-1, "ntlmssp_client", "keyexchange", True)) {
1301 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
1304 if (lp_parm_bool(-1, "ntlmssp_client", "ntlm2", True)) {
1305 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
1307 /* apparently we can't do ntlmv2 if we don't do ntlm2 */
1308 (*ntlmssp_state)->use_ntlmv2 = False;
1311 return NT_STATUS_OK;