planner: recover table/schema only needs create and drop privilege (#41226)
close pingcap/tidb#40633
This commit is contained in:
@ -296,6 +296,43 @@ func TestRecoverTableMeetError(t *testing.T) {
|
||||
tk.MustContainErrMsg("select * from t_recover", "Table 'test_recover.t_recover' doesn't exist")
|
||||
}
|
||||
|
||||
func TestRecoverTablePrivilege(t *testing.T) {
|
||||
store := testkit.CreateMockStore(t)
|
||||
tk := testkit.NewTestKit(t, store)
|
||||
|
||||
timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk)
|
||||
defer resetGC()
|
||||
|
||||
// Set GC safe point
|
||||
tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop))
|
||||
|
||||
tk.MustExec("use test")
|
||||
tk.MustExec("drop table if exists t_recover")
|
||||
tk.MustExec("create table t_recover (a int);")
|
||||
tk.MustExec("drop table t_recover")
|
||||
|
||||
// Recover without drop/create privilege.
|
||||
tk.MustExec("CREATE USER 'testrecovertable'@'localhost';")
|
||||
newTk := testkit.NewTestKit(t, store)
|
||||
require.NoError(t, newTk.Session().Auth(&auth.UserIdentity{Username: "testrecovertable", Hostname: "localhost"}, nil, nil))
|
||||
newTk.MustGetErrCode("recover table t_recover", errno.ErrTableaccessDenied)
|
||||
newTk.MustGetErrCode("flashback table t_recover", errno.ErrTableaccessDenied)
|
||||
|
||||
// Got drop privilege, still failed.
|
||||
tk.MustExec("grant drop on *.* to 'testrecovertable'@'localhost';")
|
||||
newTk.MustGetErrCode("recover table t_recover", errno.ErrTableaccessDenied)
|
||||
newTk.MustGetErrCode("flashback table t_recover", errno.ErrTableaccessDenied)
|
||||
|
||||
// Got select, create and drop privilege, execute success.
|
||||
tk.MustExec("grant select,create on *.* to 'testrecovertable'@'localhost';")
|
||||
newTk.MustExec("use test")
|
||||
newTk.MustExec("recover table t_recover")
|
||||
newTk.MustExec("drop table t_recover")
|
||||
newTk.MustExec("flashback table t_recover")
|
||||
|
||||
tk.MustExec("drop user 'testrecovertable'@'localhost';")
|
||||
}
|
||||
|
||||
func TestRecoverClusterMeetError(t *testing.T) {
|
||||
store := testkit.CreateMockStore(t)
|
||||
tk := testkit.NewTestKit(t, store)
|
||||
@ -499,6 +536,26 @@ func TestFlashbackSchema(t *testing.T) {
|
||||
tk.MustExec("use test2")
|
||||
tk.MustQuery("select a from t order by a").Check(testkit.Rows("1", "2", "3"))
|
||||
tk.MustQuery("select a from t1 order by a").Check(testkit.Rows("4", "5", "6"))
|
||||
|
||||
tk.MustExec("drop database if exists t_recover")
|
||||
tk.MustExec("create database t_recover")
|
||||
tk.MustExec("drop database t_recover")
|
||||
|
||||
// Recover without drop/create privilege.
|
||||
tk.MustExec("CREATE USER 'testflashbackschema'@'localhost';")
|
||||
newTk := testkit.NewTestKit(t, store)
|
||||
require.NoError(t, newTk.Session().Auth(&auth.UserIdentity{Username: "testflashbackschema", Hostname: "localhost"}, nil, nil))
|
||||
newTk.MustGetErrCode("flashback database t_recover", errno.ErrDBaccessDenied)
|
||||
|
||||
// Got drop privilege, still failed.
|
||||
tk.MustExec("grant drop on *.* to 'testflashbackschema'@'localhost';")
|
||||
newTk.MustGetErrCode("flashback database t_recover", errno.ErrDBaccessDenied)
|
||||
|
||||
// Got create and drop privilege, execute success.
|
||||
tk.MustExec("grant create on *.* to 'testflashbackschema'@'localhost';")
|
||||
newTk.MustExec("flashback schema t_recover")
|
||||
|
||||
tk.MustExec("drop user 'testflashbackschema'@'localhost';")
|
||||
}
|
||||
|
||||
// MockGC is used to make GC work in the test environment.
|
||||
|
||||
@ -4727,9 +4727,39 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err
|
||||
}
|
||||
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.InsertPriv, v.TableToTables[0].NewTable.Schema.L,
|
||||
v.TableToTables[0].NewTable.Name.L, "", authErr)
|
||||
case *ast.RecoverTableStmt, *ast.FlashBackTableStmt, *ast.FlashBackDatabaseStmt:
|
||||
// Recover table command can only be executed by administrator.
|
||||
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "", nil)
|
||||
case *ast.RecoverTableStmt:
|
||||
if v.Table == nil {
|
||||
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "", nil)
|
||||
} else {
|
||||
if b.ctx.GetSessionVars().User != nil {
|
||||
authErr = ErrTableaccessDenied.GenWithStackByArgs("CREATE", b.ctx.GetSessionVars().User.AuthUsername,
|
||||
b.ctx.GetSessionVars().User.AuthHostname, v.Table.Name.L)
|
||||
}
|
||||
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.CreatePriv, v.Table.Schema.L, v.Table.Name.L, "", authErr)
|
||||
if b.ctx.GetSessionVars().User != nil {
|
||||
authErr = ErrTableaccessDenied.GenWithStackByArgs("DROP", b.ctx.GetSessionVars().User.AuthUsername,
|
||||
b.ctx.GetSessionVars().User.AuthHostname, v.Table.Name.L)
|
||||
}
|
||||
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.DropPriv, v.Table.Schema.L, v.Table.Name.L, "", authErr)
|
||||
}
|
||||
case *ast.FlashBackTableStmt:
|
||||
if b.ctx.GetSessionVars().User != nil {
|
||||
authErr = ErrTableaccessDenied.GenWithStackByArgs("CREATE", b.ctx.GetSessionVars().User.AuthUsername,
|
||||
b.ctx.GetSessionVars().User.AuthHostname, v.Table.Name.L)
|
||||
}
|
||||
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.CreatePriv, v.Table.Schema.L, v.Table.Name.L, "", authErr)
|
||||
if b.ctx.GetSessionVars().User != nil {
|
||||
authErr = ErrTableaccessDenied.GenWithStackByArgs("DROP", b.ctx.GetSessionVars().User.AuthUsername,
|
||||
b.ctx.GetSessionVars().User.AuthHostname, v.Table.Name.L)
|
||||
}
|
||||
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.DropPriv, v.Table.Schema.L, v.Table.Name.L, "", authErr)
|
||||
case *ast.FlashBackDatabaseStmt:
|
||||
if b.ctx.GetSessionVars().User != nil {
|
||||
authErr = ErrDBaccessDenied.GenWithStackByArgs(b.ctx.GetSessionVars().User.AuthUsername,
|
||||
b.ctx.GetSessionVars().User.AuthHostname, v.DBName.L)
|
||||
}
|
||||
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.CreatePriv, v.DBName.L, "", "", authErr)
|
||||
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.DropPriv, v.DBName.L, "", "", authErr)
|
||||
case *ast.FlashBackToTimestampStmt:
|
||||
// Flashback cluster can only be executed by user with `super` privilege.
|
||||
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "", nil)
|
||||
|
||||
@ -27,7 +27,6 @@ go_test(
|
||||
"txn_rc_tso_optimize_test.go",
|
||||
],
|
||||
flaky = True,
|
||||
race = "on",
|
||||
shard_count = 50,
|
||||
deps = [
|
||||
":sessiontxn",
|
||||
|
||||
Reference in New Issue
Block a user