Skip to content

Commit

Permalink
Fix changing the authplugin of a user
Browse files Browse the repository at this point in the history
- `ALTER USER`: fix changing the auth plugin of a user with `IDETIFIED
  WITH ...`
- `ALTER USER`: Check for invalid auth plugins
- `CREATE USER`: Check for invalid auth plugins
  • Loading branch information
dveeden committed Oct 25, 2021
1 parent 0ee0d6f commit 0da9f37
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 12 deletions.
2 changes: 1 addition & 1 deletion errno/errname.go
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ var MySQLErrName = map[uint16]*mysql.ErrMessage{
ErrFailedReadFromParFile: mysql.Message("Failed to read from the .par file", nil),
ErrValuesIsNotIntType: mysql.Message("VALUES value for partition '%-.64s' must have type INT", nil),
ErrAccessDeniedNoPassword: mysql.Message("Access denied for user '%-.48s'@'%-.255s'", nil),
ErrSetPasswordAuthPlugin: mysql.Message("SET PASSWORD has no significance for users authenticating via plugins", nil),
ErrSetPasswordAuthPlugin: mysql.Message("SET PASSWORD has no significance for user '%-.48s'@'%-.255s' as authentication plugin does not support it.", nil),
ErrGrantPluginUserExists: mysql.Message("GRANT with IDENTIFIED WITH is illegal because the user %-.*s already exists", nil),
ErrTruncateIllegalFk: mysql.Message("Cannot truncate a table referenced in a foreign key constraint (%.192s)", nil),
ErrPluginIsPermanent: mysql.Message("Plugin '%s' is forcePlusPermanent and can not be unloaded", nil),
Expand Down
10 changes: 10 additions & 0 deletions errors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -791,11 +791,21 @@ error = '''
You are not allowed to create a user with GRANT
'''

["executor:1524"]
error = '''
Plugin '%-.192s' is not loaded
'''

["executor:1568"]
error = '''
Transaction characteristics can't be changed while a transaction is in progress
'''

["executor:1699"]
error = '''
SET PASSWORD has no significance for user '%-.48s'@'%-.255s' as authentication plugin does not support it.
'''

["executor:1827"]
error = '''
The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function.
Expand Down
2 changes: 2 additions & 0 deletions executor/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ var (
ErrDataInConsistentExtraIndex = dbterror.ClassExecutor.NewStd(mysql.ErrDataInConsistentExtraIndex)
ErrDataInConsistentMisMatchIndex = dbterror.ClassExecutor.NewStd(mysql.ErrDataInConsistentMisMatchIndex)
ErrNotSupportedWithSem = dbterror.ClassOptimizer.NewStd(mysql.ErrNotSupportedWithSem)
ErrPluginIsNotLoaded = dbterror.ClassExecutor.NewStd(mysql.ErrPluginIsNotLoaded)
ErrSetPasswordAuthPlugin = dbterror.ClassExecutor.NewStd(mysql.ErrSetPasswordAuthPlugin)

errUnsupportedFlashbackTmpTable = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message("Recover/flashback table is not supported on temporary tables", nil))
errTruncateWrongInsertValue = dbterror.ClassTable.NewStdErr(mysql.ErrTruncatedWrongValue, parser_mysql.Message("Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %d", nil))
Expand Down
39 changes: 29 additions & 10 deletions executor/simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,13 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm
if spec.AuthOpt != nil && spec.AuthOpt.AuthPlugin != "" {
authPlugin = spec.AuthOpt.AuthPlugin
}

switch authPlugin {
case mysql.AuthNativePassword, mysql.AuthCachingSha2Password, mysql.AuthSocket:
default:
return ErrPluginIsNotLoaded.GenWithStackByArgs(spec.AuthOpt.AuthPlugin)
}

hostName := strings.ToLower(spec.User.Hostname)
if s.IsCreateRole {
sqlexec.MustFormatSQL(sql, `(%?, %?, %?, %?, %?)`, hostName, spec.User.Username, pwd, authPlugin, "Y")
Expand Down Expand Up @@ -917,20 +924,28 @@ func (e *SimpleExec) executeAlterUser(ctx context.Context, s *ast.AlterUserStmt)
continue
}

authplugin, err := e.userAuthPlugin(spec.User.Username, spec.User.Hostname)
if err != nil {
return err
}
if spec.AuthOpt != nil {
spec.AuthOpt.AuthPlugin = authplugin
}
exec := e.ctx.(sqlexec.RestrictedSQLExecutor)
if spec.AuthOpt != nil {
if spec.AuthOpt.AuthPlugin == "" {
authplugin, err := e.userAuthPlugin(spec.User.Username, spec.User.Hostname)
if err != nil {
return err
}
spec.AuthOpt.AuthPlugin = authplugin
}
switch spec.AuthOpt.AuthPlugin {
case mysql.AuthNativePassword, mysql.AuthCachingSha2Password, mysql.AuthSocket:
default:
return ErrPluginIsNotLoaded.GenWithStackByArgs(spec.AuthOpt.AuthPlugin)
}
pwd, ok := spec.EncodedPassword()
if !ok {
return errors.Trace(ErrPasswordFormat)
}
stmt, err := exec.ParseWithParams(ctx, `UPDATE %n.%n SET authentication_string=%? WHERE Host=%? and User=%?;`, mysql.SystemDB, mysql.UserTable, pwd, spec.User.Hostname, spec.User.Username)
stmt, err := exec.ParseWithParams(ctx,
`UPDATE %n.%n SET authentication_string=%?, plugin=%? WHERE Host=%? and User=%?;`,
mysql.SystemDB, mysql.UserTable, pwd, spec.AuthOpt.AuthPlugin, spec.User.Hostname, spec.User.Username,
)
if err != nil {
return err
}
Expand Down Expand Up @@ -1373,9 +1388,13 @@ func (e *SimpleExec) executeSetPwd(ctx context.Context, s *ast.SetPwdStmt) error
return err
}
var pwd string
if authplugin == mysql.AuthCachingSha2Password {
switch authplugin {
case mysql.AuthCachingSha2Password:
pwd = auth.NewSha2Password(s.Password)
} else {
case mysql.AuthSocket:
e.ctx.GetSessionVars().StmtCtx.AppendNote(ErrSetPasswordAuthPlugin.GenWithStackByArgs(u, h))
pwd = ""
default:
pwd = auth.EncodePassword(s.Password)
}

Expand Down
13 changes: 13 additions & 0 deletions executor/simple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,10 @@ func (s *testSuite7) TestUser(c *C) {
tk.MustGetErrCode(alterUserSQL, mysql.ErrCannotUser)
result = tk.MustQuery(`SELECT authentication_string FROM mysql.User WHERE User="test1" and Host="localhost"`)
result.Check(testkit.Rows(auth.EncodePassword("222")))
alterUserSQL = `ALTER USER 'test1'@'localhost' IDENTIFIED WITH 'auth_socket';`
tk.MustExec(alterUserSQL)
result = tk.MustQuery(`SELECT plugin FROM mysql.User WHERE User="test1" and Host="localhost"`)
result.Check(testkit.Rows("auth_socket"))

alterUserSQL = `ALTER USER IF EXISTS 'test2'@'localhost' IDENTIFIED BY '222', 'test_not_exist'@'localhost' IDENTIFIED BY '1';`
tk.MustExec(alterUserSQL)
Expand Down Expand Up @@ -496,6 +500,10 @@ func (s *testSuite7) TestUser(c *C) {
tk.MustExec(renameUserSQL)
querySQL = `select user,host from mysql.user where user = 'userD';`
tk.MustQuery(querySQL).Check(testkit.Rows("userD demo.com"))

createUserSQL = `create user foo@localhost identified with 'foobar';`
_, err = tk.Exec(createUserSQL)
c.Check(terror.ErrorEqual(err, executor.ErrPluginIsNotLoaded), IsTrue, Commentf("err %v", err))
}

func (s *testSuite3) TestSetPwd(c *C) {
Expand All @@ -511,6 +519,11 @@ func (s *testSuite3) TestSetPwd(c *C) {
result = tk.MustQuery(`SELECT authentication_string FROM mysql.User WHERE User="testpwd" and Host="localhost"`)
result.Check(testkit.Rows(auth.EncodePassword("password")))

tk.MustExec(`CREATE USER 'testpwdsock'@'localhost' IDENTIFIED WITH 'auth_socket';`)
tk.MustExec(`SET PASSWORD FOR 'testpwdsock'@'localhost' = 'password';`)
result = tk.MustQuery("show warnings")
result.Check(testkit.Rows("Note 1699 SET PASSWORD has no significance for user 'testpwdsock'@'localhost' as authentication plugin does not support it."))

// set password
setPwdSQL := `SET PASSWORD = 'pwd'`
// Session user is empty.
Expand Down
2 changes: 2 additions & 0 deletions parser/ast/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,8 @@ func (n *UserSpec) EncodedPassword() (string, bool) {
switch opt.AuthPlugin {
case mysql.AuthCachingSha2Password:
return auth.NewSha2Password(opt.AuthString), true
case mysql.AuthSocket:
return "", true
default:
return auth.EncodePassword(opt.AuthString), true
}
Expand Down
2 changes: 1 addition & 1 deletion parser/mysql/errname.go
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ var MySQLErrName = map[uint16]*ErrMessage{
ErrFailedReadFromParFile: Message("Failed to read from the .par file", nil),
ErrValuesIsNotIntType: Message("VALUES value for partition '%-.64s' must have type INT", nil),
ErrAccessDeniedNoPassword: Message("Access denied for user '%-.48s'@'%-.64s'", nil),
ErrSetPasswordAuthPlugin: Message("SET PASSWORD has no significance for users authenticating via plugins", nil),
ErrSetPasswordAuthPlugin: Message("SET PASSWORD has no significance for user '%-.48s'@'%-.255s' as authentication plugin does not support it.", nil),
ErrGrantPluginUserExists: Message("GRANT with IDENTIFIED WITH is illegal because the user %-.*s already exists", nil),
ErrTruncateIllegalFk: Message("Cannot truncate a table referenced in a foreign key constraint (%.192s)", nil),
ErrPluginIsPermanent: Message("Plugin '%s' is forcePlusPermanent and can not be unloaded", nil),
Expand Down

0 comments on commit 0da9f37

Please sign in to comment.