Skip to content

Commit

Permalink
executor,planner: Improve SET PASSWORD #8426 (#13805)
Browse files Browse the repository at this point in the history
  • Loading branch information
tiancaiamao authored and sre-bot committed Dec 11, 2019
1 parent 8d279ad commit 8b1d288
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 11 deletions.
2 changes: 2 additions & 0 deletions executor/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ var (
ErrPsManyParam = terror.ClassExecutor.New(mysql.ErrPsManyParam, mysql.MySQLErrName[mysql.ErrPsManyParam])
ErrAdminCheckTable = terror.ClassExecutor.New(mysql.ErrAdminCheckTable, mysql.MySQLErrName[mysql.ErrAdminCheckTable])
ErrQueryInterrupted = terror.ClassExecutor.New(mysql.ErrQueryInterrupted, mysql.MySQLErrName[mysql.ErrQueryInterrupted])
ErrDBaccessDenied = terror.ClassExecutor.New(mysql.ErrDBaccessDenied, mysql.MySQLErrName[mysql.ErrDBaccessDenied])
)

func init() {
Expand All @@ -59,6 +60,7 @@ func init() {
mysql.ErrPsManyParam: mysql.ErrPsManyParam,
mysql.ErrAdminCheckTable: mysql.ErrAdminCheckTable,
mysql.ErrQueryInterrupted: mysql.ErrQueryInterrupted,
mysql.ErrDBaccessDenied: mysql.ErrDBaccessDenied,
}
terror.ErrClassToMySQLCodes[terror.ClassExecutor] = tableMySQLErrCodes
}
19 changes: 14 additions & 5 deletions executor/simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/pingcap/tidb/domain"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/plugin"
"github.com/pingcap/tidb/privilege"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/util/chunk"
Expand Down Expand Up @@ -309,14 +310,22 @@ func userExists(ctx sessionctx.Context, name string, host string) (bool, error)
}

func (e *SimpleExec) executeSetPwd(s *ast.SetPwdStmt) error {
var u, h string
if s.User == nil {
vars := e.ctx.GetSessionVars()
s.User = vars.User
if s.User == nil {
if e.ctx.GetSessionVars().User == nil {
return errors.New("Session error is empty")
}
u = e.ctx.GetSessionVars().User.AuthUsername
h = e.ctx.GetSessionVars().User.AuthHostname
} else {
checker := privilege.GetPrivilegeManager(e.ctx)
if checker != nil && !checker.RequestVerification("", "", "", mysql.SuperPriv) {
return ErrDBaccessDenied.GenWithStackByArgs(u, h, "mysql")
}
u = s.User.Username
h = s.User.Hostname
}
exists, err := userExists(e.ctx, s.User.Username, s.User.Hostname)
exists, err := userExists(e.ctx, u, h)
if err != nil {
return errors.Trace(err)
}
Expand All @@ -325,7 +334,7 @@ func (e *SimpleExec) executeSetPwd(s *ast.SetPwdStmt) error {
}

// update mysql.user
sql := fmt.Sprintf(`UPDATE %s.%s SET password='%s' WHERE User='%s' AND Host='%s';`, mysql.SystemDB, mysql.UserTable, auth.EncodePassword(s.Password), s.User.Username, s.User.Hostname)
sql := fmt.Sprintf(`UPDATE %s.%s SET password="%s" WHERE User="%s" AND Host="%s";`, mysql.SystemDB, mysql.UserTable, auth.EncodePassword(s.Password), u, h)
_, _, err = e.ctx.(sqlexec.RestrictedSQLExecutor).ExecRestrictedSQL(e.ctx, sql)
domain.GetDomain(e.ctx).NotifyUpdatePrivilege(e.ctx)
return errors.Trace(err)
Expand Down
5 changes: 3 additions & 2 deletions executor/simple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,15 +223,16 @@ func (s *testSuite) TestSetPwd(c *C) {
tk.Se, err = session.CreateSession4Test(s.store)
c.Check(err, IsNil)
ctx := tk.Se.(sessionctx.Context)
ctx.GetSessionVars().User = &auth.UserIdentity{Username: "testpwd1", Hostname: "localhost"}
ctx.GetSessionVars().User = &auth.UserIdentity{Username: "testpwd1", Hostname: "localhost", AuthUsername: "testpwd1", AuthHostname: "localhost"}
// Session user doesn't exist.
_, err = tk.Exec(setPwdSQL)
c.Check(terror.ErrorEqual(err, executor.ErrPasswordNoMatch), IsTrue, Commentf("err %v", err))
// normal
ctx.GetSessionVars().User = &auth.UserIdentity{Username: "testpwd", Hostname: "localhost"}
ctx.GetSessionVars().User = &auth.UserIdentity{Username: "testpwd", Hostname: "localhost", AuthUsername: "testpwd", AuthHostname: "localhost"}
tk.MustExec(setPwdSQL)
result = tk.MustQuery(`SELECT Password FROM mysql.User WHERE User="testpwd" and Host="localhost"`)
result.Check(testkit.Rows(auth.EncodePassword("pwd")))

}

func (s *testSuite) TestKillStmt(c *C) {
Expand Down
4 changes: 1 addition & 3 deletions planner/core/logical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1760,9 +1760,7 @@ func (s *testPlanSuite) TestVisitInfo(c *C) {
},
{
sql: `set password for 'root'@'%' = 'xxxxx'`,
ans: []visitInfo{
{mysql.SuperPriv, "", "", ""},
},
ans: []visitInfo{},
},
{
sql: `show create table test.ttt`,
Expand Down
2 changes: 1 addition & 1 deletion planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1181,7 +1181,7 @@ func (b *planBuilder) buildSimple(node ast.StmtNode) Plan {
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.CreateUserPriv, "", "", "")
case *ast.GrantStmt:
b.visitInfo = collectVisitInfoFromGrantStmt(b.ctx, b.visitInfo, raw)
case *ast.SetPwdStmt, *ast.RevokeStmt:
case *ast.RevokeStmt:
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "")
case *ast.KillStmt:
// If you have the SUPER privilege, you can kill all threads and statements.
Expand Down
20 changes: 20 additions & 0 deletions privilege/privileges/privileges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,26 @@ func (s *testPrivilegeSuite) TestDropTablePriv(c *C) {
mustExec(c, se, `DROP TABLE todrop;`)
}

func (s *testPrivilegeSuite) TestSetPasswdStmt(c *C) {

se := newSession(c, s.store, s.dbName)

// high privileged user setting password for other user (passes)
mustExec(c, se, "CREATE USER 'superuser'")
mustExec(c, se, "CREATE USER 'nobodyuser'")
mustExec(c, se, "GRANT ALL ON *.* TO 'superuser'")
mustExec(c, se, "FLUSH PRIVILEGES")

// low privileged user trying to set password for other user (fails)
c.Assert(se.Auth(&auth.UserIdentity{Username: "nobodyuser", Hostname: "localhost", AuthUsername: "nobodyuser", AuthHostname: "%"}, nil, nil), IsTrue)
_, err := se.Execute(context.Background(), "SET PASSWORD for 'superuser' = 'newpassword'")
c.Assert(err, NotNil)

c.Assert(se.Auth(&auth.UserIdentity{Username: "superuser", Hostname: "localhost", AuthUsername: "superuser", AuthHostname: "%"}, nil, nil), IsTrue)
mustExec(c, se, "SET PASSWORD for 'nobodyuser' = 'newpassword'")

}

func (s *testPrivilegeSuite) TestCheckAuthenticate(c *C) {

se := newSession(c, s.store, s.dbName)
Expand Down

0 comments on commit 8b1d288

Please sign in to comment.