Skip to content

Commit

Permalink
planner: privilege check ANALYZE TABLE stmt (pingcap#8486)
Browse files Browse the repository at this point in the history
  • Loading branch information
morgo authored and AndrewDi committed Dec 28, 2018
1 parent ac84e81 commit fcd15f7
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
8 changes: 6 additions & 2 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ type PlanBuilder struct {
inUpdateStmt bool
// colMapper stores the column that must be pre-resolved.
colMapper map[*ast.ColumnNameExpr]int
// Collect the visit information for privilege check.
// visitInfo is used for privilege check.
visitInfo []visitInfo
tableHintInfo []tableHintInfo
optFlag uint64
Expand Down Expand Up @@ -275,7 +275,7 @@ func (b *PlanBuilder) buildSet(v *ast.SetStmt) (Plan, error) {
return p, nil
}

// Detect aggregate function or groupby clause.
// detectSelectAgg detects an aggregate function or GROUP BY clause.
func (b *PlanBuilder) detectSelectAgg(sel *ast.SelectStmt) bool {
if sel.GroupBy != nil {
return true
Expand Down Expand Up @@ -749,6 +749,10 @@ const (
)

func (b *PlanBuilder) buildAnalyze(as *ast.AnalyzeTableStmt) (Plan, error) {
for _, tbl := range as.TableNames {
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.InsertPriv, tbl.Schema.O, tbl.Name.O, "")
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SelectPriv, tbl.Schema.O, tbl.Name.O, "")
}
if as.MaxNumBuckets == 0 {
as.MaxNumBuckets = defaultMaxNumBuckets
} else {
Expand Down
37 changes: 37 additions & 0 deletions privilege/privileges/privileges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,43 @@ func (s *testPrivilegeSuite) TestUseDb(c *C) {

}

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

se := newSession(c, s.store, s.dbName)
// high privileged user
mustExec(c, se, "CREATE USER 'asuper'")
mustExec(c, se, "CREATE USER 'anobody'")
mustExec(c, se, "GRANT ALL ON *.* TO 'asuper'")
mustExec(c, se, "FLUSH PRIVILEGES")
mustExec(c, se, "CREATE DATABASE atest")
mustExec(c, se, "use atest")
mustExec(c, se, "CREATE TABLE t1 (a int)")

c.Assert(se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil), IsTrue)
mustExec(c, se, "analyze table mysql.user")
// low privileged user
c.Assert(se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil), IsTrue)
_, err := se.Execute(context.Background(), "analyze table t1")
c.Assert(err, NotNil) // fails

// try again after SELECT privilege granted
c.Assert(se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil), IsTrue)
mustExec(c, se, "GRANT SELECT ON atest.* TO 'anobody'")
mustExec(c, se, "FLUSH PRIVILEGES")
c.Assert(se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil), IsTrue)
_, err = se.Execute(context.Background(), "analyze table t1")
c.Assert(err, NotNil) // stll fails (only select)

// Add INSERT privilege and it should work.
c.Assert(se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil), IsTrue)
mustExec(c, se, "GRANT INSERT ON atest.* TO 'anobody'")
mustExec(c, se, "FLUSH PRIVILEGES")
c.Assert(se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil), IsTrue)
_, err = se.Execute(context.Background(), "analyze table t1")
c.Assert(err, IsNil)

}

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

// This test tests no privilege check for INFORMATION_SCHEMA database.
Expand Down

0 comments on commit fcd15f7

Please sign in to comment.