Skip to content

Commit

Permalink
executor: fix privilege check for 'show create user current_us… (#11229)
Browse files Browse the repository at this point in the history
  • Loading branch information
tiancaiamao authored and zz-jason committed Jul 15, 2019
1 parent ea59413 commit 36f9978
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
24 changes: 19 additions & 5 deletions executor/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type ShowExec struct {
IndexName model.CIStr // Used for show table regions.
Flag int // Some flag parsed from sql, such as FULL.
Full bool
User *auth.UserIdentity // Used for show grants.
User *auth.UserIdentity // Used by show grants, show create user.
Roles []*auth.RoleIdentity // Used for show grants.
IfNotExists bool // Used for `show create database if not exists`

Expand Down Expand Up @@ -946,8 +946,23 @@ func (e *ShowExec) fetchShowCreateUser() error {
if checker == nil {
return errors.New("miss privilege checker")
}

userName, hostName := e.User.Username, e.User.Hostname
sessVars := e.ctx.GetSessionVars()
if e.User.CurrentUser {
userName = sessVars.User.AuthUsername
hostName = sessVars.User.AuthHostname
} else {
// Show create user requires the SELECT privilege on mysql.user.
// Ref https://dev.mysql.com/doc/refman/5.7/en/show-create-user.html
activeRoles := sessVars.ActiveRoles
if !checker.RequestVerification(activeRoles, mysql.SystemDB, mysql.UserTable, "", mysql.SelectPriv) {
return e.tableAccessDenied("SELECT", mysql.UserTable)
}
}

sql := fmt.Sprintf(`SELECT * FROM %s.%s WHERE User='%s' AND Host='%s';`,
mysql.SystemDB, mysql.UserTable, e.User.Username, e.User.Hostname)
mysql.SystemDB, mysql.UserTable, userName, hostName)
rows, _, err := e.ctx.(sqlexec.RestrictedSQLExecutor).ExecRestrictedSQL(e.ctx, sql)
if err != nil {
return errors.Trace(err)
Expand All @@ -956,9 +971,8 @@ func (e *ShowExec) fetchShowCreateUser() error {
return ErrCannotUser.GenWithStackByArgs("SHOW CREATE USER",
fmt.Sprintf("'%s'@'%s'", e.User.Username, e.User.Hostname))
}
showStr := fmt.Sprintf("CREATE USER '%s'@'%s' IDENTIFIED WITH 'mysql_native_password' AS '%s' %s",
e.User.Username, e.User.Hostname, checker.GetEncodedPassword(e.User.Username, e.User.Hostname),
"REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK")
showStr := fmt.Sprintf("CREATE USER '%s'@'%s' IDENTIFIED WITH 'mysql_native_password' AS '%s' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK",
e.User.Username, e.User.Hostname, checker.GetEncodedPassword(e.User.Username, e.User.Hostname))
e.appendRow([]interface{}{showStr})
return nil
}
Expand Down
23 changes: 22 additions & 1 deletion executor/show_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ func (s *testSuite2) TestShow2(c *C) {
tk.MustQuery("show grants for current_user").Check(testkit.Rows(`GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'`))
}

func (s *testSuite2) TestShow3(c *C) {
func (s *testSuite2) TestShowCreateUser(c *C) {
tk := testkit.NewTestKit(c, s.store)
// Create a new user.
tk.MustExec(`CREATE USER 'test_show_create_user'@'%' IDENTIFIED BY 'root';`)
Expand All @@ -296,6 +296,27 @@ func (s *testSuite2) TestShow3(c *C) {
// Case: a user that doesn't exist
err = tk.QueryToErr("show create user 'aaa'@'localhost';")
c.Assert(err.Error(), Equals, executor.ErrCannotUser.GenWithStackByArgs("SHOW CREATE USER", "'aaa'@'localhost'").Error())

tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "127.0.0.1", AuthUsername: "root", AuthHostname: "%"}, nil, nil)
rows := tk.MustQuery("show create user current_user")
rows.Check(testkit.Rows("CREATE USER 'root'@'127.0.0.1' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK"))

rows = tk.MustQuery("show create user current_user()")
rows.Check(testkit.Rows("CREATE USER 'root'@'127.0.0.1' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK"))

tk.MustExec("create user 'check_priv'")

// "show create user" for other user requires the SELECT privilege on mysql database.
tk1 := testkit.NewTestKit(c, s.store)
tk1.MustExec("use mysql")
succ := tk1.Se.Auth(&auth.UserIdentity{Username: "check_priv", Hostname: "127.0.0.1", AuthUsername: "test_show", AuthHostname: "asdf"}, nil, nil)
c.Assert(succ, IsTrue)
err = tk1.QueryToErr("show create user 'root'@'%'")
c.Assert(err, NotNil)

// "show create user" for current user doesn't check privileges.
rows = tk1.MustQuery("show create user current_user")
rows.Check(testkit.Rows("CREATE USER 'check_priv'@'127.0.0.1' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK"))
}

func (s *testSuite2) TestUnprivilegedShow(c *C) {
Expand Down

0 comments on commit 36f9978

Please sign in to comment.