Skip to content

Commit a56674c

Browse files
authored
expression: provide OptPropPrivilegeChecker for EvalContext (#56302)
close #56301
1 parent a0bcee3 commit a56674c

File tree

17 files changed

+210
-191
lines changed

17 files changed

+210
-191
lines changed

pkg/ddl/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,6 @@ go_test(
315315
"//pkg/parser/mysql",
316316
"//pkg/parser/terror",
317317
"//pkg/parser/types",
318-
"//pkg/privilege",
319318
"//pkg/server",
320319
"//pkg/session",
321320
"//pkg/session/types",

pkg/ddl/backfilling_test.go

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"github.com/pingcap/tidb/pkg/kv"
2727
"github.com/pingcap/tidb/pkg/meta/model"
2828
"github.com/pingcap/tidb/pkg/parser/mysql"
29-
"github.com/pingcap/tidb/pkg/privilege"
3029
"github.com/pingcap/tidb/pkg/sessionctx"
3130
"github.com/pingcap/tidb/pkg/sessionctx/variable"
3231
"github.com/pingcap/tidb/pkg/table"
@@ -182,26 +181,6 @@ func assertStaticExprContextEqual(t *testing.T, sctx sessionctx.Context, exprCtx
182181
require.NoError(t, err)
183182
},
184183
},
185-
{
186-
field: "requestVerificationFn",
187-
check: func(ctx *exprstatic.EvalContext) {
188-
// RequestVerification should allow all privileges
189-
// that is the same with input session context (GetPrivilegeManager returns nil).
190-
require.Nil(t, privilege.GetPrivilegeManager(sctx))
191-
require.True(t, sctx.GetExprCtx().GetEvalCtx().RequestVerification("any", "any", "any", mysql.CreatePriv))
192-
require.True(t, ctx.RequestVerification("any", "any", "any", mysql.CreatePriv))
193-
},
194-
},
195-
{
196-
field: "requestDynamicVerificationFn",
197-
check: func(ctx *exprstatic.EvalContext) {
198-
// RequestDynamicVerification should allow all privileges
199-
// that is the same with input session context (GetPrivilegeManager returns nil).
200-
require.Nil(t, privilege.GetPrivilegeManager(sctx))
201-
require.True(t, sctx.GetExprCtx().GetEvalCtx().RequestDynamicVerification("RESTRICTED_USER_ADMIN", true))
202-
require.True(t, ctx.RequestDynamicVerification("RESTRICTED_USER_ADMIN", true))
203-
},
204-
},
205184
}
206185

207186
// check ExprContext except EvalContext

pkg/expression/builtin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ var funcs = map[string]functionClass{
979979
ast.TiDBIsDDLOwner: &tidbIsDDLOwnerFunctionClass{baseFunctionClass{ast.TiDBIsDDLOwner, 0, 0}},
980980
ast.TiDBDecodePlan: &tidbDecodePlanFunctionClass{baseFunctionClass{ast.TiDBDecodePlan, 1, 1}},
981981
ast.TiDBDecodeBinaryPlan: &tidbDecodePlanFunctionClass{baseFunctionClass{ast.TiDBDecodeBinaryPlan, 1, 1}},
982-
ast.TiDBDecodeSQLDigests: &tidbDecodeSQLDigestsFunctionClass{baseFunctionClass{ast.TiDBDecodeSQLDigests, 1, 2}},
982+
ast.TiDBDecodeSQLDigests: &tidbDecodeSQLDigestsFunctionClass{baseFunctionClass: baseFunctionClass{ast.TiDBDecodeSQLDigests, 1, 2}},
983983
ast.TiDBEncodeSQLDigest: &tidbEncodeSQLDigestFunctionClass{baseFunctionClass{ast.TiDBEncodeSQLDigest, 1, 1}},
984984

985985
// TiDB Sequence function.

pkg/expression/builtin_info.go

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -919,11 +919,13 @@ func (c *tidbMVCCInfoFunctionClass) getFunction(ctx BuildContext, args []Express
919919
type builtinTiDBMVCCInfoSig struct {
920920
baseBuiltinFunc
921921
expropt.KVStorePropReader
922+
expropt.PrivilegeCheckerPropReader
922923
}
923924

924925
// RequiredOptionalEvalProps implements the RequireOptionalEvalProps interface.
925926
func (b *builtinTiDBMVCCInfoSig) RequiredOptionalEvalProps() OptionalEvalPropKeySet {
926-
return b.KVStorePropReader.RequiredOptionalEvalProps()
927+
return b.KVStorePropReader.RequiredOptionalEvalProps() |
928+
b.PrivilegeCheckerPropReader.RequiredOptionalEvalProps()
927929
}
928930

929931
func (b *builtinTiDBMVCCInfoSig) Clone() builtinFunc {
@@ -934,7 +936,11 @@ func (b *builtinTiDBMVCCInfoSig) Clone() builtinFunc {
934936

935937
// evalString evals a builtinTiDBMVCCInfoSig.
936938
func (b *builtinTiDBMVCCInfoSig) evalString(ctx EvalContext, row chunk.Row) (string, bool, error) {
937-
if !ctx.RequestVerification("", "", "", mysql.SuperPriv) {
939+
privChecker, err := b.GetPrivilegeChecker(ctx)
940+
if err != nil {
941+
return "", false, err
942+
}
943+
if !privChecker.RequestVerification("", "", "", mysql.SuperPriv) {
938944
return "", false, plannererrors.ErrSpecificAccessDenied.FastGenByArgs("SUPER")
939945
}
940946
s, isNull, err := b.args[0].EvalString(ctx, row)
@@ -1006,12 +1012,14 @@ type builtinTiDBEncodeRecordKeySig struct {
10061012
baseBuiltinFunc
10071013
expropt.InfoSchemaPropReader
10081014
expropt.SessionVarsPropReader
1015+
expropt.PrivilegeCheckerPropReader
10091016
}
10101017

10111018
// RequiredOptionalEvalProps implements the RequireOptionalEvalProps interface.
10121019
func (b *builtinTiDBEncodeRecordKeySig) RequiredOptionalEvalProps() OptionalEvalPropKeySet {
10131020
return b.InfoSchemaPropReader.RequiredOptionalEvalProps() |
1014-
b.SessionVarsPropReader.RequiredOptionalEvalProps()
1021+
b.SessionVarsPropReader.RequiredOptionalEvalProps() |
1022+
b.PrivilegeCheckerPropReader.RequiredOptionalEvalProps()
10151023
}
10161024

10171025
func (b *builtinTiDBEncodeRecordKeySig) Clone() builtinFunc {
@@ -1029,7 +1037,11 @@ func (b *builtinTiDBEncodeRecordKeySig) evalString(ctx EvalContext, row chunk.Ro
10291037
if EncodeRecordKeyFromRow == nil {
10301038
return "", false, errors.New("EncodeRecordKeyFromRow is not initialized")
10311039
}
1032-
recordKey, isNull, err := EncodeRecordKeyFromRow(ctx, is, b.args, row)
1040+
privChecker, err := b.GetPrivilegeChecker(ctx)
1041+
if err != nil {
1042+
return "", false, err
1043+
}
1044+
recordKey, isNull, err := EncodeRecordKeyFromRow(ctx, privChecker, is, b.args, row)
10331045
if isNull || err != nil {
10341046
if errors.ErrorEqual(err, plannererrors.ErrSpecificAccessDenied) {
10351047
sv, err2 := b.GetSessionVars(ctx)
@@ -1072,12 +1084,14 @@ type builtinTiDBEncodeIndexKeySig struct {
10721084
baseBuiltinFunc
10731085
expropt.InfoSchemaPropReader
10741086
expropt.SessionVarsPropReader
1087+
expropt.PrivilegeCheckerPropReader
10751088
}
10761089

10771090
// RequiredOptionalEvalProps implements the RequireOptionalEvalProps interface.
10781091
func (b *builtinTiDBEncodeIndexKeySig) RequiredOptionalEvalProps() OptionalEvalPropKeySet {
10791092
return b.InfoSchemaPropReader.RequiredOptionalEvalProps() |
1080-
b.SessionVarsPropReader.RequiredOptionalEvalProps()
1093+
b.SessionVarsPropReader.RequiredOptionalEvalProps() |
1094+
b.PrivilegeCheckerPropReader.RequiredOptionalEvalProps()
10811095
}
10821096

10831097
func (b *builtinTiDBEncodeIndexKeySig) Clone() builtinFunc {
@@ -1095,7 +1109,11 @@ func (b *builtinTiDBEncodeIndexKeySig) evalString(ctx EvalContext, row chunk.Row
10951109
if EncodeIndexKeyFromRow == nil {
10961110
return "", false, errors.New("EncodeIndexKeyFromRow is not initialized")
10971111
}
1098-
idxKey, isNull, err := EncodeIndexKeyFromRow(ctx, is, b.args, row)
1112+
privChecker, err := b.GetPrivilegeChecker(ctx)
1113+
if err != nil {
1114+
return "", false, err
1115+
}
1116+
idxKey, isNull, err := EncodeIndexKeyFromRow(ctx, privChecker, is, b.args, row)
10991117
if isNull || err != nil {
11001118
if errors.ErrorEqual(err, plannererrors.ErrSpecificAccessDenied) {
11011119
sv, err2 := b.GetSessionVars(ctx)
@@ -1133,10 +1151,10 @@ func (c *tidbDecodeKeyFunctionClass) getFunction(ctx BuildContext, args []Expres
11331151
var DecodeKeyFromString func(types.Context, infoschema.MetaOnlyInfoSchema, string) string
11341152

11351153
// EncodeRecordKeyFromRow is used to encode record key by expressions.
1136-
var EncodeRecordKeyFromRow func(ctx EvalContext, is infoschema.MetaOnlyInfoSchema, args []Expression, row chunk.Row) ([]byte, bool, error)
1154+
var EncodeRecordKeyFromRow func(ctx EvalContext, checker expropt.PrivilegeChecker, is infoschema.MetaOnlyInfoSchema, args []Expression, row chunk.Row) ([]byte, bool, error)
11371155

11381156
// EncodeIndexKeyFromRow is used to encode index key by expressions.
1139-
var EncodeIndexKeyFromRow func(ctx EvalContext, is infoschema.MetaOnlyInfoSchema, args []Expression, row chunk.Row) ([]byte, bool, error)
1157+
var EncodeIndexKeyFromRow func(ctx EvalContext, checker expropt.PrivilegeChecker, is infoschema.MetaOnlyInfoSchema, args []Expression, row chunk.Row) ([]byte, bool, error)
11401158

11411159
type builtinTiDBDecodeKeySig struct {
11421160
baseBuiltinFunc
@@ -1173,14 +1191,20 @@ func (b *builtinTiDBDecodeKeySig) evalString(ctx EvalContext, row chunk.Row) (st
11731191

11741192
type tidbDecodeSQLDigestsFunctionClass struct {
11751193
baseFunctionClass
1194+
expropt.PrivilegeCheckerPropReader
11761195
}
11771196

11781197
func (c *tidbDecodeSQLDigestsFunctionClass) getFunction(ctx BuildContext, args []Expression) (builtinFunc, error) {
11791198
if err := c.verifyArgs(args); err != nil {
11801199
return nil, err
11811200
}
11821201

1183-
if !ctx.GetEvalCtx().RequestVerification("", "", "", mysql.ProcessPriv) {
1202+
privChecker, err := c.GetPrivilegeChecker(ctx.GetEvalCtx())
1203+
if err != nil {
1204+
return nil, err
1205+
}
1206+
1207+
if !privChecker.RequestVerification("", "", "", mysql.ProcessPriv) {
11841208
return nil, errSpecificAccessDenied.GenWithStackByArgs("PROCESS")
11851209
}
11861210

@@ -1202,12 +1226,14 @@ type builtinTiDBDecodeSQLDigestsSig struct {
12021226
baseBuiltinFunc
12031227
expropt.SessionVarsPropReader
12041228
expropt.SQLExecutorPropReader
1229+
expropt.PrivilegeCheckerPropReader
12051230
}
12061231

12071232
// RequiredOptionalEvalProps implements the RequireOptionalEvalProps interface.
12081233
func (b *builtinTiDBDecodeSQLDigestsSig) RequiredOptionalEvalProps() OptionalEvalPropKeySet {
12091234
return b.SessionVarsPropReader.RequiredOptionalEvalProps() |
1210-
b.SQLExecutorPropReader.RequiredOptionalEvalProps()
1235+
b.SQLExecutorPropReader.RequiredOptionalEvalProps() |
1236+
b.PrivilegeCheckerPropReader.RequiredOptionalEvalProps()
12111237
}
12121238

12131239
func (b *builtinTiDBDecodeSQLDigestsSig) Clone() builtinFunc {
@@ -1217,6 +1243,15 @@ func (b *builtinTiDBDecodeSQLDigestsSig) Clone() builtinFunc {
12171243
}
12181244

12191245
func (b *builtinTiDBDecodeSQLDigestsSig) evalString(ctx EvalContext, row chunk.Row) (string, bool, error) {
1246+
privChecker, err := b.GetPrivilegeChecker(ctx)
1247+
if err != nil {
1248+
return "", true, err
1249+
}
1250+
1251+
if !privChecker.RequestVerification("", "", "", mysql.ProcessPriv) {
1252+
return "", true, errSpecificAccessDenied.GenWithStackByArgs("PROCESS")
1253+
}
1254+
12201255
args := b.getArgs()
12211256
digestsStr, isNull, err := args[0].EvalString(ctx, row)
12221257
if err != nil {
@@ -1443,11 +1478,13 @@ type builtinNextValSig struct {
14431478
baseBuiltinFunc
14441479
expropt.SequenceOperatorPropReader
14451480
expropt.SessionVarsPropReader
1481+
expropt.PrivilegeCheckerPropReader
14461482
}
14471483

14481484
func (b *builtinNextValSig) RequiredOptionalEvalProps() OptionalEvalPropKeySet {
14491485
return b.SequenceOperatorPropReader.RequiredOptionalEvalProps() |
1450-
b.SessionVarsPropReader.RequiredOptionalEvalProps()
1486+
b.SessionVarsPropReader.RequiredOptionalEvalProps() |
1487+
b.PrivilegeCheckerPropReader.RequiredOptionalEvalProps()
14511488
}
14521489

14531490
func (b *builtinNextValSig) Clone() builtinFunc {
@@ -1477,7 +1514,11 @@ func (b *builtinNextValSig) evalInt(ctx EvalContext, row chunk.Row) (int64, bool
14771514
}
14781515
// Do the privilege check.
14791516
user := vars.User
1480-
if !ctx.RequestVerification(db, seq, "", mysql.InsertPriv) {
1517+
privChecker, err := b.GetPrivilegeChecker(ctx)
1518+
if err != nil {
1519+
return 0, false, err
1520+
}
1521+
if !privChecker.RequestVerification(db, seq, "", mysql.InsertPriv) {
14811522
return 0, false, errSequenceAccessDenied.GenWithStackByArgs("INSERT", user.AuthUsername, user.AuthHostname, seq)
14821523
}
14831524
nextVal, err := sequence.GetSequenceNextVal()
@@ -1510,11 +1551,13 @@ type builtinLastValSig struct {
15101551
baseBuiltinFunc
15111552
expropt.SequenceOperatorPropReader
15121553
expropt.SessionVarsPropReader
1554+
expropt.PrivilegeCheckerPropReader
15131555
}
15141556

15151557
func (b *builtinLastValSig) RequiredOptionalEvalProps() OptionalEvalPropKeySet {
15161558
return b.SequenceOperatorPropReader.RequiredOptionalEvalProps() |
1517-
b.SessionVarsPropReader.RequiredOptionalEvalProps()
1559+
b.SessionVarsPropReader.RequiredOptionalEvalProps() |
1560+
b.PrivilegeCheckerPropReader.RequiredOptionalEvalProps()
15181561
}
15191562

15201563
func (b *builtinLastValSig) Clone() builtinFunc {
@@ -1544,7 +1587,11 @@ func (b *builtinLastValSig) evalInt(ctx EvalContext, row chunk.Row) (int64, bool
15441587
}
15451588
// Do the privilege check.
15461589
user := vars.User
1547-
if !ctx.RequestVerification(db, seq, "", mysql.SelectPriv) {
1590+
privChecker, err := b.GetPrivilegeChecker(ctx)
1591+
if err != nil {
1592+
return 0, false, err
1593+
}
1594+
if !privChecker.RequestVerification(db, seq, "", mysql.SelectPriv) {
15481595
return 0, false, errSequenceAccessDenied.GenWithStackByArgs("SELECT", user.AuthUsername, user.AuthHostname, seq)
15491596
}
15501597
return vars.SequenceState.GetLastValue(sequence.GetSequenceID())
@@ -1571,11 +1618,13 @@ type builtinSetValSig struct {
15711618
baseBuiltinFunc
15721619
expropt.SequenceOperatorPropReader
15731620
expropt.SessionVarsPropReader
1621+
expropt.PrivilegeCheckerPropReader
15741622
}
15751623

15761624
func (b *builtinSetValSig) RequiredOptionalEvalProps() OptionalEvalPropKeySet {
15771625
return b.SequenceOperatorPropReader.RequiredOptionalEvalProps() |
1578-
b.SessionVarsPropReader.RequiredOptionalEvalProps()
1626+
b.SessionVarsPropReader.RequiredOptionalEvalProps() |
1627+
b.PrivilegeCheckerPropReader.RequiredOptionalEvalProps()
15791628
}
15801629

15811630
func (b *builtinSetValSig) Clone() builtinFunc {
@@ -1605,7 +1654,11 @@ func (b *builtinSetValSig) evalInt(ctx EvalContext, row chunk.Row) (int64, bool,
16051654
}
16061655
// Do the privilege check.
16071656
user := vars.User
1608-
if !ctx.RequestVerification(db, seq, "", mysql.InsertPriv) {
1657+
privChecker, err := b.GetPrivilegeChecker(ctx)
1658+
if err != nil {
1659+
return 0, false, err
1660+
}
1661+
if !privChecker.RequestVerification(db, seq, "", mysql.InsertPriv) {
16091662
return 0, false, errSequenceAccessDenied.GenWithStackByArgs("INSERT", user.AuthUsername, user.AuthHostname, seq)
16101663
}
16111664
setValue, isNull, err := b.args[1].EvalInt(ctx, row)

pkg/expression/exprctx/context.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,6 @@ type EvalContext interface {
8888
GetDivPrecisionIncrement() int
8989
// GetUserVarsReader returns the `UserVarsReader` to read user vars.
9090
GetUserVarsReader() variable.UserVarsReader
91-
// RequestVerification verifies user privilege
92-
RequestVerification(db, table, column string, priv mysql.PrivilegeType) bool
93-
// RequestDynamicVerification verifies user privilege for a DYNAMIC privilege.
94-
RequestDynamicVerification(privName string, grantable bool) bool
9591
// GetOptionalPropSet returns the optional properties provided by this context.
9692
GetOptionalPropSet() OptionalEvalPropKeySet
9793
// GetOptionalPropProvider gets the optional property provider by key
@@ -261,6 +257,4 @@ type StaticConvertibleEvalContext interface {
261257

262258
AllParamValues() []types.Datum
263259
GetWarnHandler() contextutil.WarnHandler
264-
GetRequestVerificationFn() func(db, table, column string, priv mysql.PrivilegeType) bool
265-
GetDynamicPrivCheckFn() func(privName string, grantable bool) bool
266260
}

pkg/expression/exprctx/optional.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ const (
8787
OptPropAdvisoryLock
8888
// OptPropDDLOwnerInfo indicates to provide DDL owner information.
8989
OptPropDDLOwnerInfo
90+
// OptPropPrivilegeChecker indicates to provide the privilege checker.
91+
OptPropPrivilegeChecker
9092
// optPropsCnt is the count of optional properties. DO NOT use it as a property key.
9193
optPropsCnt
9294
)
@@ -147,6 +149,10 @@ var optionalPropertyDescList = []OptionalEvalPropDesc{
147149
key: OptPropDDLOwnerInfo,
148150
str: "OptPropDDLOwnerInfo",
149151
},
152+
{
153+
key: OptPropPrivilegeChecker,
154+
str: "OptPropPrivilegeChecker",
155+
},
150156
}
151157

152158
// OptionalEvalPropKeySet is a bit map for optional evaluation properties in EvalContext

pkg/expression/exprctx/optional_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ func TestOptionalPropKeySet(t *testing.T) {
5858
Add(OptPropKVStore).
5959
Add(OptPropSQLExecutor).
6060
Add(OptPropSequenceOperator).
61-
Add(OptPropAdvisoryLock)
61+
Add(OptPropAdvisoryLock).
62+
Add(OptPropPrivilegeChecker)
6263
require.True(t, keySet4.IsFull())
6364
require.False(t, keySet4.IsEmpty())
6465
}

pkg/expression/expropt/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ go_library(
99
"infoschema.go",
1010
"kvstore.go",
1111
"optional.go",
12+
"priv.go",
1213
"sequence.go",
1314
"sessionvars.go",
1415
"sqlexec.go",
@@ -20,6 +21,7 @@ go_library(
2021
"//pkg/infoschema/context",
2122
"//pkg/kv",
2223
"//pkg/parser/auth",
24+
"//pkg/parser/mysql",
2325
"//pkg/planner/core/resolve",
2426
"//pkg/sessionctx/variable",
2527
"//pkg/util/chunk",

pkg/expression/expropt/optional.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ func (o *OptionalEvalPropProviders) Add(val exprctx.OptionalEvalPropProvider) {
7878
case exprctx.OptPropSequenceOperator:
7979
_, ok := val.(SequenceOperatorProvider)
8080
intest.Assert(ok)
81+
case exprctx.OptPropPrivilegeChecker:
82+
_, ok := val.(PrivilegeCheckerProvider)
83+
intest.Assert(ok)
8184
default:
8285
intest.Assert(false)
8386
}

pkg/expression/expropt/optional_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,21 @@ func TestOptionalEvalPropProviders(t *testing.T) {
267267
isOwner = false
268268
require.False(t, assertReaderFuncValue(t, ctx, r.IsDDLOwner))
269269
}
270+
case exprctx.OptPropPrivilegeChecker:
271+
type mockPrivCheckerTp struct {
272+
PrivilegeChecker
273+
}
274+
mockPrivChecker := &mockPrivCheckerTp{}
275+
p = PrivilegeCheckerProvider(func() PrivilegeChecker { return mockPrivChecker })
276+
r := PrivilegeCheckerPropReader{}
277+
reader = r
278+
verifyNoProvider = func(ctx exprctx.EvalContext) {
279+
assertReaderFuncReturnErr(t, ctx, r.GetPrivilegeChecker)
280+
}
281+
verifyProvider = func(ctx exprctx.EvalContext, val exprctx.OptionalEvalPropProvider) {
282+
require.Same(t, mockPrivChecker, assertReaderFuncValue(t, ctx, r.GetPrivilegeChecker))
283+
require.Same(t, mockPrivChecker, val.(PrivilegeCheckerProvider)())
284+
}
270285
default:
271286
require.Fail(t, "unexpected optional property key")
272287
}

0 commit comments

Comments
 (0)