Enforce 'client plaintext auth', 'client lanman auth' and 'client ntlmv2 auth'.
authorAndrew Bartlett <abartlet@samba.org>
Sun, 8 Jun 2003 12:49:31 +0000 (12:49 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 8 Jun 2003 12:49:31 +0000 (12:49 +0000)
(this now causes things like the LANMAN protocol and contacting servers with 'encrypt passwords = no' set to fail, if configured)

'client ntlmv2 auth' (a BOOL) forces both plaintext and lanman off, and is the
most secure setting for compatible hosts.

Perhaps we should change this to 'client minimum auth'?

Andrew Bartlett
(This used to be commit e1fb681e4c921456fde154b87687722a18ed4aac)

source3/libsmb/cliconnect.c
source3/param/loadparm.c

index 8ebac7bae7bd236eda79e6f7a6a92ba77901870f..ffacc3af9a8fbf6097d644300a46773e210e0f86 100644 (file)
@@ -293,14 +293,18 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
                        uchar nt_hash[16];
                        E_md4hash(pass, nt_hash);
 
+                       nt_response = data_blob(NULL, 24);
+                       SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
+
                        /* 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);
+                               SMBencrypt(pass,cli->secblob.data, lm_response.data);
+                       } else {
+                               /* LM disabled, place NT# in LM feild instead */
+                               lm_response = data_blob(nt_response.data, nt_response.length);
                        }
 
-                       nt_response = data_blob(NULL, 24);
-                       SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
                        session_key = data_blob(NULL, 16);
                        SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
                }
@@ -575,7 +579,6 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
                        }
                        data_blob_free(&tmp_blob);
                } else {
-                       /* the server might give us back two challenges */
                        if (!spnego_parse_auth_response(blob, nt_status, 
                                                        &blob_in)) {
                                DEBUG(3,("Failed to parse auth response\n"));
@@ -713,8 +716,22 @@ BOOL cli_session_setup(struct cli_state *cli,
 
        /* if its an older server then we have to use the older request format */
 
-       if (cli->protocol < PROTOCOL_NT1)
+       if (cli->protocol < PROTOCOL_NT1) {
+               if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
+                       DEBUG(1, ("Server requested LM password but 'client lanman auth'"
+                                 " is disabled\n"));
+                       return False;
+               }
+
+               if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
+                   !lp_client_plaintext_auth() && (*pass)) {
+                       DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
+                                 " is disabled\n"));
+                       return False;
+               }
+
                return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup);
+       }
 
        /* if no user is supplied then we have to do an anonymous connection.
           passwords are ignored */
@@ -726,17 +743,21 @@ BOOL cli_session_setup(struct cli_state *cli,
            password at this point. The password is sent in the tree
            connect */
 
-       if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
+       if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) 
                return cli_session_setup_plaintext(cli, user, "", workgroup);
 
        /* if the server doesn't support encryption then we have to use 
           plaintext. The second password is ignored */
 
-       if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0)
+       if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
+               if (!lp_client_plaintext_auth() && (*pass)) {
+                       DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
+                                 " is disabled\n"));
+                       return False;
+               }
                return cli_session_setup_plaintext(cli, user, pass, workgroup);
+       }
 
-       /* Indidicate signing */
-       
        /* if the server supports extended security then use SPNEGO */
 
        if (cli->capabilities & CAP_EXTENDED_SECURITY)
@@ -789,6 +810,12 @@ BOOL cli_send_tconX(struct cli_state *cli,
        }
 
        if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) {
+               if (!lp_client_lanman_auth()) {
+                       DEBUG(1, ("Server requested LANMAN password but 'client use lanman auth'"
+                                 " is disabled\n"));
+                       return False;
+               }
+
                /*
                 * Non-encrypted passwords - convert to DOS codepage before encryption.
                 */
@@ -796,10 +823,17 @@ BOOL cli_send_tconX(struct cli_state *cli,
                SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
        } else {
                if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) {
+                       if (!lp_client_plaintext_auth() && (*pass)) {
+                               DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
+                                         " is disabled\n"));
+                               return False;
+                       }
+
                        /*
                         * Non-encrypted passwords - convert to DOS codepage before using.
                         */
                        passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
+                       
                } else {
                        memcpy(pword, pass, passlen);
                }
@@ -1375,6 +1409,12 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli,
 {
        char *p;
 
+       if (!lp_client_plaintext_auth() && (*pass)) {
+               DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
+                         " is disabled\n"));
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
        memset(cli->outbuf,'\0',smb_size);
        memset(cli->inbuf,'\0',smb_size);
 
index 30fc6c5d1212536f5b0c97b6e9217da80539426a..9ca7a58e832e907fb9bba08331906e7880f83395 100644 (file)
@@ -276,6 +276,7 @@ typedef struct
        BOOL bUseSpnego;
        BOOL bClientLanManAuth;
        BOOL bClientNTLMv2Auth;
+       BOOL bClientPlaintextAuth;
        BOOL bClientUseSpnego;
        BOOL bDebugHiresTimestamp;
        BOOL bDebugPid;
@@ -567,6 +568,7 @@ static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr);
 
 static void set_server_role(void);
 static void set_default_server_announce_type(void);
+static void set_allowed_client_auth(void);
 
 static const struct enum_list enum_protocol[] = {
        {PROTOCOL_NT1, "NT1"},
@@ -778,6 +780,7 @@ static struct parm_struct parm_table[] = {
        {"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},
+       {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, 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},
@@ -1386,6 +1389,7 @@ static void init_globals(void)
        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.bClientPlaintextAuth = True;    /* Do use a plaintext password if is requested by the server */
        Globals.bLanmanAuth = True;     /* Do use the LanMan hash if it is available */
        Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
        
@@ -1695,6 +1699,7 @@ 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_plaintext_auth, &Globals.bClientPlaintextAuth)
 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)
@@ -3821,6 +3826,19 @@ static void set_server_role(void)
        }
 }
 
+/***********************************************************
+ If we should send plaintext/LANMAN passwords in the clinet
+************************************************************/
+static void set_allowed_client_auth(void)
+{
+       if (Globals.bClientNTLMv2Auth) {
+               Globals.bClientLanManAuth = False;
+       }
+       if (!Globals.bClientLanManAuth) {
+               Globals.bClientPlaintextAuth = False;
+       }
+}
+
 /***************************************************************************
  Load the services array from the services file. Return True on success, 
  False on failure.
@@ -3888,6 +3906,7 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
 
        set_server_role();
        set_default_server_announce_type();
+       set_allowed_client_auth();
 
        bLoaded = True;