Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

executor, privilege: introduce a new privilege for the set config statement (#16847) #16856

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions executor/set_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ import (
"strings"

"github.com/pingcap/errors"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/tidb/expression"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/planner/core"
"github.com/pingcap/tidb/privilege"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util"
Expand All @@ -46,12 +44,6 @@ type SetConfigExec struct {

// Open implements the Executor Open interface.
func (s *SetConfigExec) Open(ctx context.Context) error {
// TODO: create a new privilege for this operation instead of using the SuperPriv
checker := privilege.GetPrivilegeManager(s.ctx)
if checker != nil && !checker.RequestVerification(s.ctx.GetSessionVars().ActiveRoles, "", "", "", mysql.SuperPriv) {
return core.ErrSpecificAccessDenied.GenWithStackByArgs("SET CONFIG")
}

if s.p.Type != "" {
s.p.Type = strings.ToLower(s.p.Type)
if s.p.Type != "tikv" && s.p.Type != "tidb" && s.p.Type != "pd" {
Expand Down
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ require (
github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989
github.com/pingcap/kvproto v0.0.0-20200420075417-e0c6e8842f22
github.com/pingcap/log v0.0.0-20200117041106-d28c14d3b1cd
<<<<<<< HEAD
github.com/pingcap/parser v0.0.0-20200422082501-7329d80eaf2c
=======
github.com/pingcap/parser v0.0.0-20200427031542-879c7bd4f27d
>>>>>>> 468b8c6... executor, privilege: introduce a new privilege for the `set config` statement (#16847)
github.com/pingcap/pd/v4 v4.0.0-rc.1.0.20200422143320-428acd53eba2
github.com/pingcap/sysutil v0.0.0-20200408114249-ed3bd6f7fdb1
github.com/pingcap/tidb-tools v4.0.0-beta.1.0.20200306084441-875bd09aa3d5+incompatible
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,13 @@ github.com/pingcap/kvproto v0.0.0-20200420075417-e0c6e8842f22/go.mod h1:IOdRDPLy
github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
github.com/pingcap/log v0.0.0-20200117041106-d28c14d3b1cd h1:CV3VsP3Z02MVtdpTMfEgRJ4T9NGgGTxdHpJerent7rM=
github.com/pingcap/log v0.0.0-20200117041106-d28c14d3b1cd/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
<<<<<<< HEAD
github.com/pingcap/parser v0.0.0-20200422082501-7329d80eaf2c h1:eXC+xkHerLvR6+mceugr4e8ALAQHj25S5slt8A2f6Ho=
github.com/pingcap/parser v0.0.0-20200422082501-7329d80eaf2c/go.mod h1:9v0Edh8IbgjGYW2ArJr19E+bvL8zKahsFp+ixWeId+4=
=======
github.com/pingcap/parser v0.0.0-20200427031542-879c7bd4f27d h1:iXKcmBOj5v8Vw4jbiWdY0LKyhJinSwqd1Hwyi0NvxBY=
github.com/pingcap/parser v0.0.0-20200427031542-879c7bd4f27d/go.mod h1:9v0Edh8IbgjGYW2ArJr19E+bvL8zKahsFp+ixWeId+4=
>>>>>>> 468b8c6... executor, privilege: introduce a new privilege for the `set config` statement (#16847)
github.com/pingcap/pd/v4 v4.0.0-rc.1.0.20200422143320-428acd53eba2 h1:JTzYYukREvxVSKW/ncrzNjFitd8snoQ/Xz32pw8i+s8=
github.com/pingcap/pd/v4 v4.0.0-rc.1.0.20200422143320-428acd53eba2/go.mod h1:s+utZtXDznOiL24VK0qGmtoHjjXNsscJx3m1n8cC56s=
github.com/pingcap/sysutil v0.0.0-20200206130906-2bfa6dc40bcd/go.mod h1:EB/852NMQ+aRKioCpToQ94Wl7fktV+FNnxf3CX/TTXI=
Expand Down
2 changes: 2 additions & 0 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,8 @@ func (b *PlanBuilder) Build(ctx context.Context, node ast.Node) (Plan, error) {
}

func (b *PlanBuilder) buildSetConfig(ctx context.Context, v *ast.SetConfigStmt) (Plan, error) {
privErr := ErrSpecificAccessDenied.GenWithStackByArgs("CONFIG")
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.ConfigPriv, "", "", "", privErr)
mockTablePlan := LogicalTableDual{}.Init(b.ctx, b.getSelectOffset())
expr, _, err := b.rewrite(ctx, v.Value, mockTablePlan, nil, true)
return &SetConfig{Name: v.Name, Type: v.Type, Instance: v.Instance, Value: expr}, err
Expand Down
3 changes: 2 additions & 1 deletion privilege/privileges/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ func (s *testCacheSuite) TestAbnormalMySQLTable(c *C) {
Shutdown_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Process_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
File_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Config_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Grant_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
References_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Index_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Expand Down Expand Up @@ -419,7 +420,7 @@ func (s *testCacheSuite) TestAbnormalMySQLTable(c *C) {
password_expired enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
PRIMARY KEY (Host,User)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges';`)
mustExec(c, se, `INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'mysql_native_password','','N');
mustExec(c, se, `INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'mysql_native_password','','N');
`)
var p privileges.MySQLPrivilege
err = p.LoadUserTable(se)
Expand Down
18 changes: 18 additions & 0 deletions privilege/privileges/privileges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,24 @@ func (s *testPrivilegeSuite) TestCreateDropUser(c *C) {
mustExec(c, se, `DROP USER tcd3`)
}

func (s *testPrivilegeSuite) TestConfigPrivilege(c *C) {
se := newSession(c, s.store, s.dbName)
mustExec(c, se, `DROP USER IF EXISTS tcd1`)
mustExec(c, se, `CREATE USER tcd1`)
mustExec(c, se, `GRANT ALL ON *.* to tcd1`)
mustExec(c, se, `DROP USER IF EXISTS tcd2`)
mustExec(c, se, `CREATE USER tcd2`)
mustExec(c, se, `GRANT ALL ON *.* to tcd2`)
mustExec(c, se, `REVOKE CONFIG ON *.* FROM tcd2`)

c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd1", Hostname: "localhost", AuthHostname: "tcd1", AuthUsername: "%"}, nil, nil), IsTrue)
mustExec(c, se, `SET CONFIG TIKV testkey="testval"`)
c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd2", Hostname: "localhost", AuthHostname: "tcd2", AuthUsername: "%"}, nil, nil), IsTrue)
_, err := se.Execute(context.Background(), `SET CONFIG TIKV testkey="testval"`)
c.Assert(err, ErrorMatches, ".*you need \\(at least one of\\) the CONFIG privilege\\(s\\) for this operation")
mustExec(c, se, `DROP USER tcd1, tcd2`)
}

func (s *testPrivilegeSuite) TestShowCreateTable(c *C) {
se := newSession(c, s.store, s.dbName)
mustExec(c, se, `CREATE USER tsct1, tsct2`)
Expand Down
14 changes: 13 additions & 1 deletion session/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const (
Shutdown_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Reload_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
FILE_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Config_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
PRIMARY KEY (Host, User));`
// CreateGlobalPrivTable is the SQL statement creates Global scope privilege table in system db.
CreateGlobalPrivTable = "CREATE TABLE if not exists mysql.global_priv (" +
Expand Down Expand Up @@ -381,6 +382,8 @@ const (
version43 = 43
// version44 delete tidb_isolation_read_engines from mysql.global_variables to avoid unexpected behavior after upgrade.
version44 = 44
// version45 introduces CONFIG_PRIV for SET CONFIG statements.
version45 = 45
)

var (
Expand Down Expand Up @@ -428,6 +431,7 @@ var (
upgradeToVer42,
upgradeToVer43,
upgradeToVer44,
upgradeToVer45,
}
)

Expand Down Expand Up @@ -1033,6 +1037,14 @@ func upgradeToVer44(s Session, ver int64) {
mustExecute(s, "DELETE FROM mysql.global_variables where variable_name = \"tidb_isolation_read_engines\"")
}

func upgradeToVer45(s Session, ver int64) {
if ver >= version45 {
return
}
doReentrantDDL(s, "ALTER TABLE mysql.user ADD COLUMN `Config_priv` ENUM('N','Y') DEFAULT 'N'", infoschema.ErrColumnExists)
mustExecute(s, "UPDATE HIGH_PRIORITY mysql.user SET Config_priv='Y' where Super_priv='Y'")
}

// updateBootstrapVer updates bootstrap version variable in mysql.TiDB table.
func updateBootstrapVer(s Session) {
// Update bootstrap version.
Expand Down Expand Up @@ -1105,7 +1117,7 @@ func doDMLWorks(s Session) {

// Insert a default user with empty password.
mustExecute(s, `INSERT HIGH_PRIORITY INTO mysql.user VALUES
("%", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y")`)
("%", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y")`)

// Init global system variables table.
values := make([]string, 0, len(variable.SysVars))
Expand Down
4 changes: 2 additions & 2 deletions session/bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (s *testBootstrapSuite) TestBootstrap(c *C) {
c.Assert(err, IsNil)
c.Assert(req.NumRows() == 0, IsFalse)
datums := statistics.RowToDatums(req.GetRow(0), r.Fields())
match(c, datums, `%`, "root", []byte(""), "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y")
match(c, datums, `%`, "root", []byte(""), "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y")

c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "anyhost"}, []byte(""), []byte("")), IsTrue)
mustExecSQL(c, se, "USE test;")
Expand Down Expand Up @@ -159,7 +159,7 @@ func (s *testBootstrapSuite) TestBootstrapWithError(c *C) {
c.Assert(req.NumRows() == 0, IsFalse)
row := req.GetRow(0)
datums := statistics.RowToDatums(row, r.Fields())
match(c, datums, `%`, "root", []byte(""), "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y")
match(c, datums, `%`, "root", []byte(""), "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y")
c.Assert(r.Close(), IsNil)

mustExecSQL(c, se, "USE test;")
Expand Down
2 changes: 1 addition & 1 deletion session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -1829,7 +1829,7 @@ func CreateSessionWithDomain(store kv.Storage, dom *domain.Domain) (*session, er

const (
notBootstrapped = 0
currentBootstrapVersion = version44
currentBootstrapVersion = version45
)

func getStoreBootstrapVersion(store kv.Storage) int64 {
Expand Down