(only for HEAD at the moment).
authorAndrew Bartlett <abartlet@samba.org>
Sun, 9 Feb 2003 12:26:58 +0000 (12:26 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 9 Feb 2003 12:26:58 +0000 (12:26 +0000)
Add NTLMv2 support to our client, used when so configured ('client use NTLMv2 =
yes') and only when 'client use spengo = no'.  (A new option to allow the
client and server ends to chose spnego seperatly).

NTLMv2 signing doesn't yet work, and NTLMv2 is not done for NTLMSSP yet.

Also some parinoia checks in our input parsing.

Andrew Bartlett
(This used to be commit 85e9c060eab59c7692198f14a447ad59f05af437)

source3/include/client.h
source3/libsmb/cliconnect.c
source3/libsmb/clientgen.c
source3/libsmb/clispnego.c
source3/libsmb/ntlmssp.c
source3/libsmb/smbencrypt.c
source3/param/loadparm.c

index d9b72d5e0a5de3e6ef26c2d6760557ce0d9a5c6c..ddb1772c2601e33466f792f9b33ee80474ec8adb 100644 (file)
@@ -62,7 +62,7 @@ typedef struct smb_sign_info {
        BOOL negotiated_smb_signing;
        BOOL temp_smb_signing;
        size_t mac_key_len;
-       uint8 mac_key[44];
+       uint8 mac_key[64];
        uint32 send_seq_num;
        uint32 reply_seq_num;
        BOOL allow_smb_signing;
index ebe19b51433e3104019cd33982a790a240e318c4..1c89423b7f8e7b7799f423ed41b40141e7be3aee 100644 (file)
@@ -2,7 +2,7 @@
    Unix SMB/CIFS implementation.
    client connect/disconnect routines
    Copyright (C) Andrew Tridgell 1994-1998
-   Copyright (C) Andrew Barteltt 2001-2002
+   Copyright (C) Andrew Barteltt 2001-2003
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -45,7 +45,7 @@ static const struct {
 ****************************************************************************/
 
 static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, 
-                                     const char *pass, int passlen, const char *workgroup)
+                                     const char *pass, size_t passlen, const char *workgroup)
 {
        fstring pword;
        char *p;
@@ -228,7 +228,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user,
        return True;
 }
 
-static void set_signing_on_cli (struct cli_state *cli, const char* pass, uint8 response[24]
+static void set_signing_on_cli (struct cli_state *cli, uint8 user_session_key[16], DATA_BLOB response
 {
        uint8 zero_sig[8];
        ZERO_STRUCT(zero_sig);
@@ -242,7 +242,7 @@ static void set_signing_on_cli (struct cli_state *cli, const char* pass, uint8 r
 
                DEBUG(3, ("smb signing enabled!\n"));
                cli->sign_info.use_smb_signing = True;
-               cli_calculate_mac_key(cli, pass, response);
+               cli_calculate_mac_key(cli, user_session_key, response);
        } else {
                DEBUG(5, ("smb signing NOT enabled!\n"));
        }
@@ -265,25 +265,90 @@ static void set_temp_signing_on_cli(struct cli_state *cli)
 ****************************************************************************/
 
 static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, 
-                                 const char *pass, int passlen,
-                                 const char *ntpass, int ntpasslen,
+                                 const char *pass, size_t passlen,
+                                 const char *ntpass, size_t ntpasslen,
                                  const char *workgroup)
 {
        uint32 capabilities = cli_session_setup_capabilities(cli);
-       uchar pword[24];
-       uchar ntpword[24];
+       DATA_BLOB lm_response = data_blob(NULL, 0);
+       DATA_BLOB nt_response = data_blob(NULL, 0);
+       uchar user_session_key[16];
        char *p;
        BOOL have_plaintext = False;
 
-       if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword))
-               return False;
-
        if (passlen != 24) {
-               /* non encrypted password supplied. Ignore ntpass. */
-               passlen = 24;
-               ntpasslen = 24;
-               SMBencrypt(pass,cli->secblob.data,pword);
-               SMBNTencrypt(pass,cli->secblob.data,ntpword);
+               uchar nt_hash[16];
+               E_md4hash(pass, nt_hash);
+
+               if (lp_client_ntlmv2_auth()) {
+                       uchar ntlm_v2_hash[16];
+                       uchar ntlmv2_response[16];
+                       uchar lmv2_response[16];
+                       DATA_BLOB ntlmv2_client_data;
+                       DATA_BLOB lmv2_client_data;
+                       DATA_BLOB server_chal;
+
+                       /* We don't use the NT# directly.  Instead we use it mashed up with
+                          the username and domain.
+                          This prevents username swapping during the auth exchange
+                       */
+                       if (!ntv2_owf_gen(nt_hash, user, workgroup, ntlm_v2_hash)) {
+                               return False;
+                       }
+
+                       server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); 
+
+                       /* NTLMv2 */
+
+                       /* We also get to specify some random data */
+                       ntlmv2_client_data = data_blob(NULL, 20);
+                       generate_random_buffer(ntlmv2_client_data.data, ntlmv2_client_data.length, False);
+                       memset(ntlmv2_client_data.data, 'A', ntlmv2_client_data.length);
+
+                       /* Given that data, and the challenge from the server, generate a response */
+                       SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, ntlmv2_client_data, ntlmv2_response);
+
+                       /* put it into nt_response, for the code below to put into the packet */
+                       nt_response = data_blob(NULL, ntlmv2_client_data.length + sizeof(ntlmv2_response));
+                       memcpy(nt_response.data, ntlmv2_response, sizeof(ntlmv2_response));
+                       /* after the first 16 bytes is the random data we generated above, so the server can verify us with it */
+                       memcpy(nt_response.data + sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length);
+                       data_blob_free(&ntlmv2_client_data);
+
+
+                       /* LMv2 */
+
+                       /* We also get to specify some random data, but only 8 bytes (24 byte total response) */
+                       lmv2_client_data = data_blob(NULL, 8);
+                       generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length, False);
+                       memset(lmv2_client_data.data, 'B', lmv2_client_data.length);
+
+                       /* Calculate response */
+                       SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, lmv2_client_data, lmv2_response);
+
+                       /* Calculate response */
+                       lm_response = data_blob(NULL, lmv2_client_data.length + sizeof(lmv2_response));
+                       memcpy(lm_response.data, lmv2_response, sizeof(lmv2_response));
+                       /* after the first 16 bytes is the 8 bytes of random data we made above */
+                       memcpy(lm_response.data + sizeof(lmv2_response), lmv2_client_data.data, lmv2_client_data.length);
+                       data_blob_free(&lmv2_client_data);
+
+                       data_blob_free(&server_chal);
+
+                       /* The NTLMv2 calculations also provide a session key, for signing etc later */
+                       SMBsesskeygen_ntv2(ntlm_v2_hash, ntlmv2_response, user_session_key);
+
+               } else {
+                       /* non encrypted password supplied. Ignore ntpass. */
+                       if (lp_client_lanman_auth()) {
+                               lm_response = data_blob(NULL, 24);
+                               SMBencrypt(pass,cli->secblob.data,lm_response.data);
+                       }
+
+                       nt_response = data_blob(NULL, 24);
+                       SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
+                       SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key);
+               }
 
                have_plaintext = True;
                set_temp_signing_on_cli(cli);
@@ -291,11 +356,9 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
                /* pre-encrypted password supplied.  Only used for 
                   security=server, can't do
                   signing becouse we don't have oringial key */
-               memcpy(pword, pass, 24);
-               if (ntpasslen == 24)
-                       memcpy(ntpword, ntpass, 24);
-               else
-                       ZERO_STRUCT(ntpword);
+
+               lm_response = data_blob(pass, passlen);
+               nt_response = data_blob(ntpass, ntpasslen);
        }
 
        /* send a session setup command */
@@ -310,28 +373,35 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
        SSVAL(cli->outbuf,smb_vwv3,2);
        SSVAL(cli->outbuf,smb_vwv4,cli->pid);
        SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
-       SSVAL(cli->outbuf,smb_vwv7,passlen);
-       SSVAL(cli->outbuf,smb_vwv8,ntpasslen);
+       SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
+       SSVAL(cli->outbuf,smb_vwv8,nt_response.length);
        SIVAL(cli->outbuf,smb_vwv11,capabilities); 
        p = smb_buf(cli->outbuf);
-       memcpy(p,pword,passlen); p += passlen;
-       memcpy(p,ntpword,ntpasslen); p += ntpasslen;
+       if (lm_response.length) {
+               memcpy(p,lm_response.data, lm_response.length); p += lm_response.length;
+       }
+       if (nt_response.length) {
+               memcpy(p,nt_response.data, nt_response.length); p += nt_response.length;
+       }
        p += clistr_push(cli, p, user, -1, STR_TERMINATE);
        p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE);
        p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
        p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
        cli_setup_bcc(cli, p);
 
-       if (!cli_send_smb(cli))
-               return False;
-
-       if (!cli_receive_smb(cli))
+       if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
+               data_blob_free(&lm_response);
+               data_blob_free(&nt_response);
                return False;
+       }
 
        show_msg(cli->inbuf);
 
-       if (cli_is_error(cli))
+       if (cli_is_error(cli)) {
+               data_blob_free(&lm_response);
+               data_blob_free(&nt_response);
                return False;
+       }
 
        /* use the returned vuid from now on */
        cli->vuid = SVAL(cli->inbuf,smb_uid);
@@ -345,9 +415,11 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
 
        if (have_plaintext) {
                /* Have plaintext orginal */
-               set_signing_on_cli(cli, pass, ntpword);
+               set_signing_on_cli(cli, user_session_key, nt_response);
        }
        
+       data_blob_free(&lm_response);
+       data_blob_free(&nt_response);
        return True;
 }
 
@@ -529,6 +601,10 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
                return False;
        }
  
+       if (challenge_blob.length < 8) {
+               return False;
+       }
+
        DEBUG(10, ("Challenge:\n"));
        dump_data(10, challenge_blob.data, 8);
 
index ab051426aee684c7fbee1bc0258b7878c192baa2..9598f4ac9642da4c55b72b72e8bd64f12e7e72b1 100644 (file)
@@ -251,8 +251,8 @@ struct cli_state *cli_initialise(struct cli_state *cli)
        cli->outbuf = (char *)malloc(cli->bufsize);
        cli->inbuf = (char *)malloc(cli->bufsize);
        cli->oplock_handler = cli_oplock_ack;
-       if (lp_use_spnego())
-               cli->use_spnego = True;
+
+       cli->use_spnego = lp_client_use_spnego();
 
        cli->capabilities = CAP_UNICODE | CAP_STATUS32;
 
index 3e28baa417c8abda8fccc0e5f5633b07fde825be..277bf4765f068641927cfc2acf6c638edd6fe93d 100644 (file)
@@ -709,7 +709,8 @@ BOOL msrpc_parse(DATA_BLOB *blob,
                case 'b':
                        b = (DATA_BLOB *)va_arg(ap, void *);
                        len1 = va_arg(ap, unsigned);
-                       *b = data_blob(blob->data + head_ofs, len1);
+                       *b = data_blob(blob->data + head_ofs, 
+                                      MIN(len1, blob->length - head_ofs));
                        head_ofs += len1;
                        break;
                case 'd':
index 5b608e0a7a90866135f417b312663c8646731674..886f87276415595ed683a2c6376b795c77808b6d 100644 (file)
@@ -37,71 +37,7 @@ static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state)
        return chal;
 }
 
-NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
-{
-       TALLOC_CTX *mem_ctx;
-
-       mem_ctx = talloc_init("NTLMSSP context");
-       
-       *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
-       if (!*ntlmssp_state) {
-               DEBUG(0,("ntlmssp_start: talloc failed!\n"));
-               talloc_destroy(mem_ctx);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       ZERO_STRUCTP(*ntlmssp_state);
-
-       (*ntlmssp_state)->mem_ctx = mem_ctx;
-       (*ntlmssp_state)->get_challenge = get_challenge;
-
-       (*ntlmssp_state)->get_global_myname = global_myname;
-       (*ntlmssp_state)->get_domain = lp_workgroup;
-       (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
-
-       return NT_STATUS_OK;
-}
-
-NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state)
-{
-       TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;
-
-       data_blob_free(&(*ntlmssp_state)->chal);
-       data_blob_free(&(*ntlmssp_state)->lm_resp);
-       data_blob_free(&(*ntlmssp_state)->nt_resp);
-
-       SAFE_FREE((*ntlmssp_state)->user);
-       SAFE_FREE((*ntlmssp_state)->domain);
-       SAFE_FREE((*ntlmssp_state)->workstation);
-
-       talloc_destroy(mem_ctx);
-       *ntlmssp_state = NULL;
-       return NT_STATUS_OK;
-}
-
-NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, 
-                              DATA_BLOB request, DATA_BLOB *reply) 
-{
-       uint32 ntlmssp_command;
-       *reply = data_blob(NULL, 0);
-
-       if (!msrpc_parse(&request, "Cd",
-                        "NTLMSSP",
-                        &ntlmssp_command)) {
-               
-               return NT_STATUS_LOGON_FAILURE;
-       }
-
-       if (ntlmssp_command == NTLMSSP_NEGOTIATE) {
-               return ntlmssp_negotiate(ntlmssp_state, request, reply);
-       } else if (ntlmssp_command == NTLMSSP_AUTH) {
-               return ntlmssp_auth(ntlmssp_state, request, reply);
-       } else {
-               return NT_STATUS_LOGON_FAILURE;
-       }
-}
-
-static const char *ntlmssp_target_name(NTLMSSP_STATE *ntlmssp_state, 
+static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
                                       uint32 neg_flags, uint32 *chal_flags) 
 {
        if (neg_flags & NTLMSSP_REQUEST_TARGET) {
@@ -119,8 +55,8 @@ static const char *ntlmssp_target_name(NTLMSSP_STATE *ntlmssp_state,
        }
 }
 
-NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state, 
-                          DATA_BLOB request, DATA_BLOB *reply) 
+static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
+                                        DATA_BLOB request, DATA_BLOB *reply) 
 {
        DATA_BLOB struct_blob;
        fstring dnsname, dnsdomname;
@@ -222,8 +158,8 @@ NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state,
        return NT_STATUS_MORE_PROCESSING_REQUIRED;
 }
 
-NTSTATUS ntlmssp_auth(NTLMSSP_STATE *ntlmssp_state, 
-                     DATA_BLOB request, DATA_BLOB *reply) 
+static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
+                                   DATA_BLOB request, DATA_BLOB *reply) 
 {
        DATA_BLOB sess_key;
        uint32 ntlmssp_command, neg_flags;
@@ -279,3 +215,68 @@ NTSTATUS ntlmssp_auth(NTLMSSP_STATE *ntlmssp_state,
 
        return nt_status;
 }
+
+NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
+{
+       TALLOC_CTX *mem_ctx;
+
+       mem_ctx = talloc_init("NTLMSSP context");
+       
+       *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
+       if (!*ntlmssp_state) {
+               DEBUG(0,("ntlmssp_start: talloc failed!\n"));
+               talloc_destroy(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       ZERO_STRUCTP(*ntlmssp_state);
+
+       (*ntlmssp_state)->mem_ctx = mem_ctx;
+       (*ntlmssp_state)->get_challenge = get_challenge;
+
+       (*ntlmssp_state)->get_global_myname = global_myname;
+       (*ntlmssp_state)->get_domain = lp_workgroup;
+       (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
+
+       return NT_STATUS_OK;
+}
+
+NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state)
+{
+       TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;
+
+       data_blob_free(&(*ntlmssp_state)->chal);
+       data_blob_free(&(*ntlmssp_state)->lm_resp);
+       data_blob_free(&(*ntlmssp_state)->nt_resp);
+
+       SAFE_FREE((*ntlmssp_state)->user);
+       SAFE_FREE((*ntlmssp_state)->domain);
+       SAFE_FREE((*ntlmssp_state)->workstation);
+
+       talloc_destroy(mem_ctx);
+       *ntlmssp_state = NULL;
+       return NT_STATUS_OK;
+}
+
+NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, 
+                              DATA_BLOB request, DATA_BLOB *reply) 
+{
+       uint32 ntlmssp_command;
+       *reply = data_blob(NULL, 0);
+
+       if (!msrpc_parse(&request, "Cd",
+                        "NTLMSSP",
+                        &ntlmssp_command)) {
+               
+               return NT_STATUS_LOGON_FAILURE;
+       }
+
+       if (ntlmssp_command == NTLMSSP_NEGOTIATE) {
+               return ntlmssp_server_negotiate(ntlmssp_state, request, reply);
+       } else if (ntlmssp_command == NTLMSSP_AUTH) {
+               return ntlmssp_server_auth(ntlmssp_state, request, reply);
+       } else {
+               return NT_STATUS_LOGON_FAILURE;
+       }
+}
+
index a30a48a020c82d038443f77c98954514745bfbe9..34689b502c9a9ab1ac6cedfd76b65a1d40ce0748 100644 (file)
@@ -363,19 +363,17 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
  SMB signing - setup the MAC key.
 ************************************************************/
 
-void cli_calculate_mac_key(struct cli_state *cli, const char *plain_passwd, const uchar resp[24])
+void cli_calculate_mac_key(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response)
 {
-       uchar nt_hash[16];
-       E_md4hash(plain_passwd, nt_hash);
        
-       mdfour(&cli->sign_info.mac_key[0], nt_hash, sizeof(nt_hash));
-       memcpy(&cli->sign_info.mac_key[16],resp,24);
-       cli->sign_info.mac_key_len = 40;
+       memcpy(&cli->sign_info.mac_key[0], user_session_key, 16);
+       memcpy(&cli->sign_info.mac_key[16],response.data, MIN(response.length, 40 - 16));
+       cli->sign_info.mac_key_len = MIN(response.length + 16, 40);
        cli->sign_info.use_smb_signing = True;
 
        /* These calls are INCONPATIBLE with SMB signing */
        cli->readbraw_supported = False;
-       cli->writebraw_supported = False;    
+       cli->writebraw_supported = False;
 
        /* Reset the sequence number in case we had a previous (aborted) attempt */
        cli->sign_info.send_seq_num = 2;
index ac366d4ccd5593731355796d036a1c0fdf0908a0..398ae88b97c3cfce1c5ffa20efff4fcf8698a502 100644 (file)
@@ -264,6 +264,10 @@ typedef struct
        BOOL bAllowTrustedDomains;
        BOOL bLanmanAuth;
        BOOL bNTLMAuth;
+       BOOL bUseSpnego;
+       BOOL bClientLanManAuth;
+       BOOL bClientNTLMv2Auth;
+       BOOL bClientUseSpnego;
        BOOL bDebugHiresTimestamp;
        BOOL bDebugPid;
        BOOL bDebugUid;
@@ -272,7 +276,6 @@ typedef struct
        BOOL bUnicode;
        BOOL bUseMmap;
        BOOL bHostnameLookups;
-       BOOL bUseSpnego;
        BOOL bUnixExtensions;
        BOOL bDisableNetbios;
        BOOL bKernelChangeNotify;
@@ -772,6 +775,8 @@ static struct parm_struct parm_table[] = {
        {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
        {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
        {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+       {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+       {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
        
        {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
        {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
@@ -864,6 +869,7 @@ static struct parm_struct parm_table[] = {
        {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
        {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
        {"client signing", P_BOOL, P_GLOBAL, &Globals.client_signing, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+       {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_DEVELOPER},
 
        {"Tuning Options", P_SEP, P_SEPARATOR},
        
@@ -1375,8 +1381,10 @@ static void init_globals(void)
        Globals.bNTStatusSupport = True; /* Use NT status by default. */
        Globals.bStatCache = True;      /* use stat cache by default */
        Globals.restrict_anonymous = 0;
+       Globals.bClientLanManAuth = True;       /* Do use the LanMan hash if it is available */
        Globals.bLanmanAuth = True;     /* Do use the LanMan hash if it is available */
        Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
+       
        Globals.map_to_guest = 0;       /* By Default, "Never" */
        Globals.min_passwd_length = MINPASSWDLENGTH;    /* By Default, 5. */
        Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
@@ -1453,6 +1461,7 @@ static void init_globals(void)
        Globals.name_cache_timeout = 660; /* In seconds */
 
        Globals.bUseSpnego = True;
+       Globals.bClientUseSpnego = True;
 
        string_set(&Globals.smb_ports, SMB_PORTS);
 }
@@ -1677,12 +1686,15 @@ FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
+FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
+FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
+FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
 FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)