2 Unix SMB/Netbios implementation.
4 handle NLTMSSP, client server side parsing
6 Copyright (C) Andrew Tridgell 2001
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "auth/auth.h"
26 #include "lib/crypto/crypto.h"
29 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
30 TALLOC_CTX *out_mem_ctx,
31 DATA_BLOB in, DATA_BLOB *out);
32 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
33 TALLOC_CTX *out_mem_ctx,
34 const DATA_BLOB in, DATA_BLOB *out);
35 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
36 TALLOC_CTX *out_mem_ctx,
37 const DATA_BLOB in, DATA_BLOB *out);
38 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
39 TALLOC_CTX *out_mem_ctx,
40 const DATA_BLOB in, DATA_BLOB *out);
43 * Callbacks for NTLMSSP - for both client and server operating modes
47 static const struct ntlmssp_callbacks {
48 enum ntlmssp_role role;
49 enum ntlmssp_message_type ntlmssp_command;
50 NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state,
51 TALLOC_CTX *out_mem_ctx,
52 DATA_BLOB in, DATA_BLOB *out);
53 } ntlmssp_callbacks[] = {
54 {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},
55 {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},
56 {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},
57 {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},
58 {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
59 {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
64 * Print out the NTLMSSP flags for debugging
65 * @param neg_flags The flags from the packet
68 void debug_ntlmssp_flags(uint32_t neg_flags)
70 DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
72 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)
73 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n"));
74 if (neg_flags & NTLMSSP_NEGOTIATE_OEM)
75 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n"));
76 if (neg_flags & NTLMSSP_REQUEST_TARGET)
77 DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n"));
78 if (neg_flags & NTLMSSP_NEGOTIATE_SIGN)
79 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n"));
80 if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)
81 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n"));
82 if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
83 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n"));
84 if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)
85 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n"));
86 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM)
87 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n"));
88 if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED)
89 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n"));
90 if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED)
91 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n"));
92 if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL)
93 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
94 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
95 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
96 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
97 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n"));
98 if (neg_flags & NTLMSSP_CHAL_TARGET_INFO)
99 DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n"));
100 if (neg_flags & NTLMSSP_NEGOTIATE_128)
101 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n"));
102 if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
103 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
107 * Default challenge generation code.
111 static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state)
113 uint8_t *chal = talloc_size(ntlmssp_state, 8);
114 generate_random_buffer(chal, 8);
120 * Default 'we can set the challenge to anything we like' implementation
124 static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
130 * Default 'we can set the challenge to anything we like' implementation
132 * Does not actually do anything, as the value is always in the structure anyway.
136 static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
138 SMB_ASSERT(challenge->length == 8);
143 * Set a username on an NTLMSSP context - ensures it is talloc()ed
147 NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user)
150 /* it should be at least "" */
151 DEBUG(1, ("NTLMSSP failed to set username - cannot accept NULL username\n"));
152 return NT_STATUS_INVALID_PARAMETER;
154 ntlmssp_state->user = talloc_strdup(ntlmssp_state, user);
155 if (!ntlmssp_state->user) {
156 return NT_STATUS_NO_MEMORY;
162 * Set a password on an NTLMSSP context - ensures it is talloc()ed
165 NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password)
168 ntlmssp_state->password = NULL;
170 ntlmssp_state->password = talloc_strdup(ntlmssp_state, password);
171 if (!ntlmssp_state->password) {
172 return NT_STATUS_NO_MEMORY;
179 * Set a domain on an NTLMSSP context - ensures it is talloc()ed
182 NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain)
184 ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain);
185 if (!ntlmssp_state->domain) {
186 return NT_STATUS_NO_MEMORY;
192 * Set a workstation on an NTLMSSP context - ensures it is talloc()ed
195 NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation)
197 ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
198 if (!ntlmssp_state->workstation) {
199 return NT_STATUS_NO_MEMORY;
205 * Store a DATA_BLOB containing an NTLMSSP response, for use later.
206 * This copies the data blob
209 NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state,
212 ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state,
213 response.data, response.length);
218 * Next state function for the NTLMSSP state machine
220 * @param ntlmssp_state NTLMSSP State
221 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
222 * @param in The request, as a DATA_BLOB
223 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
224 * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,
225 * or NT_STATUS_OK if the user is authenticated.
228 NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
229 TALLOC_CTX *out_mem_ctx,
230 const DATA_BLOB in, DATA_BLOB *out)
233 uint32_t ntlmssp_command;
236 *out = data_blob(NULL, 0);
238 if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
243 /* if the caller doesn't want to manage/own the memory,
244 we can put it on our context */
245 out_mem_ctx = ntlmssp_state;
248 if (!in.length && ntlmssp_state->stored_response.length) {
249 input = ntlmssp_state->stored_response;
251 /* we only want to read the stored response once - overwrite it */
252 ntlmssp_state->stored_response = data_blob(NULL, 0);
258 switch (ntlmssp_state->role) {
260 ntlmssp_command = NTLMSSP_INITIAL;
263 /* 'datagram' mode - no neg packet */
264 ntlmssp_command = NTLMSSP_NEGOTIATE;
268 if (!msrpc_parse(ntlmssp_state,
272 DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
273 dump_data(2, input.data, input.length);
274 return NT_STATUS_INVALID_PARAMETER;
278 if (ntlmssp_command != ntlmssp_state->expected_state) {
279 DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
280 return NT_STATUS_INVALID_PARAMETER;
283 for (i=0; ntlmssp_callbacks[i].fn; i++) {
284 if (ntlmssp_callbacks[i].role == ntlmssp_state->role
285 && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command
286 && ntlmssp_callbacks[i].fn) {
287 return ntlmssp_callbacks[i].fn(ntlmssp_state, out_mem_ctx, input, out);
291 DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n",
292 ntlmssp_state->role, ntlmssp_command));
294 return NT_STATUS_INVALID_PARAMETER;
298 * Return the NTLMSSP master session key
300 * @param ntlmssp_state NTLMSSP State
303 NTSTATUS ntlmssp_session_key(struct ntlmssp_state *ntlmssp_state,
304 DATA_BLOB *session_key)
306 if (!ntlmssp_state->session_key.data) {
307 return NT_STATUS_NO_USER_SESSION_KEY;
309 *session_key = ntlmssp_state->session_key;
315 * End an NTLMSSP state machine
317 * @param ntlmssp_state NTLMSSP State, free()ed by this function
320 void ntlmssp_end(struct ntlmssp_state **ntlmssp_state)
322 (*ntlmssp_state)->ref_count--;
324 if ((*ntlmssp_state)->ref_count == 0) {
325 talloc_free(*ntlmssp_state);
328 *ntlmssp_state = NULL;
333 * Determine correct target name flags for reply, given server role
334 * and negotiated flags
336 * @param ntlmssp_state NTLMSSP State
337 * @param neg_flags The flags from the packet
338 * @param chal_flags The flags to be set in the reply packet
339 * @return The 'target name' string.
342 static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
343 uint32_t neg_flags, uint32_t *chal_flags)
345 if (neg_flags & NTLMSSP_REQUEST_TARGET) {
346 *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
347 *chal_flags |= NTLMSSP_REQUEST_TARGET;
348 if (ntlmssp_state->server_role == ROLE_STANDALONE) {
349 *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
350 return ntlmssp_state->server_name;
352 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
353 return ntlmssp_state->get_domain();
360 static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
361 uint32_t neg_flags, BOOL allow_lm) {
362 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
363 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
364 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
365 ntlmssp_state->unicode = True;
367 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
368 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
369 ntlmssp_state->unicode = False;
372 if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !ntlmssp_state->use_ntlmv2) {
373 /* other end forcing us to use LM */
374 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
375 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
377 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
380 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) {
381 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
384 if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
385 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
388 if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
389 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
392 if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
393 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
396 if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
397 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
398 if (neg_flags & NTLMSSP_NEGOTIATE_56) {
399 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
403 if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
404 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
407 if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
408 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
411 if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
412 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
418 Weaken NTLMSSP keys to cope with down-level clients and servers.
420 We probably should have some parameters to control this, but as
421 it only occours for LM_KEY connections, and this is controlled
422 by the client lanman auth/lanman auth parameters, it isn't too bad.
425 static void ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state) {
426 /* Key weakening not performed on the master key for NTLM2
427 and does not occour for NTLM1. Therefore we only need
428 to do this for the LM_KEY.
431 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
432 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
434 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
435 ntlmssp_state->session_key.data[7] = 0xa0;
436 } else { /* forty bits */
437 ntlmssp_state->session_key.data[5] = 0xe5;
438 ntlmssp_state->session_key.data[6] = 0x38;
439 ntlmssp_state->session_key.data[7] = 0xb0;
441 ntlmssp_state->session_key.length = 8;
446 * Next state function for the Negotiate packet
448 * @param ntlmssp_state NTLMSSP State
449 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
450 * @param in The request, as a DATA_BLOB
451 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
452 * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent.
455 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
456 TALLOC_CTX *out_mem_ctx,
457 const DATA_BLOB in, DATA_BLOB *out)
459 DATA_BLOB struct_blob;
460 fstring dnsname, dnsdomname;
461 uint32_t neg_flags = 0;
462 uint32_t ntlmssp_command, chal_flags;
463 char *cliname=NULL, *domname=NULL;
464 const uint8_t *cryptkey;
465 const char *target_name;
467 /* parse the NTLMSSP packet */
469 file_save("ntlmssp_negotiate.dat", request.data, request.length);
473 if (!msrpc_parse(ntlmssp_state,
480 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
481 dump_data(2, in.data, in.length);
482 return NT_STATUS_INVALID_PARAMETER;
485 debug_ntlmssp_flags(neg_flags);
488 ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key);
490 /* Ask our caller what challenge they would like in the packet */
491 cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
493 /* Check if we may set the challenge */
494 if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
495 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
498 /* The flags we send back are not just the negotiated flags,
499 * they are also 'what is in this packet'. Therfore, we
500 * operate on 'chal_flags' from here on
503 chal_flags = ntlmssp_state->neg_flags;
505 /* get the right name to fill in as 'target' */
506 target_name = ntlmssp_target_name(ntlmssp_state,
507 neg_flags, &chal_flags);
508 if (target_name == NULL)
509 return NT_STATUS_INVALID_PARAMETER;
511 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
512 ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
514 /* This should be a 'netbios domain -> DNS domain' mapping */
515 dnsdomname[0] = '\0';
516 get_mydomname(dnsdomname);
517 strlower_m(dnsdomname);
520 get_myfullname(dnsname);
522 /* This creates the 'blob' of names that appears at the end of the packet */
523 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO)
525 const char *target_name_dns = "";
526 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
527 target_name_dns = dnsdomname;
528 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
529 target_name_dns = dnsname;
532 msrpc_gen(out_mem_ctx,
533 &struct_blob, "aaaaa",
534 NTLMSSP_NAME_TYPE_DOMAIN, target_name,
535 NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->server_name,
536 NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
537 NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
540 struct_blob = data_blob(NULL, 0);
544 /* Marshel the packet in the right format, be it unicode or ASCII */
545 const char *gen_string;
546 if (ntlmssp_state->unicode) {
547 gen_string = "CdUdbddB";
549 gen_string = "CdAdbddB";
552 msrpc_gen(out_mem_ctx,
560 struct_blob.data, struct_blob.length);
563 ntlmssp_state->expected_state = NTLMSSP_AUTH;
565 return NT_STATUS_MORE_PROCESSING_REQUIRED;
569 * Next state function for the Authenticate packet
571 * @param ntlmssp_state NTLMSSP State
572 * @param request The request, as a DATA_BLOB
573 * @return Errors or NT_STATUS_OK.
576 static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state,
577 const DATA_BLOB request)
579 uint32_t ntlmssp_command, auth_flags;
582 uint8_t session_nonce_hash[16];
584 const char *parse_string;
587 char *workstation = NULL;
590 file_save("ntlmssp_auth.dat", request.data, request.length);
593 if (ntlmssp_state->unicode) {
594 parse_string = "CdBBUUUBd";
596 parse_string = "CdBBAAABd";
600 data_blob_free(&ntlmssp_state->lm_resp);
601 data_blob_free(&ntlmssp_state->nt_resp);
603 ntlmssp_state->user = NULL;
604 ntlmssp_state->domain = NULL;
605 ntlmssp_state->workstation = NULL;
607 /* now the NTLMSSP encoded auth hashes */
608 if (!msrpc_parse(ntlmssp_state,
609 &request, parse_string,
612 &ntlmssp_state->lm_resp,
613 &ntlmssp_state->nt_resp,
617 &ntlmssp_state->encrypted_session_key,
619 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
620 dump_data(10, request.data, request.length);
623 data_blob_free(&ntlmssp_state->encrypted_session_key);
626 /* Try again with a shorter string (Win9X truncates this packet) */
627 if (ntlmssp_state->unicode) {
628 parse_string = "CdBBUUU";
630 parse_string = "CdBBAAA";
633 /* now the NTLMSSP encoded auth hashes */
634 if (!msrpc_parse(ntlmssp_state,
635 &request, parse_string,
638 &ntlmssp_state->lm_resp,
639 &ntlmssp_state->nt_resp,
643 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
644 dump_data(2, request.data, request.length);
646 return NT_STATUS_INVALID_PARAMETER;
651 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key);
653 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
655 data_blob_free(&ntlmssp_state->encrypted_session_key);
659 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
661 data_blob_free(&ntlmssp_state->encrypted_session_key);
665 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
667 data_blob_free(&ntlmssp_state->encrypted_session_key);
671 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
672 ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
675 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);
676 file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length);
679 /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
682 However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
684 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
685 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
686 struct MD5Context md5_session_nonce_ctx;
687 SMB_ASSERT(ntlmssp_state->internal_chal.data
688 && ntlmssp_state->internal_chal.length == 8);
690 ntlmssp_state->doing_ntlm2 = True;
692 memcpy(ntlmssp_state->session_nonce, ntlmssp_state->internal_chal.data, 8);
693 memcpy(&ntlmssp_state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
695 MD5Init(&md5_session_nonce_ctx);
696 MD5Update(&md5_session_nonce_ctx, ntlmssp_state->session_nonce, 16);
697 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
699 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state,
700 session_nonce_hash, 8);
702 /* LM response is no longer useful, zero it out */
703 data_blob_free(&ntlmssp_state->lm_resp);
705 /* We changed the effective challenge - set it */
706 if (!NT_STATUS_IS_OK(nt_status =
707 ntlmssp_state->set_challenge(ntlmssp_state,
708 &ntlmssp_state->chal))) {
710 data_blob_free(&ntlmssp_state->encrypted_session_key);
714 /* LM Key is incompatible... */
715 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
722 * Next state function for the Authenticate packet
723 * (after authentication - figures out the session keys etc)
725 * @param ntlmssp_state NTLMSSP State
726 * @return Errors or NT_STATUS_OK.
729 static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
730 DATA_BLOB *user_session_key,
731 DATA_BLOB *lm_session_key)
734 DATA_BLOB session_key = data_blob(NULL, 0);
736 if (user_session_key)
737 dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length);
740 dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length);
742 /* Handle the different session key derivation for NTLM2 */
743 if (ntlmssp_state->doing_ntlm2) {
744 if (user_session_key && user_session_key->data && user_session_key->length == 16) {
745 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
746 hmac_md5(user_session_key->data, ntlmssp_state->session_nonce,
747 sizeof(ntlmssp_state->session_nonce), session_key.data);
748 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
749 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
752 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
753 session_key = data_blob(NULL, 0);
755 } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
756 /* Ensure we can never get here on NTLMv2 */
757 && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
759 if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
760 if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
761 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
762 SMBsesskeygen_lm_sess_key(lm_session_key->data, ntlmssp_state->lm_resp.data,
764 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
765 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
768 /* When there is no LM response, just use zeros */
769 static const uint8_t zeros[24];
770 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
771 SMBsesskeygen_lm_sess_key(zeros, zeros,
773 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
774 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
777 /* LM Key not selected */
778 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
780 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
781 session_key = data_blob(NULL, 0);
784 } else if (user_session_key && user_session_key->data) {
785 session_key = *user_session_key;
786 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
787 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
789 /* LM Key not selected */
790 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
792 } else if (lm_session_key && lm_session_key->data) {
793 /* Very weird to have LM key, but no user session key, but anyway.. */
794 session_key = *lm_session_key;
795 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
796 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
798 /* LM Key not selected */
799 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
802 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
803 session_key = data_blob(NULL, 0);
805 /* LM Key not selected */
806 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
809 /* With KEY_EXCH, the client supplies the proposed session key,
810 but encrypts it with the long-term key */
811 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
812 if (!ntlmssp_state->encrypted_session_key.data
813 || ntlmssp_state->encrypted_session_key.length != 16) {
814 data_blob_free(&ntlmssp_state->encrypted_session_key);
815 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
816 ntlmssp_state->encrypted_session_key.length));
817 return NT_STATUS_INVALID_PARAMETER;
818 } else if (!session_key.data || session_key.length != 16) {
819 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
820 session_key.length));
821 ntlmssp_state->session_key = session_key;
823 dump_data_pw("KEY_EXCH session key (enc):\n",
824 ntlmssp_state->encrypted_session_key.data,
825 ntlmssp_state->encrypted_session_key.length);
826 arcfour_crypt(ntlmssp_state->encrypted_session_key.data,
828 ntlmssp_state->encrypted_session_key.length);
829 ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
830 ntlmssp_state->encrypted_session_key.data,
831 ntlmssp_state->encrypted_session_key.length);
832 dump_data_pw("KEY_EXCH session key:\n", ntlmssp_state->encrypted_session_key.data,
833 ntlmssp_state->encrypted_session_key.length);
836 ntlmssp_state->session_key = session_key;
839 /* The server might need us to use a partial-strength session key */
840 ntlmssp_weaken_keys(ntlmssp_state);
842 nt_status = ntlmssp_sign_init(ntlmssp_state);
844 data_blob_free(&ntlmssp_state->encrypted_session_key);
846 /* allow arbitarily many authentications, but watch that this will cause a
847 memory leak, until the ntlmssp_state is shutdown
850 if (ntlmssp_state->server_multiple_authentications) {
851 ntlmssp_state->expected_state = NTLMSSP_AUTH;
853 ntlmssp_state->expected_state = NTLMSSP_DONE;
861 * Next state function for the Authenticate packet
863 * @param ntlmssp_state NTLMSSP State
864 * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
865 * @param out The reply, as an allocated DATA_BLOB, caller to free.
866 * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK.
869 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
870 TALLOC_CTX *out_mem_ctx,
871 const DATA_BLOB in, DATA_BLOB *out)
873 DATA_BLOB user_session_key = data_blob(NULL, 0);
874 DATA_BLOB lm_session_key = data_blob(NULL, 0);
877 /* zero the outbound NTLMSSP packet */
878 *out = data_blob_talloc(out_mem_ctx, NULL, 0);
880 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(ntlmssp_state, in))) {
885 * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
886 * is required (by "ntlm auth = no" and "lm auth = no" being set in the
887 * smb.conf file) and no NTLMv2 response was sent then the password check
888 * will fail here. JRA.
891 /* Finally, actually ask if the password is OK */
893 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state,
894 &user_session_key, &lm_session_key))) {
898 if (ntlmssp_state->server_use_session_keys) {
899 return ntlmssp_server_postauth(ntlmssp_state, &user_session_key, &lm_session_key);
901 ntlmssp_state->session_key = data_blob(NULL, 0);
907 * Create an NTLMSSP state machine
909 * @param ntlmssp_state NTLMSSP State, allocated by this function
912 NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
914 *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state);
915 if (!*ntlmssp_state) {
916 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
917 return NT_STATUS_NO_MEMORY;
919 ZERO_STRUCTP(*ntlmssp_state);
921 (*ntlmssp_state)->role = NTLMSSP_SERVER;
923 (*ntlmssp_state)->get_challenge = get_challenge;
924 (*ntlmssp_state)->set_challenge = set_challenge;
925 (*ntlmssp_state)->may_set_challenge = may_set_challenge;
927 (*ntlmssp_state)->workstation = NULL;
928 (*ntlmssp_state)->server_name = lp_netbios_name();
930 (*ntlmssp_state)->get_domain = lp_workgroup;
931 (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
933 (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
935 (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
936 && lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False));
938 (*ntlmssp_state)->server_use_session_keys = True;
939 (*ntlmssp_state)->server_multiple_authentications = False;
941 (*ntlmssp_state)->ref_count = 1;
943 (*ntlmssp_state)->neg_flags =
944 NTLMSSP_NEGOTIATE_NTLM;
946 if (lp_parm_bool(-1, "ntlmssp_server", "128bit", True)) {
947 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
950 if (lp_parm_bool(-1, "ntlmssp_server", "keyexchange", True)) {
951 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
954 if (lp_parm_bool(-1, "ntlmssp_server", "ntlm2", True)) {
955 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
961 /*********************************************************************
963 *********************************************************************/
966 * Next state function for the Initial packet
968 * @param ntlmssp_state NTLMSSP State
969 * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context
970 * @param in The request, as a DATA_BLOB. reply.data must be NULL
971 * @param out The reply, as an talloc()ed DATA_BLOB, on out_mem_ctx
972 * @return Errors or NT_STATUS_OK.
975 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
976 TALLOC_CTX *out_mem_ctx,
977 DATA_BLOB in, DATA_BLOB *out)
979 if (ntlmssp_state->unicode) {
980 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
982 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
985 if (ntlmssp_state->use_ntlmv2) {
986 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
989 /* generate the ntlmssp negotiate packet */
990 msrpc_gen(out_mem_ctx,
994 ntlmssp_state->neg_flags,
995 ntlmssp_state->get_domain(),
996 ntlmssp_state->workstation);
998 ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
1000 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1004 * Next state function for the Challenge Packet. Generate an auth packet.
1006 * @param ntlmssp_state NTLMSSP State
1007 * @param request The request, as a DATA_BLOB. reply.data must be NULL
1008 * @param request The reply, as an allocated DATA_BLOB, caller to free.
1009 * @return Errors or NT_STATUS_OK.
1012 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
1013 TALLOC_CTX *out_mem_ctx,
1014 const DATA_BLOB in, DATA_BLOB *out)
1016 uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
1017 DATA_BLOB server_domain_blob;
1018 DATA_BLOB challenge_blob;
1019 DATA_BLOB struct_blob = data_blob(NULL, 0);
1020 char *server_domain;
1021 const char *chal_parse_string;
1022 const char *auth_gen_string;
1023 uint8_t lm_hash[16];
1024 DATA_BLOB lm_response = data_blob(NULL, 0);
1025 DATA_BLOB nt_response = data_blob(NULL, 0);
1026 DATA_BLOB session_key = data_blob(NULL, 0);
1027 DATA_BLOB lm_session_key = data_blob(NULL, 0);
1028 DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
1031 if (!msrpc_parse(ntlmssp_state,
1035 &server_domain_blob,
1037 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
1038 dump_data(2, in.data, in.length);
1040 return NT_STATUS_INVALID_PARAMETER;
1043 data_blob_free(&server_domain_blob);
1045 DEBUG(3, ("Got challenge flags:\n"));
1046 debug_ntlmssp_flags(chal_flags);
1048 ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key);
1050 if (ntlmssp_state->unicode) {
1051 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1052 chal_parse_string = "CdUdbddB";
1054 chal_parse_string = "CdUdbdd";
1056 auth_gen_string = "CdBBUUUBd";
1058 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1059 chal_parse_string = "CdAdbddB";
1061 chal_parse_string = "CdAdbdd";
1064 auth_gen_string = "CdBBAAABd";
1067 DEBUG(3, ("NTLMSSP: Set final flags:\n"));
1068 debug_ntlmssp_flags(ntlmssp_state->neg_flags);
1070 if (!msrpc_parse(ntlmssp_state,
1071 &in, chal_parse_string,
1079 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
1080 dump_data(2, in.data, in.length);
1081 return NT_STATUS_INVALID_PARAMETER;
1084 ntlmssp_state->server_domain = server_domain;
1086 if (challenge_blob.length != 8) {
1087 return NT_STATUS_INVALID_PARAMETER;
1090 if (!ntlmssp_state->password) {
1091 static const uint8_t zeros[16];
1092 /* do nothing - blobs are zero length */
1094 /* session key is all zeros */
1095 session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1096 lm_session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1098 /* not doing NLTM2 without a password */
1099 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
1100 } else if (ntlmssp_state->use_ntlmv2) {
1102 if (!struct_blob.length) {
1103 /* be lazy, match win2k - we can't do NTLMv2 without it */
1104 DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
1105 return NT_STATUS_INVALID_PARAMETER;
1108 /* TODO: if the remote server is standalone, then we should replace 'domain'
1109 with the server name as supplied above */
1111 if (!SMBNTLMv2encrypt(ntlmssp_state->user,
1112 ntlmssp_state->domain,
1113 ntlmssp_state->password, &challenge_blob,
1115 &lm_response, &nt_response,
1116 NULL, &session_key)) {
1117 data_blob_free(&challenge_blob);
1118 data_blob_free(&struct_blob);
1119 return NT_STATUS_NO_MEMORY;
1122 /* LM Key is incompatible... */
1123 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1125 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
1126 struct MD5Context md5_session_nonce_ctx;
1127 uint8_t nt_hash[16];
1128 uint8_t session_nonce[16];
1129 uint8_t session_nonce_hash[16];
1130 uint8_t user_session_key[16];
1131 E_md4hash(ntlmssp_state->password, nt_hash);
1133 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1134 generate_random_buffer(lm_response.data, 8);
1135 memset(lm_response.data+8, 0, 16);
1137 memcpy(session_nonce, challenge_blob.data, 8);
1138 memcpy(&session_nonce[8], lm_response.data, 8);
1140 MD5Init(&md5_session_nonce_ctx);
1141 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
1142 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
1143 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
1145 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
1146 DEBUG(5, ("challenge is: \n"));
1147 dump_data(5, session_nonce_hash, 8);
1149 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1150 SMBNTencrypt(ntlmssp_state->password,
1154 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1156 SMBsesskeygen_ntv1(nt_hash, user_session_key);
1157 hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
1158 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
1160 /* LM Key is incompatible... */
1161 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1163 uint8_t nt_hash[16];
1165 if (ntlmssp_state->use_nt_response) {
1166 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1167 SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
1169 E_md4hash(ntlmssp_state->password, nt_hash);
1170 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1171 SMBsesskeygen_ntv1(nt_hash, session_key.data);
1172 dump_data_pw("NT session key:\n", session_key.data, session_key.length);
1175 /* lanman auth is insecure, it may be disabled */
1176 if (lp_client_lanman_auth()) {
1177 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1178 if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data,
1179 lm_response.data)) {
1180 /* If the LM password was too long (and therefore the LM hash being
1181 of the first 14 chars only), don't send it */
1182 data_blob_free(&lm_response);
1184 /* LM Key is incompatible with 'long' passwords */
1185 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1187 E_deshash(ntlmssp_state->password, lm_hash);
1188 lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1189 memcpy(lm_session_key.data, lm_hash, 8);
1190 memset(&lm_session_key.data[8], '\0', 8);
1192 if (!ntlmssp_state->use_nt_response) {
1193 session_key = lm_session_key;
1197 /* LM Key is incompatible... */
1198 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1202 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
1203 && lp_client_lanman_auth() && lm_session_key.length == 16) {
1204 DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1205 if (lm_response.length == 24) {
1206 SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data,
1207 new_session_key.data);
1209 static const uint8_t zeros[24];
1210 SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros,
1211 new_session_key.data);
1213 new_session_key.length = 16;
1214 session_key = new_session_key;
1215 dump_data_pw("LM session key\n", session_key.data, session_key.length);
1219 /* Key exchange encryptes a new client-generated session key with
1220 the password-derived key */
1221 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1222 /* Make up a new session key */
1223 uint8_t client_session_key[16];
1224 generate_random_buffer(client_session_key, sizeof(client_session_key));
1226 /* Encrypt the new session key with the old one */
1227 encrypted_session_key = data_blob_talloc(ntlmssp_state,
1228 client_session_key, sizeof(client_session_key));
1229 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
1230 arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
1231 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
1233 /* Mark the new session key as the 'real' session key */
1234 session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key));
1237 /* this generates the actual auth packet */
1238 if (!msrpc_gen(out_mem_ctx,
1239 out, auth_gen_string,
1242 lm_response.data, lm_response.length,
1243 nt_response.data, nt_response.length,
1244 ntlmssp_state->domain,
1245 ntlmssp_state->user,
1246 ntlmssp_state->workstation,
1247 encrypted_session_key.data, encrypted_session_key.length,
1248 ntlmssp_state->neg_flags)) {
1250 return NT_STATUS_NO_MEMORY;
1253 ntlmssp_state->session_key = session_key;
1255 /* The client might be using 56 or 40 bit weakened keys */
1256 ntlmssp_weaken_keys(ntlmssp_state);
1258 ntlmssp_state->chal = challenge_blob;
1259 ntlmssp_state->lm_resp = lm_response;
1260 ntlmssp_state->nt_resp = nt_response;
1262 ntlmssp_state->expected_state = NTLMSSP_DONE;
1264 nt_status = ntlmssp_sign_init(ntlmssp_state);
1265 if (!NT_STATUS_IS_OK(nt_status)) {
1266 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
1267 nt_errstr(nt_status)));
1274 NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
1276 *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state);
1277 if (!*ntlmssp_state) {
1278 DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
1279 return NT_STATUS_NO_MEMORY;
1281 ZERO_STRUCTP(*ntlmssp_state);
1283 (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1285 (*ntlmssp_state)->workstation = lp_netbios_name();
1286 (*ntlmssp_state)->get_domain = lp_workgroup;
1288 (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True);
1290 (*ntlmssp_state)->use_nt_response = lp_parm_bool(-1, "ntlmssp_client", "send_nt_reponse", True);
1292 (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
1293 && lp_parm_bool(-1, "ntlmssp_client", "allow_lm_key", False));
1295 (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1297 (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1299 (*ntlmssp_state)->ref_count = 1;
1301 (*ntlmssp_state)->neg_flags =
1302 NTLMSSP_NEGOTIATE_NTLM |
1303 NTLMSSP_REQUEST_TARGET;
1305 if (lp_parm_bool(-1, "ntlmssp_client", "128bit", True)) {
1306 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
1309 if (lp_parm_bool(-1, "ntlmssp_client", "keyexchange", True)) {
1310 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
1313 if (lp_parm_bool(-1, "ntlmssp_client", "ntlm2", True)) {
1314 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
1316 /* apparently we can't do ntlmv2 if we don't do ntlm2 */
1317 (*ntlmssp_state)->use_ntlmv2 = False;
1320 return NT_STATUS_OK;