Skip to content

Commit

Permalink
*: check privilege for 'show create table' and infoschema tables (pin…
Browse files Browse the repository at this point in the history
…gcap#6426)

1. 'show create table xxx' require privilege for the table
2. 'select * from information_schema.tables' should only returns data visible to user
  • Loading branch information
tiancaiamao authored May 3, 2018
1 parent 0fda3b4 commit bab4993
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 3 deletions.
16 changes: 14 additions & 2 deletions infoschema/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,8 @@ func dataForTables(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.D
return nil, errors.Trace(err)
}

checker := privilege.GetPrivilegeManager(ctx)

var rows [][]types.Datum
createTimeTp := tablesCols[15].tp
for _, schema := range schemas {
Expand All @@ -668,6 +670,11 @@ func dataForTables(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.D
Time: types.FromGoTime(table.GetUpdateTime()),
Type: createTimeTp,
}

if checker != nil && !checker.RequestVerification(schema.Name.L, table.Name.L, "", mysql.AllPrivMask) {
continue
}

record := types.MakeDatums(
catalogVal, // TABLE_CATALOG
schema.Name.O, // TABLE_SCHEMA
Expand Down Expand Up @@ -697,10 +704,15 @@ func dataForTables(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.D
return rows, nil
}

func dataForColumns(schemas []*model.DBInfo) [][]types.Datum {
func dataForColumns(ctx sessionctx.Context, schemas []*model.DBInfo) [][]types.Datum {
checker := privilege.GetPrivilegeManager(ctx)
var rows [][]types.Datum
for _, schema := range schemas {
for _, table := range schema.Tables {
if checker != nil && !checker.RequestVerification(schema.Name.L, table.Name.L, "", mysql.AllPrivMask) {
continue
}

rs := dataForColumnsInTable(schema, table)
rows = append(rows, rs...)
}
Expand Down Expand Up @@ -1084,7 +1096,7 @@ func (it *infoschemaTable) getRows(ctx sessionctx.Context, cols []*table.Column)
case tableTables:
fullRows, err = dataForTables(ctx, dbs)
case tableColumns:
fullRows = dataForColumns(dbs)
fullRows = dataForColumns(ctx, dbs)
case tableStatistics:
fullRows = dataForStatistics(dbs)
case tableCharacterSets:
Expand Down
13 changes: 13 additions & 0 deletions infoschema/tables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
. "github.com/pingcap/check"
"github.com/pingcap/tidb/session"
"github.com/pingcap/tidb/store/mockstore"
"github.com/pingcap/tidb/util/auth"
"github.com/pingcap/tidb/util/testkit"
"github.com/pingcap/tidb/util/testleak"
)
Expand Down Expand Up @@ -60,4 +61,16 @@ func (s *testSuite) TestDataForTableRowsCountField(c *C) {
h.Update(is)
tk.MustQuery("select table_rows from information_schema.tables where table_name='t'").Check(
testkit.Rows("2"))

tk.MustExec("create user xxx")
tk.MustExec("flush privileges")

tk1 := testkit.NewTestKit(c, store)
tk1.MustExec("use test")
c.Assert(tk1.Se.Auth(&auth.UserIdentity{
Username: "xxx",
Hostname: "127.0.0.1",
}, nil, nil), IsTrue)

tk1.MustQuery("select distinct(table_schema) from information_schema.tables").Check(testkit.Rows("INFORMATION_SCHEMA"))
}
1 change: 1 addition & 0 deletions mysql/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ const (
)

// AllPrivMask is the mask for PrivilegeType with all bits set to 1.
// If it's passed to RequestVerification, it means any privilege would be OK.
const AllPrivMask = AllPriv - 1

// MySQL type maximum length.
Expand Down
6 changes: 6 additions & 0 deletions plan/logical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,12 @@ func (s *testPlanSuite) TestVisitInfo(c *C) {
{mysql.SuperPriv, "", "", ""},
},
},
{
sql: `show create table test.ttt`,
ans: []visitInfo{
{mysql.AllPrivMask, "test", "ttt", ""},
},
},
}

for _, tt := range tests {
Expand Down
2 changes: 2 additions & 0 deletions plan/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,8 @@ func (b *planBuilder) buildShow(show *ast.ShowStmt) Plan {
b.err = ErrNoDB
return nil
}
case ast.ShowCreateTable:
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.AllPrivMask, show.Table.Schema.L, show.Table.Name.L, "")
}
p.SetSchema(buildShowSchema(show))
}
Expand Down
4 changes: 3 additions & 1 deletion privilege/privilege.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ type Manager interface {
// RequestVerification verifies user privilege for the request.
// If table is "", only check global/db scope privileges.
// If table is not "", check global/db/table scope privileges.
// priv should be a defined constant like CreatePriv, if pass AllPrivMask to priv,
// this means any privilege would be OK.
RequestVerification(db, table, column string, priv mysql.PrivilegeType) bool
// ConnectionVerification verifies user privilege for connection.
ConnectionVerification(host, user string, auth, salt []byte) bool
ConnectionVerification(user, host string, auth, salt []byte) bool

// DBIsVisible returns true is the database is visible to current user.
DBIsVisible(db string) bool
Expand Down

0 comments on commit bab4993

Please sign in to comment.