Skip to content

Commit

Permalink
privilege: fix privilege check of CREATE ROLE and DROP ROLE (#13940)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lingyu Song authored and sre-bot committed Dec 11, 2019
1 parent 641963e commit 7c17add
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 4 deletions.
17 changes: 13 additions & 4 deletions executor/simple.go
Expand Up @@ -647,8 +647,11 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm
}
activeRoles := e.ctx.GetSessionVars().ActiveRoles
if !checker.RequestVerification(activeRoles, mysql.SystemDB, mysql.UserTable, "", mysql.InsertPriv) {
if s.IsCreateRole && !checker.RequestVerification(activeRoles, "", "", "", mysql.CreateRolePriv) {
return core.ErrSpecificAccessDenied.GenWithStackByArgs("CREATE ROLE")
if s.IsCreateRole {
if !checker.RequestVerification(activeRoles, "", "", "", mysql.CreateRolePriv) &&
!checker.RequestVerification(activeRoles, "", "", "", mysql.CreateUserPriv) {
return core.ErrSpecificAccessDenied.GenWithStackByArgs("CREATE ROLE or CREATE USER")
}
}
if !s.IsCreateRole && !checker.RequestVerification(activeRoles, "", "", "", mysql.CreateUserPriv) {
return core.ErrSpecificAccessDenied.GenWithStackByArgs("CREATE User")
Expand All @@ -665,6 +668,9 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm
if exists {
user := fmt.Sprintf(`'%s'@'%s'`, spec.User.Username, spec.User.Hostname)
if !s.IfNotExists {
if s.IsCreateRole {
return ErrCannotUser.GenWithStackByArgs("CREATE ROLE", user)
}
return ErrCannotUser.GenWithStackByArgs("CREATE USER", user)
}
err := infoschema.ErrUserAlreadyExists.GenWithStackByArgs(user)
Expand Down Expand Up @@ -827,8 +833,11 @@ func (e *SimpleExec) executeDropUser(s *ast.DropUserStmt) error {
}
activeRoles := e.ctx.GetSessionVars().ActiveRoles
if !checker.RequestVerification(activeRoles, mysql.SystemDB, mysql.UserTable, "", mysql.DeletePriv) {
if s.IsDropRole && !checker.RequestVerification(activeRoles, "", "", "", mysql.DropRolePriv) {
return core.ErrSpecificAccessDenied.GenWithStackByArgs("DROP ROLE")
if s.IsDropRole {
if !checker.RequestVerification(activeRoles, "", "", "", mysql.DropRolePriv) &&
!checker.RequestVerification(activeRoles, "", "", "", mysql.CreateUserPriv) {
return core.ErrSpecificAccessDenied.GenWithStackByArgs("DROP ROLE or CREATE USER")
}
}
if !s.IsDropRole && !checker.RequestVerification(activeRoles, "", "", "", mysql.CreateUserPriv) {
return core.ErrSpecificAccessDenied.GenWithStackByArgs("CREATE USER")
Expand Down
48 changes: 48 additions & 0 deletions executor/simple_test.go
Expand Up @@ -59,6 +59,54 @@ func (s *testSuite3) TestDo(c *C) {
tk.MustQuery("select @a").Check(testkit.Rows("1"))
}

func (s *testSuite3) TestCreateRole(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("create user testCreateRole;")
tk.MustExec("grant CREATE USER on *.* to testCreateRole;")
se, err := session.CreateSession4Test(s.store)
c.Check(err, IsNil)
defer se.Close()
c.Assert(se.Auth(&auth.UserIdentity{Username: "testCreateRole", Hostname: "localhost"}, nil, nil), IsTrue)

ctx := context.Background()
_, err = se.Execute(ctx, `create role test_create_role;`)
c.Assert(err, IsNil)
tk.MustExec("revoke CREATE USER on *.* from testCreateRole;")
tk.MustExec("drop role test_create_role;")
tk.MustExec("grant CREATE ROLE on *.* to testCreateRole;")
_, err = se.Execute(ctx, `create role test_create_role;`)
c.Assert(err, IsNil)
tk.MustExec("drop role test_create_role;")
_, err = se.Execute(ctx, `create user test_create_role;`)
c.Assert(err, NotNil)
tk.MustExec("drop user testCreateRole;")
}

func (s *testSuite3) TestDropRole(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("create user testCreateRole;")
tk.MustExec("create user test_create_role;")
tk.MustExec("grant CREATE USER on *.* to testCreateRole;")
se, err := session.CreateSession4Test(s.store)
c.Check(err, IsNil)
defer se.Close()
c.Assert(se.Auth(&auth.UserIdentity{Username: "testCreateRole", Hostname: "localhost"}, nil, nil), IsTrue)

ctx := context.Background()
_, err = se.Execute(ctx, `drop role test_create_role;`)
c.Assert(err, IsNil)
tk.MustExec("revoke CREATE USER on *.* from testCreateRole;")
tk.MustExec("create role test_create_role;")
tk.MustExec("grant DROP ROLE on *.* to testCreateRole;")
_, err = se.Execute(ctx, `drop role test_create_role;`)
c.Assert(err, IsNil)
tk.MustExec("create user test_create_role;")
_, err = se.Execute(ctx, `drop user test_create_role;`)
c.Assert(err, NotNil)
tk.MustExec("drop user testCreateRole;")
tk.MustExec("drop user test_create_role;")
}

func (s *testSuite3) TestTransaction(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("begin")
Expand Down

0 comments on commit 7c17add

Please sign in to comment.