Skip to content

Commit

Permalink
executor/simple: prohibit setting a resource group to a role (#54525) (
Browse files Browse the repository at this point in the history
…#54628)

close #54417, ref #54434
  • Loading branch information
ti-chi-bot authored Jul 15, 2024
1 parent 223032b commit e90a1ce
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 0 deletions.
1 change: 1 addition & 0 deletions errno/errcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,7 @@ const (
ErrResourceGroupSupportDisabled = 8250
ErrResourceGroupConfigUnavailable = 8251
ErrResourceGroupThrottled = 8252
ErrResourceGroupInvalidForRole = 8257

// TiKV/PD/TiFlash errors.
ErrPDServerTimeout = 9001
Expand Down
1 change: 1 addition & 0 deletions errno/errname.go
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,7 @@ var MySQLErrName = map[uint16]*mysql.ErrMessage{
ErrOptOnCacheTable: mysql.Message("'%s' is unsupported on cache tables.", nil),
ErrResourceGroupExists: mysql.Message("Resource group '%-.192s' already exists", nil),
ErrResourceGroupNotExists: mysql.Message("Unknown resource group '%-.192s'", nil),
ErrResourceGroupInvalidForRole: mysql.Message("Cannot set resource group for a role", nil),

ErrColumnInChange: mysql.Message("column %s id %d does not exist, this column may have been updated by other DDL ran in parallel", nil),
ErrResourceGroupSupportDisabled: mysql.Message("Resource control feature is disabled. Run `SET GLOBAL tidb_enable_resource_control='on'` to enable the feature", nil),
Expand Down
5 changes: 5 additions & 0 deletions errors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2696,6 +2696,11 @@ error = '''
Resource control feature is disabled. Run `SET GLOBAL tidb_enable_resource_control='on'` to enable the feature
'''

["schema:8257"]
error = '''
Cannot set resource group for a role
'''

["session:8002"]
error = '''
[%d] can not retry select for update statement
Expand Down
30 changes: 30 additions & 0 deletions executor/simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,9 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm
if !variable.EnableResourceControl.Load() {
return infoschema.ErrResourceGroupSupportDisabled
}
if s.IsCreateRole {
return infoschema.ErrResourceGroupInvalidForRole
}

resourceGroupName := strings.ToLower(s.ResourceGroupNameOption.Value)

Expand Down Expand Up @@ -1284,6 +1287,26 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm
return domain.GetDomain(e.ctx).NotifyUpdatePrivilege()
}

func isRole(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, name, host string) (bool, error) {
sql := new(strings.Builder)
sqlexec.MustFormatSQL(sql, `SELECT 1 FROM %n.%n WHERE User=%? AND Host=%? AND Account_locked="Y" AND Password_expired="Y";`,
mysql.SystemDB, mysql.UserTable, name, strings.ToLower(host))
recordSet, err := sqlExecutor.ExecuteInternal(ctx, sql.String())
if err != nil {
return false, err
}
defer func() {
if closeErr := recordSet.Close(); closeErr != nil {
err = closeErr
}
}()
rows, err := sqlexec.DrainRecordSet(ctx, recordSet, 1)
if err != nil {
return false, err
}
return len(rows) > 0, nil
}

func getUserPasswordLimit(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, name string, host string, plOptions *passwordOrLockOptionsInfo) (pRI *passwordReuseInfo, err error) {
res := &passwordReuseInfo{notSpecified, notSpecified}
sql := new(strings.Builder)
Expand Down Expand Up @@ -1906,6 +1929,13 @@ func (e *SimpleExec) executeAlterUser(ctx context.Context, s *ast.AlterUserStmt)
if !variable.EnableResourceControl.Load() {
return infoschema.ErrResourceGroupSupportDisabled
}
is, err := isRole(ctx, sqlExecutor, spec.User.Username, spec.User.Hostname)
if err != nil {
return err
}
if is {
return infoschema.ErrResourceGroupInvalidForRole
}

// check if specified resource group exists
resourceGroupName := strings.ToLower(s.ResourceGroupNameOption.Value)
Expand Down
5 changes: 5 additions & 0 deletions executor/simple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"testing"

"github.com/pingcap/tidb/config"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/parser/auth"
"github.com/pingcap/tidb/parser/mysql"
Expand Down Expand Up @@ -148,6 +149,10 @@ func TestSetResourceGroup(t *testing.T) {
require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil, nil))
tk.MustQuery("SELECT CURRENT_RESOURCE_GROUP()").Check(testkit.Rows("rg1"))

tk.MustExec("CREATE ROLE role_for_resource_group")
tk.MustGetDBError("ALTER USER role_for_resource_group RESOURCE GROUP `rg1`", infoschema.ErrResourceGroupInvalidForRole)
tk.MustExec("DROP ROLE role_for_resource_group")

tk.MustExec("CREATE RESOURCE GROUP rg2 ru_per_sec = 200")
tk.MustExec("SET RESOURCE GROUP `rg2`")
tk.MustQuery("SELECT CURRENT_RESOURCE_GROUP()").Check(testkit.Rows("rg2"))
Expand Down
2 changes: 2 additions & 0 deletions infoschema/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ var (
ErrResourceGroupExists = dbterror.ClassSchema.NewStd(mysql.ErrResourceGroupExists)
// ErrResourceGroupNotExists return for resource group not exists.
ErrResourceGroupNotExists = dbterror.ClassSchema.NewStd(mysql.ErrResourceGroupNotExists)
// ErrResourceGroupInvalidForRole return for invalid resource group for role.
ErrResourceGroupInvalidForRole = dbterror.ClassSchema.NewStd(mysql.ErrResourceGroupInvalidForRole)
// ErrReservedSyntax for internal syntax.
ErrReservedSyntax = dbterror.ClassSchema.NewStd(mysql.ErrReservedSyntax)
// ErrTableExists returns for table already exists.
Expand Down

0 comments on commit e90a1ce

Please sign in to comment.