Skip to content

Commit

Permalink
*: Support PLACEMENT_ADMIN dynamic priv (#27600)
Browse files Browse the repository at this point in the history
  • Loading branch information
sylzd authored Aug 31, 2021
1 parent aab723a commit 8fd6193
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 0 deletions.
1 change: 1 addition & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ func (s *testSuiteP1) TestShow(c *C) {
"SYSTEM_VARIABLES_ADMIN Server Admin ",
"ROLE_ADMIN Server Admin ",
"CONNECTION_ADMIN Server Admin ",
"PLACEMENT_ADMIN Server Admin ",
"DASHBOARD_CLIENT Server Admin ",
"RESTRICTED_TABLES_ADMIN Server Admin ",
"RESTRICTED_STATUS_ADMIN Server Admin ",
Expand Down
12 changes: 12 additions & 0 deletions planner/core/logical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1253,6 +1253,18 @@ func (s *testPlanSuite) TestVisitInfo(c *C) {
{mysql.ExtendedPriv, "", "", "", ErrSpecificAccessDenied, false, "SYSTEM_VARIABLES_ADMIN", false},
},
},
{
sql: "create placement policy x LEARNERS=1",
ans: []visitInfo{
{mysql.ExtendedPriv, "", "", "", ErrSpecificAccessDenied, false, "PLACEMENT_ADMIN", false},
},
},
{
sql: "drop placement policy if exists x",
ans: []visitInfo{
{mysql.ExtendedPriv, "", "", "", ErrSpecificAccessDenied, false, "PLACEMENT_ADMIN", false},
},
},
{
sql: "BACKUP DATABASE test TO 'local:///tmp/a'",
ans: []visitInfo{
Expand Down
3 changes: 3 additions & 0 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3809,6 +3809,9 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err
case *ast.RepairTableStmt:
// Repair table command can only be executed by administrator.
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "", nil)
case *ast.DropPlacementPolicyStmt, *ast.CreatePlacementPolicyStmt, *ast.AlterPlacementPolicyStmt:
err := ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or PLACEMENT_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "PLACEMENT_ADMIN", false, err)
}
p := &DDL{Statement: node}
return p, nil
Expand Down
1 change: 1 addition & 0 deletions privilege/privileges/privileges.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ var dynamicPrivs = []string{
"SYSTEM_VARIABLES_ADMIN",
"ROLE_ADMIN",
"CONNECTION_ADMIN",
"PLACEMENT_ADMIN", // Can Create/Drop/Alter PLACEMENT POLICY
"DASHBOARD_CLIENT", // Can login to the TiDB-Dashboard.
"RESTRICTED_TABLES_ADMIN", // Can see system tables when SEM is enabled
"RESTRICTED_STATUS_ADMIN", // Can see all status vars when SEM is enabled.
Expand Down
52 changes: 52 additions & 0 deletions privilege/privileges/privileges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2412,3 +2412,55 @@ func TestShowGrantsForCurrentUserUsingRole(t *testing.T) {
))

}

func TestGrantPlacementAdminDynamicPriv(t *testing.T) {
t.Parallel()
store, clean := newStore(t)
defer clean()

tk := testkit.NewTestKit(t, store)
tk.MustExec("CREATE DATABASE placement_db")
tk.MustExec("USE placement_db")
tk.MustExec("CREATE TABLE placement_table (a int)")
tk.MustExec("CREATE USER placement_user")
tk.MustExec("GRANT PLACEMENT_ADMIN ON *.* TO placement_user")
// Must set a session user to avoid null pointer dereferencing
tk.Session().Auth(&auth.UserIdentity{
Username: "root",
Hostname: "localhost",
}, nil, nil)
tk.MustQuery("SHOW GRANTS FOR placement_user").Check(testkit.Rows(
`GRANT USAGE ON *.* TO 'placement_user'@'%'`,
`GRANT PLACEMENT_ADMIN ON *.* TO 'placement_user'@'%'`))
tk.MustExec("DROP USER placement_user")
tk.MustExec("DROP DATABASE placement_db")
}

func TestPlacementPolicyStmt(t *testing.T) {
store, clean := newStore(t)
defer clean()
se := newSession(t, store, dbName)
mustExec(t, se, "drop placement policy if exists x")
createStmt := "create placement policy x PRIMARY_REGION=\"cn-east-1\" "
dropStmt := "drop placement policy if exists x"

// high privileged user setting password for other user (passes)
mustExec(t, se, "CREATE USER super_user, placement_user, empty_user")
mustExec(t, se, "GRANT ALL ON *.* TO super_user")
mustExec(t, se, "GRANT PLACEMENT_ADMIN ON *.* TO placement_user")

require.True(t, se.Auth(&auth.UserIdentity{Username: "empty_user", Hostname: "localhost"}, nil, nil))
_, err := se.ExecuteInternal(context.Background(), createStmt)
require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SUPER or PLACEMENT_ADMIN privilege(s) for this operation")
_, err = se.ExecuteInternal(context.Background(), dropStmt)
require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SUPER or PLACEMENT_ADMIN privilege(s) for this operation")

require.True(t, se.Auth(&auth.UserIdentity{Username: "super_user", Hostname: "localhost"}, nil, nil))
mustExec(t, se, createStmt)
mustExec(t, se, dropStmt)

require.True(t, se.Auth(&auth.UserIdentity{Username: "placement_user", Hostname: "localhost"}, nil, nil))
mustExec(t, se, createStmt)
mustExec(t, se, dropStmt)

}

0 comments on commit 8fd6193

Please sign in to comment.