Skip to content

Commit

Permalink
*: kill one's own connection doesn't require SUPER privilege (#6954)
Browse files Browse the repository at this point in the history
`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.
  • Loading branch information
tiancaiamao authored and coocood committed Jul 5, 2018
1 parent 3914266 commit 7682a74
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 9 deletions.
8 changes: 6 additions & 2 deletions executor/executor_pkg_test.go
Expand Up @@ -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.
Expand Down
5 changes: 3 additions & 2 deletions executor/show_test.go
Expand Up @@ -417,8 +417,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.
Expand Down
15 changes: 14 additions & 1 deletion plan/planbuilder.go
Expand Up @@ -783,8 +783,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
}
Expand Down
7 changes: 4 additions & 3 deletions server/server.go
Expand Up @@ -321,14 +321,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
Expand Down
3 changes: 2 additions & 1 deletion util/processinfo.go
Expand Up @@ -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)
}

0 comments on commit 7682a74

Please sign in to comment.