Skip to content

Commit

Permalink
executor: disable password validation for tidb_auth_token users (#4…
Browse files Browse the repository at this point in the history
  • Loading branch information
CbcWestwolf committed May 24, 2023
1 parent ad0957f commit a98e98e
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 26 deletions.
2 changes: 1 addition & 1 deletion errno/errname.go
Expand Up @@ -782,7 +782,7 @@ var MySQLErrName = map[uint16]*mysql.ErrMessage{
ErrInnodbImport: mysql.Message("ALTER TABLE '%-.192s' IMPORT TABLESPACE failed with error %d : '%s'", nil),
ErrInnodbIndexCorrupt: mysql.Message("Index corrupt: %s", nil),
ErrInvalidYearColumnLength: mysql.Message("Supports only YEAR or YEAR(4) column", nil),
ErrNotValidPassword: mysql.Message("Your password does not satisfy the current policy requirements", nil),
ErrNotValidPassword: mysql.Message("Your password does not satisfy the current policy requirements (%s)", nil),
ErrMustChangePassword: mysql.Message("You must reset your password using ALTER USER statement before executing this statement", nil),
ErrFkNoIndexChild: mysql.Message("Failed to add the foreign key constraint. Missing index for constraint '%s' in the foreign table '%s'", nil),
ErrForeignKeyNoIndexInParent: mysql.Message("Failed to add the foreign key constraint. Missing index for constraint '%s' in the referenced table '%s'", nil),
Expand Down
2 changes: 1 addition & 1 deletion errors.toml
Expand Up @@ -1558,7 +1558,7 @@ SET PASSWORD has no significance for user '%-.48s'@'%-.255s' as authentication p

["executor:1819"]
error = '''
Your password does not satisfy the current policy requirements
Your password does not satisfy the current policy requirements (%s)
'''

["executor:1820"]
Expand Down
23 changes: 8 additions & 15 deletions executor/simple.go
Expand Up @@ -1025,13 +1025,6 @@ func deletePasswordLockingAttribute(ctx context.Context, sqlExecutor sqlexec.SQL
return err
}

func (e *SimpleExec) authUsingCleartextPwd(authOpt *ast.AuthOption, authPlugin string) bool {
if authOpt == nil || !authOpt.ByAuthString {
return false
}
return mysql.IsAuthPluginClearText(authPlugin)
}

func (e *SimpleExec) isValidatePasswordEnabled() bool {
validatePwdEnable, err := e.ctx.GetSessionVars().GlobalVarsAccessor.GetGlobalSysVar(variable.ValidatePasswordEnable)
if err != nil {
Expand Down Expand Up @@ -1175,14 +1168,14 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm
if spec.AuthOpt != nil && spec.AuthOpt.AuthPlugin != "" {
authPlugin = spec.AuthOpt.AuthPlugin
}
if e.isValidatePasswordEnabled() && !s.IsCreateRole {
if spec.AuthOpt == nil || !spec.AuthOpt.ByAuthString && spec.AuthOpt.HashString == "" {
return variable.ErrNotValidPassword.GenWithStackByArgs()
// Validate the strength of the password if necessary
if e.isValidatePasswordEnabled() && !s.IsCreateRole && mysql.IsAuthPluginClearText(authPlugin) {
pwd := ""
if spec.AuthOpt != nil {
pwd = spec.AuthOpt.AuthString
}
if e.authUsingCleartextPwd(spec.AuthOpt, authPlugin) {
if err := pwdValidator.ValidatePassword(e.ctx.GetSessionVars(), spec.AuthOpt.AuthString); err != nil {
return err
}
if err := pwdValidator.ValidatePassword(e.ctx.GetSessionVars(), pwd); err != nil {
return err
}
}
pwd, ok := spec.EncodedPassword()
Expand Down Expand Up @@ -1829,7 +1822,7 @@ func (e *SimpleExec) executeAlterUser(ctx context.Context, s *ast.AlterUserStmt)
break
}
}
if e.isValidatePasswordEnabled() && e.authUsingCleartextPwd(spec.AuthOpt, spec.AuthOpt.AuthPlugin) {
if e.isValidatePasswordEnabled() && spec.AuthOpt.ByAuthString && mysql.IsAuthPluginClearText(spec.AuthOpt.AuthPlugin) {
if err := pwdValidator.ValidatePassword(e.ctx.GetSessionVars(), spec.AuthOpt.AuthString); err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions executor/test/passwordtest/password_management_test.go
Expand Up @@ -103,9 +103,9 @@ func TestValidatePassword(t *testing.T) {
// "IDENTIFIED AS 'xxx'" is not affected by validation
tk.MustExec(fmt.Sprintf("ALTER USER testuser IDENTIFIED WITH '%s' AS ''", authPlugin))
}
tk.MustContainErrMsg("CREATE USER 'testuser1'@'localhost'", "Your password does not satisfy the current policy requirements")
tk.MustContainErrMsg("CREATE USER 'testuser1'@'localhost' IDENTIFIED WITH 'caching_sha2_password'", "Your password does not satisfy the current policy requirements")
tk.MustContainErrMsg("CREATE USER 'testuser1'@'localhost' IDENTIFIED WITH 'caching_sha2_password' AS ''", "Your password does not satisfy the current policy requirements")
tk.MustGetErrCode("CREATE USER 'testuser1'@'localhost'", errno.ErrNotValidPassword)
tk.MustGetErrCode("CREATE USER 'testuser1'@'localhost' IDENTIFIED WITH 'caching_sha2_password'", errno.ErrNotValidPassword)
tk.MustGetErrCode("CREATE USER 'testuser1'@'localhost' IDENTIFIED WITH 'caching_sha2_password' AS ''", errno.ErrNotValidPassword)

// if the username is '', all password can pass the check_user_name
subtk.MustQuery("SELECT user(), current_user()").Check(testkit.Rows("@localhost @localhost"))
Expand Down
3 changes: 2 additions & 1 deletion executor/test/simpletest/BUILD.bazel
Expand Up @@ -10,9 +10,10 @@ go_test(
],
flaky = True,
race = "on",
shard_count = 35,
shard_count = 36,
deps = [
"//config",
"//errno",
"//parser/auth",
"//parser/model",
"//parser/mysql",
Expand Down
17 changes: 17 additions & 0 deletions executor/test/simpletest/simple_test.go
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/pingcap/errors"
"github.com/pingcap/tidb/config"
"github.com/pingcap/tidb/errno"
"github.com/pingcap/tidb/parser/auth"
"github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/parser/mysql"
Expand Down Expand Up @@ -1134,3 +1135,19 @@ func TestAlterUserWithLDAP(t *testing.T) {
tk.MustExec("ALTER USER 'bob'@'localhost' IDENTIFIED WITH authentication_ldap_sasl AS 'uid=bob,ou=People,dc=example,dc=com'")
tk.MustExec("ALTER USER 'bob'@'localhost' IDENTIFIED WITH authentication_ldap_sasl AS 'uid=bob,ou=Manager,dc=example,dc=com'")
}

func TestIssue44098(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)

tk.MustExec("set global validate_password.enable = 1")
tk.MustExec("create user u1 identified with 'tidb_auth_token'")
tk.MustExec("create user u2 identified with 'auth_socket'")
tk.MustExec("create user u3 identified with 'authentication_ldap_simple'")
tk.MustExec("create user u4 identified with 'authentication_ldap_sasl'")
tk.MustGetErrCode("create user u5 identified with 'mysql_native_password'", errno.ErrNotValidPassword)
tk.MustGetErrCode("create user u5 identified with 'caching_sha2_password'", errno.ErrNotValidPassword)
tk.MustGetErrCode("create user u5 identified with 'tidb_sm3_password'", errno.ErrNotValidPassword)
tk.MustGetErrCode("create user u5 identified with 'mysql_clear_password'", errno.ErrPluginIsNotLoaded)
tk.MustGetErrCode("create user u5 identified with 'tidb_session_token'", errno.ErrPluginIsNotLoaded)
}
2 changes: 1 addition & 1 deletion parser/mysql/errname.go
Expand Up @@ -845,7 +845,7 @@ var MySQLErrName = map[uint16]*ErrMessage{
ErrInnodbImport: Message("ALTER TABLE '%-.192s' IMPORT TABLESPACE failed with error %d : '%s'", nil),
ErrInnodbIndexCorrupt: Message("Index corrupt: %s", nil),
ErrInvalidYearColumnLength: Message("Supports only YEAR or YEAR(4) column", nil),
ErrNotValidPassword: Message("Your password does not satisfy the current policy requirements", nil),
ErrNotValidPassword: Message("Your password does not satisfy the current policy requirements (%s)", nil),
ErrMustChangePassword: Message("You must SET PASSWORD before executing this statement", nil),
ErrFkNoIndexChild: Message("Failed to add the foreign key constraint. Missing index for constraint '%s' in the foreign table '%s'", nil),
ErrForeignKeyNoIndexInParent: Message("Failed to add the foreign key constraint. Missing index for constraint '%s' in the referenced table '%s'", nil),
Expand Down
8 changes: 4 additions & 4 deletions util/password-validation/password_validation.go
Expand Up @@ -143,12 +143,12 @@ func ValidatePassword(sessionVars *variable.SessionVars, pwd string) error {
if warn, err := ValidateUserNameInPassword(pwd, sessionVars); err != nil {
return err
} else if len(warn) > 0 {
return variable.ErrNotValidPassword.GenWithStack(warn)
return variable.ErrNotValidPassword.GenWithStackByArgs(warn)
}
if warn, err := ValidatePasswordLowPolicy(pwd, &globalVars); err != nil {
return err
} else if len(warn) > 0 {
return variable.ErrNotValidPassword.GenWithStack(warn)
return variable.ErrNotValidPassword.GenWithStackByArgs(warn)
}
// LOW
if validatePolicy == "LOW" {
Expand All @@ -159,7 +159,7 @@ func ValidatePassword(sessionVars *variable.SessionVars, pwd string) error {
if warn, err := ValidatePasswordMediumPolicy(pwd, &globalVars); err != nil {
return err
} else if len(warn) > 0 {
return variable.ErrNotValidPassword.GenWithStack(warn)
return variable.ErrNotValidPassword.GenWithStackByArgs(warn)
}
if validatePolicy == "MEDIUM" {
return nil
Expand All @@ -169,7 +169,7 @@ func ValidatePassword(sessionVars *variable.SessionVars, pwd string) error {
if ok, err := ValidateDictionaryPassword(pwd, &globalVars); err != nil {
return err
} else if !ok {
return variable.ErrNotValidPassword.GenWithStack("Password contains word in the dictionary")
return variable.ErrNotValidPassword.GenWithStackByArgs("Password contains word in the dictionary")
}
return nil
}

0 comments on commit a98e98e

Please sign in to comment.