From 1101329c5be445f4cfc5fb19b742ef1dd977c8db Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Thu, 5 Jul 2018 20:17:17 +0800 Subject: [PATCH 1/2] *: kill one's own connection doesn't require SUPER privilege (#6954) `kill tidb connID`, if the user is the owner of that connection, there is no need to check the SUPER privilege. SessionManager interface is slightly modified. --- executor/executor_pkg_test.go | 8 ++++++-- executor/show_test.go | 5 +++-- plan/planbuilder.go | 15 ++++++++++++++- server/server.go | 7 ++++--- util/processinfo.go | 3 ++- 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/executor/executor_pkg_test.go b/executor/executor_pkg_test.go index b9db2635f88f9..f790b42b946e2 100644 --- a/executor/executor_pkg_test.go +++ b/executor/executor_pkg_test.go @@ -41,8 +41,12 @@ type mockSessionManager struct { } // ShowProcessList implements the SessionManager.ShowProcessList interface. -func (msm *mockSessionManager) ShowProcessList() []util.ProcessInfo { - return msm.PS +func (msm *mockSessionManager) ShowProcessList() map[uint64]util.ProcessInfo { + ret := make(map[uint64]util.ProcessInfo) + for _, item := range msm.PS { + ret[item.ID] = item + } + return ret } // Kill implements the SessionManager.Kill interface. diff --git a/executor/show_test.go b/executor/show_test.go index 8ee7e5a208547..65fb85d987a97 100644 --- a/executor/show_test.go +++ b/executor/show_test.go @@ -386,8 +386,9 @@ type mockSessionManager struct { } // ShowProcessList implements the SessionManager.ShowProcessList interface. -func (msm *mockSessionManager) ShowProcessList() []util.ProcessInfo { - return []util.ProcessInfo{msm.ShowProcess()} +func (msm *mockSessionManager) ShowProcessList() map[uint64]util.ProcessInfo { + ps := msm.ShowProcess() + return map[uint64]util.ProcessInfo{ps.ID: ps} } // Kill implements the SessionManager.Kill interface. diff --git a/plan/planbuilder.go b/plan/planbuilder.go index d08aa5952454e..4216159caf6fd 100644 --- a/plan/planbuilder.go +++ b/plan/planbuilder.go @@ -773,8 +773,21 @@ func (b *planBuilder) buildSimple(node ast.StmtNode) Plan { b.visitInfo = appendVisitInfo(b.visitInfo, mysql.CreateUserPriv, "", "", "") case *ast.GrantStmt: b.visitInfo = collectVisitInfoFromGrantStmt(b.visitInfo, raw) - case *ast.SetPwdStmt, *ast.RevokeStmt, *ast.KillStmt: + case *ast.SetPwdStmt, *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. + // Otherwise, you can kill only your own threads and statements. + sm := b.ctx.GetSessionManager() + if sm != nil { + processList := sm.ShowProcessList() + if pi, ok := processList[raw.ConnectionID]; ok { + loginUser := b.ctx.GetSessionVars().User + if pi.User != loginUser.Username { + b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "") + } + } + } } return p } diff --git a/server/server.go b/server/server.go index 13005e25efc04..4c6db343ff512 100644 --- a/server/server.go +++ b/server/server.go @@ -314,14 +314,15 @@ func (s *Server) onConn(c net.Conn) { } // ShowProcessList implements the SessionManager interface. -func (s *Server) ShowProcessList() []util.ProcessInfo { - var rs []util.ProcessInfo +func (s *Server) ShowProcessList() map[uint64]util.ProcessInfo { s.rwlock.RLock() + rs := make(map[uint64]util.ProcessInfo, len(s.clients)) for _, client := range s.clients { if atomic.LoadInt32(&client.status) == connStatusWaitShutdown { continue } - rs = append(rs, client.ctx.ShowProcess()) + pi := client.ctx.ShowProcess() + rs[pi.ID] = pi } s.rwlock.RUnlock() return rs diff --git a/util/processinfo.go b/util/processinfo.go index 2d204c8a2a5c5..9c43d0573e856 100644 --- a/util/processinfo.go +++ b/util/processinfo.go @@ -33,6 +33,7 @@ type ProcessInfo struct { // SessionManager is an interface for session manage. Show processlist and // kill statement rely on this interface. type SessionManager interface { - ShowProcessList() []ProcessInfo + // ShowProcessList returns map[connectionID]ProcessInfo + ShowProcessList() map[uint64]ProcessInfo Kill(connectionID uint64, query bool) } From b6d81cb1b5995117227904990e747018ce3b8c7e Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Fri, 6 Jul 2018 12:19:58 +0800 Subject: [PATCH 2/2] address comment --- util/processinfo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/processinfo.go b/util/processinfo.go index 9c43d0573e856..0c497aab22974 100644 --- a/util/processinfo.go +++ b/util/processinfo.go @@ -33,7 +33,7 @@ type ProcessInfo struct { // SessionManager is an interface for session manage. Show processlist and // kill statement rely on this interface. type SessionManager interface { - // ShowProcessList returns map[connectionID]ProcessInfo + // ShowProcessList returns map[connectionID]ProcessInfo. ShowProcessList() map[uint64]ProcessInfo Kill(connectionID uint64, query bool) }