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);
150 ntlmssp_state->user = NULL;
152 if (!ntlmssp_state->user) {
153 return NT_STATUS_NO_MEMORY;
159 * Set a password on an NTLMSSP context - ensures it is talloc()ed
162 NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password)
165 ntlmssp_state->password = NULL;
167 ntlmssp_state->password = talloc_strdup(ntlmssp_state, password);
168 if (!ntlmssp_state->password) {
169 return NT_STATUS_NO_MEMORY;
176 * Set a domain on an NTLMSSP context - ensures it is talloc()ed
179 NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain)
181 ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain);
182 if (!ntlmssp_state->domain) {
183 return NT_STATUS_NO_MEMORY;
189 * Set a workstation on an NTLMSSP context - ensures it is talloc()ed
192 NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation)
194 ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
195 if (!ntlmssp_state->domain) {
196 return NT_STATUS_NO_MEMORY;
202 * Store a DATA_BLOB containing an NTLMSSP response, for use later.
203 * This copies the data blob
206 NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state,
209 ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state,
210 response.data, response.length);
215 * Next state function for the NTLMSSP state machine
217 * @param ntlmssp_state NTLMSSP State
218 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
219 * @param in The request, as a DATA_BLOB
220 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
221 * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,
222 * or NT_STATUS_OK if the user is authenticated.
225 NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
226 TALLOC_CTX *out_mem_ctx,
227 const DATA_BLOB in, DATA_BLOB *out)
230 uint32_t ntlmssp_command;
233 *out = data_blob(NULL, 0);
235 if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
240 /* if the caller doesn't want to manage/own the memory,
241 we can put it on our context */
242 out_mem_ctx = ntlmssp_state;
245 if (!in.length && ntlmssp_state->stored_response.length) {
246 input = ntlmssp_state->stored_response;
248 /* we only want to read the stored response once - overwrite it */
249 ntlmssp_state->stored_response = data_blob(NULL, 0);
255 switch (ntlmssp_state->role) {
257 ntlmssp_command = NTLMSSP_INITIAL;
260 /* 'datagram' mode - no neg packet */
261 ntlmssp_command = NTLMSSP_NEGOTIATE;
265 if (!msrpc_parse(ntlmssp_state,
269 DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
270 dump_data(2, input.data, input.length);
271 return NT_STATUS_INVALID_PARAMETER;
275 if (ntlmssp_command != ntlmssp_state->expected_state) {
276 DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
277 return NT_STATUS_INVALID_PARAMETER;
280 for (i=0; ntlmssp_callbacks[i].fn; i++) {
281 if (ntlmssp_callbacks[i].role == ntlmssp_state->role
282 && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command
283 && ntlmssp_callbacks[i].fn) {
284 return ntlmssp_callbacks[i].fn(ntlmssp_state, out_mem_ctx, input, out);
288 DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n",
289 ntlmssp_state->role, ntlmssp_command));
291 return NT_STATUS_INVALID_PARAMETER;
295 * Return the NTLMSSP master session key
297 * @param ntlmssp_state NTLMSSP State
300 NTSTATUS ntlmssp_session_key(struct ntlmssp_state *ntlmssp_state,
301 DATA_BLOB *session_key)
303 if (!ntlmssp_state->session_key.data) {
304 return NT_STATUS_NO_USER_SESSION_KEY;
306 *session_key = ntlmssp_state->session_key;
312 * End an NTLMSSP state machine
314 * @param ntlmssp_state NTLMSSP State, free()ed by this function
317 void ntlmssp_end(struct ntlmssp_state **ntlmssp_state)
319 (*ntlmssp_state)->ref_count--;
321 if ((*ntlmssp_state)->ref_count == 0) {
322 talloc_free(*ntlmssp_state);
325 *ntlmssp_state = NULL;
330 * Determine correct target name flags for reply, given server role
331 * and negotiated flags
333 * @param ntlmssp_state NTLMSSP State
334 * @param neg_flags The flags from the packet
335 * @param chal_flags The flags to be set in the reply packet
336 * @return The 'target name' string.
339 static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
340 uint32_t neg_flags, uint32_t *chal_flags)
342 if (neg_flags & NTLMSSP_REQUEST_TARGET) {
343 *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
344 *chal_flags |= NTLMSSP_REQUEST_TARGET;
345 if (ntlmssp_state->server_role == ROLE_STANDALONE) {
346 *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
347 return ntlmssp_state->get_global_myname();
349 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
350 return ntlmssp_state->get_domain();
357 static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
358 uint32_t neg_flags, BOOL allow_lm) {
359 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
360 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
361 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
362 ntlmssp_state->unicode = True;
364 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
365 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
366 ntlmssp_state->unicode = False;
369 if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !ntlmssp_state->use_ntlmv2) {
370 /* other end forcing us to use LM */
371 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
372 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
374 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
377 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) {
378 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
381 if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
382 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
385 if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
386 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
389 if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
390 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
393 if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
394 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
395 if (neg_flags & NTLMSSP_NEGOTIATE_56) {
396 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
400 if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
401 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
404 if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
405 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
408 if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
409 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
415 Weaken NTLMSSP keys to cope with down-level clients and servers.
417 We probably should have some parameters to control this, but as
418 it only occours for LM_KEY connections, and this is controlled
419 by the client lanman auth/lanman auth parameters, it isn't too bad.
422 static void ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state) {
423 /* Key weakening not performed on the master key for NTLM2
424 and does not occour for NTLM1. Therefore we only need
425 to do this for the LM_KEY.
428 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
429 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
431 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
432 ntlmssp_state->session_key.data[7] = 0xa0;
433 } else { /* forty bits */
434 ntlmssp_state->session_key.data[5] = 0xe5;
435 ntlmssp_state->session_key.data[6] = 0x38;
436 ntlmssp_state->session_key.data[7] = 0xb0;
438 ntlmssp_state->session_key.length = 8;
443 * Next state function for the Negotiate packet
445 * @param ntlmssp_state NTLMSSP State
446 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
447 * @param in The request, as a DATA_BLOB
448 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
449 * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent.
452 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
453 TALLOC_CTX *out_mem_ctx,
454 const DATA_BLOB in, DATA_BLOB *out)
456 DATA_BLOB struct_blob;
457 fstring dnsname, dnsdomname;
458 uint32_t neg_flags = 0;
459 uint32_t ntlmssp_command, chal_flags;
460 char *cliname=NULL, *domname=NULL;
461 const uint8_t *cryptkey;
462 const char *target_name;
464 /* parse the NTLMSSP packet */
466 file_save("ntlmssp_negotiate.dat", request.data, request.length);
470 if (!msrpc_parse(ntlmssp_state,
477 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
478 dump_data(2, in.data, in.length);
479 return NT_STATUS_INVALID_PARAMETER;
482 debug_ntlmssp_flags(neg_flags);
485 ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key);
487 /* Ask our caller what challenge they would like in the packet */
488 cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
490 /* Check if we may set the challenge */
491 if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
492 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
495 /* The flags we send back are not just the negotiated flags,
496 * they are also 'what is in this packet'. Therfore, we
497 * operate on 'chal_flags' from here on
500 chal_flags = ntlmssp_state->neg_flags;
502 /* get the right name to fill in as 'target' */
503 target_name = ntlmssp_target_name(ntlmssp_state,
504 neg_flags, &chal_flags);
505 if (target_name == NULL)
506 return NT_STATUS_INVALID_PARAMETER;
508 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
509 ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
511 /* This should be a 'netbios domain -> DNS domain' mapping */
512 dnsdomname[0] = '\0';
513 get_mydomname(dnsdomname);
514 strlower_m(dnsdomname);
517 get_myfullname(dnsname);
519 /* This creates the 'blob' of names that appears at the end of the packet */
520 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO)
522 const char *target_name_dns = "";
523 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
524 target_name_dns = dnsdomname;
525 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
526 target_name_dns = dnsname;
529 msrpc_gen(out_mem_ctx,
530 &struct_blob, "aaaaa",
531 NTLMSSP_NAME_TYPE_DOMAIN, target_name,
532 NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
533 NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
534 NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
537 struct_blob = data_blob(NULL, 0);
541 /* Marshel the packet in the right format, be it unicode or ASCII */
542 const char *gen_string;
543 if (ntlmssp_state->unicode) {
544 gen_string = "CdUdbddB";
546 gen_string = "CdAdbddB";
549 msrpc_gen(out_mem_ctx,
557 struct_blob.data, struct_blob.length);
560 ntlmssp_state->expected_state = NTLMSSP_AUTH;
562 return NT_STATUS_MORE_PROCESSING_REQUIRED;
566 * Next state function for the Authenticate packet
568 * @param ntlmssp_state NTLMSSP State
569 * @param request The request, as a DATA_BLOB
570 * @return Errors or NT_STATUS_OK.
573 static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state,
574 const DATA_BLOB request)
576 uint32_t ntlmssp_command, auth_flags;
579 uint8_t session_nonce_hash[16];
581 const char *parse_string;
584 char *workstation = NULL;
587 file_save("ntlmssp_auth.dat", request.data, request.length);
590 if (ntlmssp_state->unicode) {
591 parse_string = "CdBBUUUBd";
593 parse_string = "CdBBAAABd";
597 data_blob_free(&ntlmssp_state->lm_resp);
598 data_blob_free(&ntlmssp_state->nt_resp);
600 ntlmssp_state->user = NULL;
601 ntlmssp_state->domain = NULL;
602 ntlmssp_state->workstation = NULL;
604 /* now the NTLMSSP encoded auth hashes */
605 if (!msrpc_parse(ntlmssp_state,
606 &request, parse_string,
609 &ntlmssp_state->lm_resp,
610 &ntlmssp_state->nt_resp,
614 &ntlmssp_state->encrypted_session_key,
616 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
617 dump_data(10, request.data, request.length);
620 data_blob_free(&ntlmssp_state->encrypted_session_key);
623 /* Try again with a shorter string (Win9X truncates this packet) */
624 if (ntlmssp_state->unicode) {
625 parse_string = "CdBBUUU";
627 parse_string = "CdBBAAA";
630 /* now the NTLMSSP encoded auth hashes */
631 if (!msrpc_parse(ntlmssp_state,
632 &request, parse_string,
635 &ntlmssp_state->lm_resp,
636 &ntlmssp_state->nt_resp,
640 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
641 dump_data(2, request.data, request.length);
643 return NT_STATUS_INVALID_PARAMETER;
648 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key);
650 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
652 data_blob_free(&ntlmssp_state->encrypted_session_key);
656 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
658 data_blob_free(&ntlmssp_state->encrypted_session_key);
662 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
664 data_blob_free(&ntlmssp_state->encrypted_session_key);
668 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
669 ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
672 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);
673 file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length);
676 /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
679 However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
681 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
682 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
683 struct MD5Context md5_session_nonce_ctx;
684 SMB_ASSERT(ntlmssp_state->internal_chal.data
685 && ntlmssp_state->internal_chal.length == 8);
687 ntlmssp_state->doing_ntlm2 = True;
689 memcpy(ntlmssp_state->session_nonce, ntlmssp_state->internal_chal.data, 8);
690 memcpy(&ntlmssp_state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
692 MD5Init(&md5_session_nonce_ctx);
693 MD5Update(&md5_session_nonce_ctx, ntlmssp_state->session_nonce, 16);
694 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
696 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state,
697 session_nonce_hash, 8);
699 /* LM response is no longer useful, zero it out */
700 data_blob_free(&ntlmssp_state->lm_resp);
702 /* We changed the effective challenge - set it */
703 if (!NT_STATUS_IS_OK(nt_status =
704 ntlmssp_state->set_challenge(ntlmssp_state,
705 &ntlmssp_state->chal))) {
707 data_blob_free(&ntlmssp_state->encrypted_session_key);
711 /* LM Key is incompatible... */
712 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
719 * Next state function for the Authenticate packet
720 * (after authentication - figures out the session keys etc)
722 * @param ntlmssp_state NTLMSSP State
723 * @return Errors or NT_STATUS_OK.
726 static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
727 DATA_BLOB *user_session_key,
728 DATA_BLOB *lm_session_key)
731 DATA_BLOB session_key = data_blob(NULL, 0);
733 if (user_session_key)
734 dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length);
737 dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length);
739 /* Handle the different session key derivation for NTLM2 */
740 if (ntlmssp_state->doing_ntlm2) {
741 if (user_session_key && user_session_key->data && user_session_key->length == 16) {
742 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
743 hmac_md5(user_session_key->data, ntlmssp_state->session_nonce,
744 sizeof(ntlmssp_state->session_nonce), session_key.data);
745 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
746 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
749 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
750 session_key = data_blob(NULL, 0);
752 } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
753 /* Ensure we can never get here on NTLMv2 */
754 && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
756 if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
757 if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
758 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
759 SMBsesskeygen_lm_sess_key(lm_session_key->data, ntlmssp_state->lm_resp.data,
761 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
762 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
765 /* When there is no LM response, just use zeros */
766 static const uint8_t zeros[24];
767 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
768 SMBsesskeygen_lm_sess_key(zeros, zeros,
770 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
771 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
774 /* LM Key not selected */
775 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
777 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
778 session_key = data_blob(NULL, 0);
781 } else if (user_session_key && user_session_key->data) {
782 session_key = *user_session_key;
783 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
784 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
786 /* LM Key not selected */
787 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
789 } else if (lm_session_key && lm_session_key->data) {
790 /* Very weird to have LM key, but no user session key, but anyway.. */
791 session_key = *lm_session_key;
792 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
793 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
795 /* LM Key not selected */
796 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
799 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
800 session_key = data_blob(NULL, 0);
802 /* LM Key not selected */
803 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
806 /* With KEY_EXCH, the client supplies the proposed session key,
807 but encrypts it with the long-term key */
808 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
809 if (!ntlmssp_state->encrypted_session_key.data
810 || ntlmssp_state->encrypted_session_key.length != 16) {
811 data_blob_free(&ntlmssp_state->encrypted_session_key);
812 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
813 ntlmssp_state->encrypted_session_key.length));
814 return NT_STATUS_INVALID_PARAMETER;
815 } else if (!session_key.data || session_key.length != 16) {
816 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
817 session_key.length));
818 ntlmssp_state->session_key = session_key;
820 dump_data_pw("KEY_EXCH session key (enc):\n",
821 ntlmssp_state->encrypted_session_key.data,
822 ntlmssp_state->encrypted_session_key.length);
823 arcfour_crypt(ntlmssp_state->encrypted_session_key.data,
825 ntlmssp_state->encrypted_session_key.length);
826 ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
827 ntlmssp_state->encrypted_session_key.data,
828 ntlmssp_state->encrypted_session_key.length);
829 dump_data_pw("KEY_EXCH session key:\n", ntlmssp_state->encrypted_session_key.data,
830 ntlmssp_state->encrypted_session_key.length);
833 ntlmssp_state->session_key = session_key;
836 /* The server might need us to use a partial-strength session key */
837 ntlmssp_weaken_keys(ntlmssp_state);
839 nt_status = ntlmssp_sign_init(ntlmssp_state);
841 data_blob_free(&ntlmssp_state->encrypted_session_key);
843 /* allow arbitarily many authentications, but watch that this will cause a
844 memory leak, until the ntlmssp_state is shutdown
847 if (ntlmssp_state->server_multiple_authentications) {
848 ntlmssp_state->expected_state = NTLMSSP_AUTH;
850 ntlmssp_state->expected_state = NTLMSSP_DONE;
858 * Next state function for the Authenticate packet
860 * @param ntlmssp_state NTLMSSP State
861 * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
862 * @param out The reply, as an allocated DATA_BLOB, caller to free.
863 * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK.
866 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
867 TALLOC_CTX *out_mem_ctx,
868 const DATA_BLOB in, DATA_BLOB *out)
870 DATA_BLOB user_session_key = data_blob(NULL, 0);
871 DATA_BLOB lm_session_key = data_blob(NULL, 0);
874 /* zero the outbound NTLMSSP packet */
875 *out = data_blob_talloc(out_mem_ctx, NULL, 0);
877 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(ntlmssp_state, in))) {
882 * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
883 * is required (by "ntlm auth = no" and "lm auth = no" being set in the
884 * smb.conf file) and no NTLMv2 response was sent then the password check
885 * will fail here. JRA.
888 /* Finally, actually ask if the password is OK */
890 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state,
891 &user_session_key, &lm_session_key))) {
895 if (ntlmssp_state->server_use_session_keys) {
896 return ntlmssp_server_postauth(ntlmssp_state, &user_session_key, &lm_session_key);
898 ntlmssp_state->session_key = data_blob(NULL, 0);
904 * Create an NTLMSSP state machine
906 * @param ntlmssp_state NTLMSSP State, allocated by this function
909 NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
911 *ntlmssp_state = talloc_p(mem_ctx, struct ntlmssp_state);
912 if (!*ntlmssp_state) {
913 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
914 return NT_STATUS_NO_MEMORY;
916 ZERO_STRUCTP(*ntlmssp_state);
918 (*ntlmssp_state)->role = NTLMSSP_SERVER;
920 (*ntlmssp_state)->get_challenge = get_challenge;
921 (*ntlmssp_state)->set_challenge = set_challenge;
922 (*ntlmssp_state)->may_set_challenge = may_set_challenge;
924 (*ntlmssp_state)->get_global_myname = lp_netbios_name;
925 (*ntlmssp_state)->get_domain = lp_workgroup;
926 (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
928 (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
930 (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
931 && lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False));
933 (*ntlmssp_state)->server_use_session_keys = True;
934 (*ntlmssp_state)->server_multiple_authentications = False;
936 (*ntlmssp_state)->ref_count = 1;
938 (*ntlmssp_state)->neg_flags =
939 NTLMSSP_NEGOTIATE_NTLM;
941 if (lp_parm_bool(-1, "ntlmssp_server", "128bit", True)) {
942 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
945 if (lp_parm_bool(-1, "ntlmssp_server", "keyexchange", True)) {
946 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
949 if (lp_parm_bool(-1, "ntlmssp_server", "ntlm2", True)) {
950 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
956 /*********************************************************************
958 *********************************************************************/
961 * Next state function for the Initial packet
963 * @param ntlmssp_state NTLMSSP State
964 * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context
965 * @param in The request, as a DATA_BLOB. reply.data must be NULL
966 * @param out The reply, as an talloc()ed DATA_BLOB, on out_mem_ctx
967 * @return Errors or NT_STATUS_OK.
970 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
971 TALLOC_CTX *out_mem_ctx,
972 DATA_BLOB in, DATA_BLOB *out)
974 if (ntlmssp_state->unicode) {
975 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
977 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
980 if (ntlmssp_state->use_ntlmv2) {
981 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
984 /* generate the ntlmssp negotiate packet */
985 msrpc_gen(out_mem_ctx,
989 ntlmssp_state->neg_flags,
990 ntlmssp_state->get_domain(),
991 ntlmssp_state->get_global_myname());
993 ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
995 return NT_STATUS_MORE_PROCESSING_REQUIRED;
999 * Next state function for the Challenge Packet. Generate an auth packet.
1001 * @param ntlmssp_state NTLMSSP State
1002 * @param request The request, as a DATA_BLOB. reply.data must be NULL
1003 * @param request The reply, as an allocated DATA_BLOB, caller to free.
1004 * @return Errors or NT_STATUS_OK.
1007 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
1008 TALLOC_CTX *out_mem_ctx,
1009 const DATA_BLOB in, DATA_BLOB *out)
1011 uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
1012 DATA_BLOB server_domain_blob;
1013 DATA_BLOB challenge_blob;
1014 DATA_BLOB struct_blob = data_blob(NULL, 0);
1015 char *server_domain;
1016 const char *chal_parse_string;
1017 const char *auth_gen_string;
1018 uint8_t lm_hash[16];
1019 DATA_BLOB lm_response = data_blob(NULL, 0);
1020 DATA_BLOB nt_response = data_blob(NULL, 0);
1021 DATA_BLOB session_key = data_blob(NULL, 0);
1022 DATA_BLOB lm_session_key = data_blob(NULL, 0);
1023 DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
1026 if (!msrpc_parse(ntlmssp_state,
1030 &server_domain_blob,
1032 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
1033 dump_data(2, in.data, in.length);
1035 return NT_STATUS_INVALID_PARAMETER;
1038 data_blob_free(&server_domain_blob);
1040 DEBUG(3, ("Got challenge flags:\n"));
1041 debug_ntlmssp_flags(chal_flags);
1043 ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key);
1045 if (ntlmssp_state->unicode) {
1046 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1047 chal_parse_string = "CdUdbddB";
1049 chal_parse_string = "CdUdbdd";
1051 auth_gen_string = "CdBBUUUBd";
1053 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1054 chal_parse_string = "CdAdbddB";
1056 chal_parse_string = "CdAdbdd";
1059 auth_gen_string = "CdBBAAABd";
1062 DEBUG(3, ("NTLMSSP: Set final flags:\n"));
1063 debug_ntlmssp_flags(ntlmssp_state->neg_flags);
1065 if (!msrpc_parse(ntlmssp_state,
1066 &in, chal_parse_string,
1074 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
1075 dump_data(2, in.data, in.length);
1076 return NT_STATUS_INVALID_PARAMETER;
1079 ntlmssp_state->server_domain = server_domain;
1081 if (challenge_blob.length != 8) {
1082 return NT_STATUS_INVALID_PARAMETER;
1085 if (!ntlmssp_state->password) {
1086 static const uint8_t zeros[16];
1087 /* do nothing - blobs are zero length */
1089 /* session key is all zeros */
1090 session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1091 lm_session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1093 /* not doing NLTM2 without a password */
1094 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
1095 } else if (ntlmssp_state->use_ntlmv2) {
1097 if (!struct_blob.length) {
1098 /* be lazy, match win2k - we can't do NTLMv2 without it */
1099 DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
1100 return NT_STATUS_INVALID_PARAMETER;
1103 /* TODO: if the remote server is standalone, then we should replace 'domain'
1104 with the server name as supplied above */
1106 if (!SMBNTLMv2encrypt(ntlmssp_state->user,
1107 ntlmssp_state->domain,
1108 ntlmssp_state->password, &challenge_blob,
1110 &lm_response, &nt_response,
1111 NULL, &session_key)) {
1112 data_blob_free(&challenge_blob);
1113 data_blob_free(&struct_blob);
1114 return NT_STATUS_NO_MEMORY;
1117 /* LM Key is incompatible... */
1118 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1120 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
1121 struct MD5Context md5_session_nonce_ctx;
1122 uint8_t nt_hash[16];
1123 uint8_t session_nonce[16];
1124 uint8_t session_nonce_hash[16];
1125 uint8_t user_session_key[16];
1126 E_md4hash(ntlmssp_state->password, nt_hash);
1128 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1129 generate_random_buffer(lm_response.data, 8);
1130 memset(lm_response.data+8, 0, 16);
1132 memcpy(session_nonce, challenge_blob.data, 8);
1133 memcpy(&session_nonce[8], lm_response.data, 8);
1135 MD5Init(&md5_session_nonce_ctx);
1136 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
1137 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
1138 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
1140 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
1141 DEBUG(5, ("challenge is: \n"));
1142 dump_data(5, session_nonce_hash, 8);
1144 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1145 SMBNTencrypt(ntlmssp_state->password,
1149 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1151 SMBsesskeygen_ntv1(nt_hash, user_session_key);
1152 hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
1153 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
1155 /* LM Key is incompatible... */
1156 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1158 uint8_t nt_hash[16];
1160 if (ntlmssp_state->use_nt_response) {
1161 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1162 SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
1164 E_md4hash(ntlmssp_state->password, nt_hash);
1165 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1166 SMBsesskeygen_ntv1(nt_hash, session_key.data);
1167 dump_data_pw("NT session key:\n", session_key.data, session_key.length);
1170 /* lanman auth is insecure, it may be disabled */
1171 if (lp_client_lanman_auth()) {
1172 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1173 if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data,
1174 lm_response.data)) {
1175 /* If the LM password was too long (and therefore the LM hash being
1176 of the first 14 chars only), don't send it */
1177 data_blob_free(&lm_response);
1179 /* LM Key is incompatible with 'long' passwords */
1180 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1182 E_deshash(ntlmssp_state->password, lm_hash);
1183 lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1184 memcpy(lm_session_key.data, lm_hash, 8);
1185 memset(&lm_session_key.data[8], '\0', 8);
1187 if (!ntlmssp_state->use_nt_response) {
1188 session_key = lm_session_key;
1192 /* LM Key is incompatible... */
1193 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1197 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
1198 && lp_client_lanman_auth() && lm_session_key.length == 16) {
1199 DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1200 if (lm_response.length == 24) {
1201 SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data,
1202 new_session_key.data);
1204 static const uint8_t zeros[24];
1205 SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros,
1206 new_session_key.data);
1208 new_session_key.length = 16;
1209 session_key = new_session_key;
1210 dump_data_pw("LM session key\n", session_key.data, session_key.length);
1214 /* Key exchange encryptes a new client-generated session key with
1215 the password-derived key */
1216 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1217 /* Make up a new session key */
1218 uint8_t client_session_key[16];
1219 generate_random_buffer(client_session_key, sizeof(client_session_key));
1221 /* Encrypt the new session key with the old one */
1222 encrypted_session_key = data_blob_talloc(ntlmssp_state,
1223 client_session_key, sizeof(client_session_key));
1224 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
1225 arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
1226 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
1228 /* Mark the new session key as the 'real' session key */
1229 session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key));
1232 /* this generates the actual auth packet */
1233 if (!msrpc_gen(out_mem_ctx,
1234 out, auth_gen_string,
1237 lm_response.data, lm_response.length,
1238 nt_response.data, nt_response.length,
1239 ntlmssp_state->domain,
1240 ntlmssp_state->user,
1241 ntlmssp_state->get_global_myname(),
1242 encrypted_session_key.data, encrypted_session_key.length,
1243 ntlmssp_state->neg_flags)) {
1245 return NT_STATUS_NO_MEMORY;
1248 ntlmssp_state->session_key = session_key;
1250 /* The client might be using 56 or 40 bit weakened keys */
1251 ntlmssp_weaken_keys(ntlmssp_state);
1253 ntlmssp_state->chal = challenge_blob;
1254 ntlmssp_state->lm_resp = lm_response;
1255 ntlmssp_state->nt_resp = nt_response;
1257 ntlmssp_state->expected_state = NTLMSSP_DONE;
1259 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
1260 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
1261 nt_errstr(nt_status)));
1265 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1268 NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
1270 *ntlmssp_state = talloc_p(mem_ctx, struct ntlmssp_state);
1271 if (!*ntlmssp_state) {
1272 DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
1273 return NT_STATUS_NO_MEMORY;
1275 ZERO_STRUCTP(*ntlmssp_state);
1277 (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1279 (*ntlmssp_state)->get_global_myname = lp_netbios_name;
1280 (*ntlmssp_state)->get_domain = lp_workgroup;
1282 (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True);
1284 (*ntlmssp_state)->use_nt_response = lp_parm_bool(-1, "ntlmssp_client", "send_nt_reponse", True);
1286 (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
1287 && lp_parm_bool(-1, "ntlmssp_client", "allow_lm_key", False));
1289 (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1291 (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1293 (*ntlmssp_state)->ref_count = 1;
1295 (*ntlmssp_state)->neg_flags =
1296 NTLMSSP_NEGOTIATE_NTLM |
1297 NTLMSSP_REQUEST_TARGET;
1299 if (lp_parm_bool(-1, "ntlmssp_client", "128bit", True)) {
1300 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
1303 if (lp_parm_bool(-1, "ntlmssp_client", "keyexchange", True)) {
1304 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
1307 if (lp_parm_bool(-1, "ntlmssp_client", "ntlm2", True)) {
1308 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
1310 /* apparently we can't do ntlmv2 if we don't do ntlm2 */
1311 (*ntlmssp_state)->use_ntlmv2 = False;
1314 return NT_STATUS_OK;