Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

executor/simple: prohibit setting a resource group to a role (#54525) #54551

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions errors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2856,6 +2856,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
'''

["server:1040"]
error = '''
Too many connections
Expand Down
1 change: 1 addition & 0 deletions pkg/errno/errcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,7 @@ const (
ErrResourceGroupQueryRunawayInterrupted = 8253
ErrResourceGroupQueryRunawayQuarantine = 8254
ErrResourceGroupInvalidBackgroundTaskName = 8255
ErrResourceGroupInvalidForRole = 8257

// TiKV/PD/TiFlash errors.
ErrPDServerTimeout = 9001
Expand Down
1 change: 1 addition & 0 deletions pkg/errno/errname.go
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,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
30 changes: 30 additions & 0 deletions pkg/executor/simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,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 @@ -1270,6 +1273,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)
sqlescape.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 @@ -1892,6 +1915,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
2 changes: 2 additions & 0 deletions pkg/infoschema/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ var (
ErrResourceGroupNotExists = dbterror.ClassSchema.NewStd(mysql.ErrResourceGroupNotExists)
// ErrResourceGroupInvalidBackgroundTaskName return for unknown resource group background task name.
ErrResourceGroupInvalidBackgroundTaskName = dbterror.ClassExecutor.NewStd(mysql.ErrResourceGroupInvalidBackgroundTaskName)
// 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
4 changes: 4 additions & 0 deletions tests/integrationtest/r/executor/simple.result
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,10 @@ ALTER USER `user1` RESOURCE GROUP `rg1`;
SELECT CURRENT_RESOURCE_GROUP();
CURRENT_RESOURCE_GROUP()
default
create role role_for_resource_group;
alter user role_for_resource_group resource group rg1;
Error 8257 (HY000): Cannot set resource group for a role
drop role role_for_resource_group;
SELECT CURRENT_RESOURCE_GROUP();
CURRENT_RESOURCE_GROUP()
rg1
Expand Down
5 changes: 5 additions & 0 deletions tests/integrationtest/t/executor/simple.test
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,11 @@ create user user1;
ALTER USER `user1` RESOURCE GROUP `rg1`;
SELECT CURRENT_RESOURCE_GROUP();

create role role_for_resource_group;
-- error 8257
alter user role_for_resource_group resource group rg1;
drop role role_for_resource_group;

connect(conn1, localhost, user1,,);
SELECT CURRENT_RESOURCE_GROUP();

Expand Down