Skip to content

Commit

Permalink
executor, privileges: fix infoschema.user_privileges privilege requir…
Browse files Browse the repository at this point in the history
…ements
  • Loading branch information
morgo committed Jul 8, 2021
1 parent 560a3f7 commit d4cb1d4
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 12 deletions.
3 changes: 2 additions & 1 deletion executor/infoschema_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -1255,7 +1255,8 @@ func (e *memtableRetriever) setDataForProcessList(ctx sessionctx.Context) {

func (e *memtableRetriever) setDataFromUserPrivileges(ctx sessionctx.Context) {
pm := privilege.GetPrivilegeManager(ctx)
e.rows = pm.UserPrivilegesTable()
// The results depend on the user querying the information.
e.rows = pm.UserPrivilegesTable(ctx.GetSessionVars().ActiveRoles, ctx.GetSessionVars().User.Username, ctx.GetSessionVars().User.Hostname)
}

func (e *memtableRetriever) setDataForMetricTables(ctx sessionctx.Context) {
Expand Down
12 changes: 9 additions & 3 deletions executor/infoschema_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,17 +395,23 @@ func (s *testInfoschemaTableSuite) TestUserPrivileges(c *C) {

func (s *testInfoschemaTableSuite) TestUserPrivilegesTable(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk1 := testkit.NewTestKit(c, s.store)

// test the privilege of new user for information_schema.user_privileges
tk.MustExec("create user usageuser")
c.Assert(tk.Se.Auth(&auth.UserIdentity{
Username: "usageuser",
Hostname: "127.0.0.1",
}, nil, nil), IsTrue)
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee="'usageuser'@'%'"`).Check(testkit.Rows("'usageuser'@'%' def USAGE NO"))
// the usage row disappears when there is a non-dynamic privilege added
tk.MustExec("GRANT SELECT ON *.* to usageuser")
tk1.MustExec("GRANT SELECT ON *.* to usageuser")
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee="'usageuser'@'%'"`).Check(testkit.Rows("'usageuser'@'%' def Select NO"))
// test grant privilege
tk.MustExec("GRANT SELECT ON *.* to usageuser WITH GRANT OPTION")
tk1.MustExec("GRANT SELECT ON *.* to usageuser WITH GRANT OPTION")
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee="'usageuser'@'%'"`).Check(testkit.Rows("'usageuser'@'%' def Select YES"))
// test DYNAMIC privs
tk.MustExec("GRANT BACKUP_ADMIN ON *.* to usageuser")
tk1.MustExec("GRANT BACKUP_ADMIN ON *.* to usageuser")
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee="'usageuser'@'%'" ORDER BY privilege_type`).Check(testkit.Rows("'usageuser'@'%' def BACKUP_ADMIN NO", "'usageuser'@'%' def Select YES"))
}

Expand Down
2 changes: 1 addition & 1 deletion privilege/privilege.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type Manager interface {
DBIsVisible(activeRole []*auth.RoleIdentity, db string) bool

// UserPrivilegesTable provide data for INFORMATION_SCHEMA.USER_PRIVILEGES table.
UserPrivilegesTable() [][]types.Datum
UserPrivilegesTable(activeRoles []*auth.RoleIdentity, user, host string) [][]types.Datum

// ActiveRoles active roles for current session.
// The first illegal role will be returned.
Expand Down
18 changes: 13 additions & 5 deletions privilege/privileges/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -1420,15 +1420,23 @@ func privToString(priv mysql.PrivilegeType, allPrivs []mysql.PrivilegeType, allP
return strings.Join(pstrs, ",")
}

// UserPrivilegesTable provide data for INFORMATION_SCHEMA.USERS_PRIVILEGE table.
func (p *MySQLPrivilege) UserPrivilegesTable() [][]types.Datum {
// UserPrivilegesTable provide data for INFORMATION_SCHEMA.USERS_PRIVILEGES table.
func (p *MySQLPrivilege) UserPrivilegesTable(activeRoles []*auth.RoleIdentity, user, host string) [][]types.Datum {
// Seeing all users requires SELECT ON * FROM mysql.user
// The SUPER privilege (or any other dynamic privilege) doesn't help here.
// This is verified against MySQL.
showOtherUsers := p.RequestVerification(activeRoles, user, host, mysql.SystemDB, mysql.UserTable, "", mysql.SelectPriv)
var rows [][]types.Datum
for _, user := range p.User {
rows = appendUserPrivilegesTableRow(rows, user)
for _, u := range p.User {
if showOtherUsers || u.match(user, host) {
rows = appendUserPrivilegesTableRow(rows, u)
}
}
for _, dynamicPrivs := range p.Dynamic {
for _, dynamicPriv := range dynamicPrivs {
rows = appendDynamicPrivRecord(rows, dynamicPriv)
if showOtherUsers || dynamicPriv.match(user, host) {
rows = appendDynamicPrivRecord(rows, dynamicPriv)
}
}
}
return rows
Expand Down
4 changes: 2 additions & 2 deletions privilege/privileges/privileges.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,9 @@ func (p *UserPrivileges) DBIsVisible(activeRoles []*auth.RoleIdentity, db string
}

// UserPrivilegesTable implements the Manager interface.
func (p *UserPrivileges) UserPrivilegesTable() [][]types.Datum {
func (p *UserPrivileges) UserPrivilegesTable(activeRoles []*auth.RoleIdentity, user, host string) [][]types.Datum {
mysqlPriv := p.Handle.Get()
return mysqlPriv.UserPrivilegesTable()
return mysqlPriv.UserPrivilegesTable(activeRoles, user, host)
}

// ShowGrants implements privilege.Manager ShowGrants interface.
Expand Down
46 changes: 46 additions & 0 deletions privilege/privileges/privileges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1729,3 +1729,49 @@ func (s *testPrivilegeSuite) TestDynamicPrivsRegistration(c *C) {
tk.MustExec(sqlGrant)
}
}

func (s *testPrivilegeSuite) TestInfoschemaUserPrivileges(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("CREATE USER isnobody, isroot, isselectonmysqluser")
tk.MustExec("GRANT SUPER ON *.* TO isroot")
tk.MustExec("GRANT SELECT ON mysql.user TO isselectonmysqluser")

// First as Nobody
tk.Se.Auth(&auth.UserIdentity{
Username: "isnobody",
Hostname: "localhost",
AuthUsername: "isnobody",
AuthHostname: "%",
}, nil, nil)

// I can see myself, but I can not see other users
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isnobody'@'%'"`).Check(testkit.Rows("'isnobody'@'%' def USAGE NO"))
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isroot'@'%'"`).Check(testkit.Rows())
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isselectonmysqluser'@'%'"`).Check(testkit.Rows())

// Now as root
tk.Se.Auth(&auth.UserIdentity{
Username: "isroot",
Hostname: "localhost",
AuthUsername: "isroot",
AuthHostname: "%",
}, nil, nil)

// I can see myself, but I can not see other users
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isnobody'@'%'"`).Check(testkit.Rows())
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isroot'@'%'"`).Check(testkit.Rows("'isroot'@'%' def Super NO"))
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isselectonmysqluser'@'%'"`).Check(testkit.Rows())

// Now as isselectonmysqluser
tk.Se.Auth(&auth.UserIdentity{
Username: "isselectonmysqluser",
Hostname: "localhost",
AuthUsername: "isselectonmysqluser",
AuthHostname: "%",
}, nil, nil)

// Now as isselectonmysqluser
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isnobody'@'%'"`).Check(testkit.Rows("'isnobody'@'%' def USAGE NO"))
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isroot'@'%'"`).Check(testkit.Rows("'isroot'@'%' def Super NO"))
tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isselectonmysqluser'@'%'"`).Check(testkit.Rows("'isselectonmysqluser'@'%' def USAGE NO"))
}

0 comments on commit d4cb1d4

Please sign in to comment.