Skip to content

Commit

Permalink
planner: recover table/schema only needs create and drop privilege (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Defined2014 authored Feb 10, 2023
1 parent caaf668 commit 0db6df7
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 4 deletions.
57 changes: 57 additions & 0 deletions executor/recover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down
36 changes: 33 additions & 3 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion sessiontxn/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ go_test(
"txn_rc_tso_optimize_test.go",
],
flaky = True,
race = "on",
shard_count = 50,
deps = [
":sessiontxn",
Expand Down

0 comments on commit 0db6df7

Please sign in to comment.