From d7a81d9cba9be10cefa7307cf30bf9915194070e Mon Sep 17 00:00:00 2001 From: zhangdong <493738387@qq.com> Date: Fri, 20 Oct 2023 20:43:05 +0800 Subject: [PATCH 01/10] 1 --- .../org/apache/doris/analysis/AlterTableStmt.java | 5 +++-- .../apache/doris/analysis/CreateTableLikeStmt.java | 2 +- .../org/apache/doris/analysis/DropTableStmt.java | 4 ++-- .../doris/analysis/InsertOverwriteTableStmt.java | 12 ++++++++++++ .../org/apache/doris/analysis/NativeInsertStmt.java | 2 +- .../org/apache/doris/analysis/StatementBase.java | 6 ++++++ .../main/java/org/apache/doris/qe/StmtExecutor.java | 8 ++++++++ 7 files changed, 33 insertions(+), 6 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java index f2831a628f2319..5e7abc668d4cf8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java @@ -67,8 +67,9 @@ public void analyze(Analyzer analyzer) throws UserException { tbl.analyze(analyzer); // disallow external catalog Util.prohibitExternalCatalog(tbl.getCtl(), this.getClass().getSimpleName()); - if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), tbl.getDb(), tbl.getTbl(), - PrivPredicate.ALTER)) { + if (!skipAuth && !Env.getCurrentEnv().getAccessManager() + .checkTblPriv(ConnectContext.get(), tbl.getDb(), tbl.getTbl(), + PrivPredicate.ALTER)) { ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "ALTER TABLE", ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(), diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableLikeStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableLikeStmt.java index a3d64c45907f11..269dd10aa9f4bc 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableLikeStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableLikeStmt.java @@ -95,7 +95,7 @@ public void analyze(Analyzer analyzer) throws UserException { // disallow external catalog Util.prohibitExternalCatalog(existedTableName.getCtl(), this.getClass().getSimpleName()); ConnectContext ctx = ConnectContext.get(); - if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ctx, existedTableName.getDb(), + if (!skipAuth && !Env.getCurrentEnv().getAccessManager().checkTblPriv(ctx, existedTableName.getDb(), existedTableName.getTbl(), PrivPredicate.SELECT)) { ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "SELECT"); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java index a8b091705e4d3b..93cd7d7ba89466 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java @@ -87,8 +87,8 @@ public void analyze(Analyzer analyzer) throws UserException { Util.prohibitExternalCatalog(tableName.getCtl(), this.getClass().getSimpleName()); // check access - if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), tableName.getDb(), - tableName.getTbl(), PrivPredicate.DROP)) { + if (!skipAuth && !Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), tableName.getDb(), + tableName.getTbl(), PrivPredicate.DROP)) { ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "DROP"); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java index a34c2cab0b90b5..fe8d0a17c8d5aa 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java @@ -17,7 +17,12 @@ package org.apache.doris.analysis; +import org.apache.doris.catalog.Env; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; import org.apache.doris.common.UserException; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; import lombok.Getter; @@ -69,5 +74,12 @@ public List getPartitionNames() { @Override public void analyze(Analyzer analyzer) throws UserException { + if (!skipAuth && !Env.getCurrentEnv().getAccessManager() + .checkTblPriv(ConnectContext.get(), getDb(), getTbl(), PrivPredicate.LOAD)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "LOAD", + ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(), + getDb() + ": " + getTbl()); + } + getQueryStmt().analyze(analyzer); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java index d357c2129ca237..3b07cbdd6d2436 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java @@ -279,7 +279,7 @@ public void getTables(Analyzer analyzer, Map tableMap, Set placeholders = new ArrayList<>(); + //internal call like `insert overwrite` not need skipAuth + protected boolean skipAuth = false; protected StatementBase() { } @@ -246,6 +248,10 @@ public void setUserInfo(UserIdentity userInfo) { this.userInfo = userInfo; } + public void setSkipAuth(boolean skipAuth) { + this.skipAuth = skipAuth; + } + /** * Resets the internal analysis state of this node. * For easier maintenance, class members that need to be reset are grouped into diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java index 2ce0de22cb2d6c..1d011a790f8224 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java @@ -2393,6 +2393,7 @@ private void handleOverwriteTable(InsertOverwriteTableStmt iotStmt) { // create a tmp table with uuid parsedStmt = new CreateTableLikeStmt(false, tmpTableName, targetTableName, null, false); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); + parsedStmt.setSkipAuth(true); execute(); // if create tmp table err, return if (MysqlStateType.ERR.equals(context.getState().getStateType())) { @@ -2411,6 +2412,7 @@ private void handleOverwriteTable(InsertOverwriteTableStmt iotStmt) { parsedStmt = new NativeInsertStmt(tmpTableName, null, new LabelName(iotStmt.getDb(), iotStmt.getLabel()), iotStmt.getQueryStmt(), iotStmt.getHints(), iotStmt.getCols()); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); + parsedStmt.setSkipAuth(true); execute(); if (MysqlStateType.ERR.equals(context.getState().getStateType())) { LOG.warn("IOT insert data error, stmt={}", parsedStmt.toSql()); @@ -2432,6 +2434,7 @@ private void handleOverwriteTable(InsertOverwriteTableStmt iotStmt) { ops.add(new ReplaceTableClause(tmpTableName.getTbl(), properties)); parsedStmt = new AlterTableStmt(targetTableName, ops); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); + parsedStmt.setSkipAuth(true); execute(); if (MysqlStateType.ERR.equals(context.getState().getStateType())) { LOG.warn("IOT overwrite table error, stmt={}", parsedStmt.toSql()); @@ -2462,6 +2465,7 @@ private void handleOverwritePartition(InsertOverwriteTableStmt iotStmt) { ops.add(new AddPartitionLikeClause(tempPartName, partitionName, true)); parsedStmt = new AlterTableStmt(targetTableName, ops); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); + parsedStmt.setSkipAuth(true); execute(); if (MysqlStateType.ERR.equals(context.getState().getStateType())) { LOG.warn("IOT create tmp partitions error, stmt={}", originStmt.originStmt); @@ -2484,6 +2488,7 @@ private void handleOverwritePartition(InsertOverwriteTableStmt iotStmt) { new LabelName(iotStmt.getDb(), iotStmt.getLabel()), iotStmt.getQueryStmt(), iotStmt.getHints(), iotStmt.getCols()); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); + parsedStmt.setSkipAuth(true); execute(); if (MysqlStateType.ERR.equals(context.getState().getStateType())) { LOG.warn("IOT insert data error, stmt={}", parsedStmt.toSql()); @@ -2506,6 +2511,7 @@ private void handleOverwritePartition(InsertOverwriteTableStmt iotStmt) { new PartitionNames(true, tempPartitionName), properties)); parsedStmt = new AlterTableStmt(targetTableName, ops); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); + parsedStmt.setSkipAuth(true); execute(); if (MysqlStateType.ERR.equals(context.getState().getStateType())) { LOG.warn("IOT overwrite table partitions error, stmt={}", parsedStmt.toSql()); @@ -2524,6 +2530,7 @@ private void handleOverwritePartition(InsertOverwriteTableStmt iotStmt) { private void handleIotRollback(TableName table) { // insert error drop the tmp table DropTableStmt dropTableStmt = new DropTableStmt(true, table, true); + dropTableStmt.setSkipAuth(true); try { Analyzer tempAnalyzer = new Analyzer(Env.getCurrentEnv(), context); dropTableStmt.analyze(tempAnalyzer); @@ -2541,6 +2548,7 @@ private void handleIotPartitionRollback(TableName targetTableName, List List ops = new ArrayList<>(); ops.add(new DropPartitionClause(true, partitionName, true, true)); AlterTableStmt dropTablePartitionStmt = new AlterTableStmt(targetTableName, ops); + dropTablePartitionStmt.setSkipAuth(true); Analyzer tempAnalyzer = new Analyzer(Env.getCurrentEnv(), context); dropTablePartitionStmt.analyze(tempAnalyzer); DdlExecutor.execute(context.getEnv(), dropTablePartitionStmt); From 769b7c7ea8d357699fdd01781eede733fde998dd Mon Sep 17 00:00:00 2001 From: zhangdong <493738387@qq.com> Date: Fri, 20 Oct 2023 21:40:45 +0800 Subject: [PATCH 02/10] 1 --- .../doris/analysis/InsertOverwriteTableStmt.java | 1 - .../java/org/apache/doris/analysis/StatementBase.java | 6 ------ .../mysql/privilege/AccessControllerManager.java | 3 +++ .../main/java/org/apache/doris/qe/ConnectContext.java | 11 +++++++++++ .../main/java/org/apache/doris/qe/StmtExecutor.java | 11 +++-------- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java index fe8d0a17c8d5aa..4512603b31a777 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java @@ -80,6 +80,5 @@ public void analyze(Analyzer analyzer) throws UserException { ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(), getDb() + ": " + getTbl()); } - getQueryStmt().analyze(analyzer); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/StatementBase.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/StatementBase.java index cf56d996f2e679..13895f5695bbd9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/StatementBase.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/StatementBase.java @@ -61,8 +61,6 @@ public abstract class StatementBase implements ParseNode { // select * from tbl where a = ? and b = ? // `?` is the placeholder private ArrayList placeholders = new ArrayList<>(); - //internal call like `insert overwrite` not need skipAuth - protected boolean skipAuth = false; protected StatementBase() { } @@ -248,10 +246,6 @@ public void setUserInfo(UserIdentity userInfo) { this.userInfo = userInfo; } - public void setSkipAuth(boolean skipAuth) { - this.skipAuth = skipAuth; - } - /** * Resets the internal analysis state of this node. * For easier maintenance, class members that need to be reset are grouped into diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/AccessControllerManager.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/AccessControllerManager.java index 257a6e88bc5a4d..db88ee34b7d7cb 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/AccessControllerManager.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/AccessControllerManager.java @@ -170,6 +170,9 @@ public boolean checkTblPriv(ConnectContext ctx, TableName tableName, PrivPredica public boolean checkTblPriv(ConnectContext ctx, String qualifiedCtl, String qualifiedDb, String tbl, PrivPredicate wanted) { + if (ctx.isSkipAuth()) { + return true; + } return checkTblPriv(ctx.getCurrentUserIdentity(), qualifiedCtl, qualifiedDb, tbl, wanted); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java index 91be948aa9c8cf..55433da38c9033 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java @@ -190,6 +190,9 @@ public enum ConnectType { private TResultSinkType resultSinkType = TResultSinkType.MYSQL_PROTOCAL; + //internal call like `insert overwrite` not need skipAuth + private boolean skipAuth = false; + public void setUserQueryTimeout(int queryTimeout) { if (queryTimeout > 0) { sessionVariable.setQueryTimeoutS(queryTimeout); @@ -903,5 +906,13 @@ public void setInsertGroupCommit(long tableId, Backend backend) { public Backend getInsertGroupCommit(long tableId) { return insertGroupCommitTableToBeMap.get(tableId); } + + public boolean isSkipAuth() { + return skipAuth; + } + + public void setSkipAuth(boolean skipAuth) { + this.skipAuth = skipAuth; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java index 1d011a790f8224..07354dab11e405 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java @@ -985,6 +985,7 @@ public void analyze(TQueryOptions tQueryOptions) throws UserException, Interrupt queryStmt.getTables(analyzer, false, tableMap, parentViewNameSet); } else if (parsedStmt instanceof InsertOverwriteTableStmt) { InsertOverwriteTableStmt parsedStmt = (InsertOverwriteTableStmt) this.parsedStmt; + parsedStmt.analyze(analyzer); queryStmt = parsedStmt.getQueryStmt(); queryStmt.getTables(analyzer, false, tableMap, parentViewNameSet); } else if (parsedStmt instanceof CreateTableAsSelectStmt) { @@ -2374,6 +2375,7 @@ private void handleCtasRollback(TableName table) { } private void handleIotStmt() { + ConnectContext.get().setSkipAuth(true); InsertOverwriteTableStmt iotStmt = (InsertOverwriteTableStmt) this.parsedStmt; if (iotStmt.getPartitionNames().size() == 0) { // insert overwrite table @@ -2382,6 +2384,7 @@ private void handleIotStmt() { // insert overwrite table with partition handleOverwritePartition(iotStmt); } + ConnectContext.get().setSkipAuth(false); } private void handleOverwriteTable(InsertOverwriteTableStmt iotStmt) { @@ -2393,7 +2396,6 @@ private void handleOverwriteTable(InsertOverwriteTableStmt iotStmt) { // create a tmp table with uuid parsedStmt = new CreateTableLikeStmt(false, tmpTableName, targetTableName, null, false); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); - parsedStmt.setSkipAuth(true); execute(); // if create tmp table err, return if (MysqlStateType.ERR.equals(context.getState().getStateType())) { @@ -2412,7 +2414,6 @@ private void handleOverwriteTable(InsertOverwriteTableStmt iotStmt) { parsedStmt = new NativeInsertStmt(tmpTableName, null, new LabelName(iotStmt.getDb(), iotStmt.getLabel()), iotStmt.getQueryStmt(), iotStmt.getHints(), iotStmt.getCols()); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); - parsedStmt.setSkipAuth(true); execute(); if (MysqlStateType.ERR.equals(context.getState().getStateType())) { LOG.warn("IOT insert data error, stmt={}", parsedStmt.toSql()); @@ -2434,7 +2435,6 @@ private void handleOverwriteTable(InsertOverwriteTableStmt iotStmt) { ops.add(new ReplaceTableClause(tmpTableName.getTbl(), properties)); parsedStmt = new AlterTableStmt(targetTableName, ops); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); - parsedStmt.setSkipAuth(true); execute(); if (MysqlStateType.ERR.equals(context.getState().getStateType())) { LOG.warn("IOT overwrite table error, stmt={}", parsedStmt.toSql()); @@ -2465,7 +2465,6 @@ private void handleOverwritePartition(InsertOverwriteTableStmt iotStmt) { ops.add(new AddPartitionLikeClause(tempPartName, partitionName, true)); parsedStmt = new AlterTableStmt(targetTableName, ops); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); - parsedStmt.setSkipAuth(true); execute(); if (MysqlStateType.ERR.equals(context.getState().getStateType())) { LOG.warn("IOT create tmp partitions error, stmt={}", originStmt.originStmt); @@ -2488,7 +2487,6 @@ private void handleOverwritePartition(InsertOverwriteTableStmt iotStmt) { new LabelName(iotStmt.getDb(), iotStmt.getLabel()), iotStmt.getQueryStmt(), iotStmt.getHints(), iotStmt.getCols()); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); - parsedStmt.setSkipAuth(true); execute(); if (MysqlStateType.ERR.equals(context.getState().getStateType())) { LOG.warn("IOT insert data error, stmt={}", parsedStmt.toSql()); @@ -2511,7 +2509,6 @@ private void handleOverwritePartition(InsertOverwriteTableStmt iotStmt) { new PartitionNames(true, tempPartitionName), properties)); parsedStmt = new AlterTableStmt(targetTableName, ops); parsedStmt.setUserInfo(context.getCurrentUserIdentity()); - parsedStmt.setSkipAuth(true); execute(); if (MysqlStateType.ERR.equals(context.getState().getStateType())) { LOG.warn("IOT overwrite table partitions error, stmt={}", parsedStmt.toSql()); @@ -2530,7 +2527,6 @@ private void handleOverwritePartition(InsertOverwriteTableStmt iotStmt) { private void handleIotRollback(TableName table) { // insert error drop the tmp table DropTableStmt dropTableStmt = new DropTableStmt(true, table, true); - dropTableStmt.setSkipAuth(true); try { Analyzer tempAnalyzer = new Analyzer(Env.getCurrentEnv(), context); dropTableStmt.analyze(tempAnalyzer); @@ -2548,7 +2544,6 @@ private void handleIotPartitionRollback(TableName targetTableName, List List ops = new ArrayList<>(); ops.add(new DropPartitionClause(true, partitionName, true, true)); AlterTableStmt dropTablePartitionStmt = new AlterTableStmt(targetTableName, ops); - dropTablePartitionStmt.setSkipAuth(true); Analyzer tempAnalyzer = new Analyzer(Env.getCurrentEnv(), context); dropTablePartitionStmt.analyze(tempAnalyzer); DdlExecutor.execute(context.getEnv(), dropTablePartitionStmt); From b91ce79a4bff2ac8e827c1e5f21c318b0fb903e9 Mon Sep 17 00:00:00 2001 From: zhangdong <493738387@qq.com> Date: Fri, 20 Oct 2023 21:43:37 +0800 Subject: [PATCH 03/10] 1 --- .../main/java/org/apache/doris/analysis/AlterTableStmt.java | 5 ++--- .../java/org/apache/doris/analysis/CreateTableLikeStmt.java | 2 +- .../main/java/org/apache/doris/analysis/DropTableStmt.java | 4 ++-- .../java/org/apache/doris/analysis/NativeInsertStmt.java | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java index 5e7abc668d4cf8..f2831a628f2319 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java @@ -67,9 +67,8 @@ public void analyze(Analyzer analyzer) throws UserException { tbl.analyze(analyzer); // disallow external catalog Util.prohibitExternalCatalog(tbl.getCtl(), this.getClass().getSimpleName()); - if (!skipAuth && !Env.getCurrentEnv().getAccessManager() - .checkTblPriv(ConnectContext.get(), tbl.getDb(), tbl.getTbl(), - PrivPredicate.ALTER)) { + if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), tbl.getDb(), tbl.getTbl(), + PrivPredicate.ALTER)) { ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "ALTER TABLE", ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(), diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableLikeStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableLikeStmt.java index 269dd10aa9f4bc..a3d64c45907f11 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableLikeStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableLikeStmt.java @@ -95,7 +95,7 @@ public void analyze(Analyzer analyzer) throws UserException { // disallow external catalog Util.prohibitExternalCatalog(existedTableName.getCtl(), this.getClass().getSimpleName()); ConnectContext ctx = ConnectContext.get(); - if (!skipAuth && !Env.getCurrentEnv().getAccessManager().checkTblPriv(ctx, existedTableName.getDb(), + if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ctx, existedTableName.getDb(), existedTableName.getTbl(), PrivPredicate.SELECT)) { ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "SELECT"); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java index 93cd7d7ba89466..a8b091705e4d3b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java @@ -87,8 +87,8 @@ public void analyze(Analyzer analyzer) throws UserException { Util.prohibitExternalCatalog(tableName.getCtl(), this.getClass().getSimpleName()); // check access - if (!skipAuth && !Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), tableName.getDb(), - tableName.getTbl(), PrivPredicate.DROP)) { + if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), tableName.getDb(), + tableName.getTbl(), PrivPredicate.DROP)) { ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "DROP"); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java index 3b07cbdd6d2436..d357c2129ca237 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java @@ -279,7 +279,7 @@ public void getTables(Analyzer analyzer, Map tableMap, Set Date: Fri, 20 Oct 2023 22:07:59 +0800 Subject: [PATCH 04/10] 1 --- .../analysis/InsertOverwriteTableStmt.java | 2 +- .../commands/InsertIntoTableCommand.java | 31 +++++++++++++------ .../org/apache/doris/qe/StmtExecutor.java | 19 +++++++----- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java index 4512603b31a777..04e28c7fa6c263 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertOverwriteTableStmt.java @@ -74,7 +74,7 @@ public List getPartitionNames() { @Override public void analyze(Analyzer analyzer) throws UserException { - if (!skipAuth && !Env.getCurrentEnv().getAccessManager() + if (!Env.getCurrentEnv().getAccessManager() .checkTblPriv(ConnectContext.get(), getDb(), getTbl(), PrivPredicate.LOAD)) { ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "LOAD", ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(), diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/InsertIntoTableCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/InsertIntoTableCommand.java index 780ba178f09e97..2f49388b32fa9e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/InsertIntoTableCommand.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/InsertIntoTableCommand.java @@ -29,9 +29,11 @@ import org.apache.doris.catalog.OlapTable; import org.apache.doris.common.DdlException; import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; import org.apache.doris.common.UserException; import org.apache.doris.common.util.ProfileManager.ProfileType; import org.apache.doris.datasource.InternalCatalog; +import org.apache.doris.mysql.privilege.PrivPredicate; import org.apache.doris.nereids.NereidsPlanner; import org.apache.doris.nereids.analyzer.UnboundOlapTableSink; import org.apache.doris.nereids.exceptions.AnalysisException; @@ -189,7 +191,6 @@ public void run(ConnectContext ctx, StmtExecutor executor) throws Exception { * @param ctx ctx * @param executor executor * @param physicalOlapTableSink physicalOlapTableSink - * * @throws Exception Exception */ public void dealOverwrite(ConnectContext ctx, StmtExecutor executor, @@ -197,16 +198,28 @@ public void dealOverwrite(ConnectContext ctx, StmtExecutor executor, OlapTable targetTable = physicalOlapTableSink.getTargetTable(); TableName tableName = new TableName(InternalCatalog.INTERNAL_CATALOG_NAME, targetTable.getQualifiedDbName(), targetTable.getName()); - List partitionNames = ((UnboundOlapTableSink) logicalQuery).getPartitions(); - if (CollectionUtils.isEmpty(partitionNames)) { - partitionNames = Lists.newArrayList(targetTable.getPartitionNames()); + if (!Env.getCurrentEnv().getAccessManager() + .checkTblPriv(ConnectContext.get(), tableName.getDb(), tableName.getTbl(), PrivPredicate.LOAD)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "LOAD", + ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(), + tableName.getDb() + ": " + tableName.getTbl()); } - List tempPartitionNames = addTempPartition(ctx, tableName, partitionNames); - boolean insertRes = insertInto(ctx, executor, tempPartitionNames, tableName); - if (!insertRes) { - return; + ConnectContext.get().setSkipAuth(true); + try { + List partitionNames = ((UnboundOlapTableSink) logicalQuery).getPartitions(); + if (CollectionUtils.isEmpty(partitionNames)) { + partitionNames = Lists.newArrayList(targetTable.getPartitionNames()); + } + List tempPartitionNames = addTempPartition(ctx, tableName, partitionNames); + boolean insertRes = insertInto(ctx, executor, tempPartitionNames, tableName); + if (!insertRes) { + return; + } + replacePartition(ctx, tableName, partitionNames, tempPartitionNames); + } finally { + ConnectContext.get().setSkipAuth(false); } - replacePartition(ctx, tableName, partitionNames, tempPartitionNames); + } /** diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java index 07354dab11e405..dc3c8acf34f657 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java @@ -2376,15 +2376,18 @@ private void handleCtasRollback(TableName table) { private void handleIotStmt() { ConnectContext.get().setSkipAuth(true); - InsertOverwriteTableStmt iotStmt = (InsertOverwriteTableStmt) this.parsedStmt; - if (iotStmt.getPartitionNames().size() == 0) { - // insert overwrite table - handleOverwriteTable(iotStmt); - } else { - // insert overwrite table with partition - handleOverwritePartition(iotStmt); + try { + InsertOverwriteTableStmt iotStmt = (InsertOverwriteTableStmt) this.parsedStmt; + if (iotStmt.getPartitionNames().size() == 0) { + // insert overwrite table + handleOverwriteTable(iotStmt); + } else { + // insert overwrite table with partition + handleOverwritePartition(iotStmt); + } + } finally { + ConnectContext.get().setSkipAuth(false); } - ConnectContext.get().setSkipAuth(false); } private void handleOverwriteTable(InsertOverwriteTableStmt iotStmt) { From 09d9bf006d8a775c555c830b49e5c24fd1c2c499 Mon Sep 17 00:00:00 2001 From: zhangdong <493738387@qq.com> Date: Thu, 26 Oct 2023 21:05:09 +0800 Subject: [PATCH 05/10] 1 --- .../plans/commands/InsertIntoTableCommand.java | 16 ++++++++++------ .../java/org/apache/doris/qe/ConnectContext.java | 5 ++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/InsertIntoTableCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/InsertIntoTableCommand.java index 2f49388b32fa9e..83273dc696199b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/InsertIntoTableCommand.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/InsertIntoTableCommand.java @@ -136,6 +136,16 @@ public void run(ConnectContext ctx, StmtExecutor executor) throws Exception { Preconditions.checkArgument(plan.isPresent(), "insert into command must contain OlapTableSinkNode"); PhysicalOlapTableSink physicalOlapTableSink = ((PhysicalOlapTableSink) plan.get()); + OlapTable targetTable = physicalOlapTableSink.getTargetTable(); + // check auth + if (!Env.getCurrentEnv().getAccessManager() + .checkTblPriv(ConnectContext.get(), targetTable.getQualifiedDbName(), targetTable.getName(), + PrivPredicate.LOAD)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "LOAD", + ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(), + targetTable.getQualifiedDbName() + ": " + targetTable.getName()); + } + if (isOverwrite) { dealOverwrite(ctx, executor, physicalOlapTableSink); return; @@ -198,12 +208,6 @@ public void dealOverwrite(ConnectContext ctx, StmtExecutor executor, OlapTable targetTable = physicalOlapTableSink.getTargetTable(); TableName tableName = new TableName(InternalCatalog.INTERNAL_CATALOG_NAME, targetTable.getQualifiedDbName(), targetTable.getName()); - if (!Env.getCurrentEnv().getAccessManager() - .checkTblPriv(ConnectContext.get(), tableName.getDb(), tableName.getTbl(), PrivPredicate.LOAD)) { - ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "LOAD", - ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(), - tableName.getDb() + ": " + tableName.getTbl()); - } ConnectContext.get().setSkipAuth(true); try { List partitionNames = ((UnboundOlapTableSink) logicalQuery).getPartitions(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java index 55433da38c9033..d791fed53d4740 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java @@ -190,7 +190,10 @@ public enum ConnectType { private TResultSinkType resultSinkType = TResultSinkType.MYSQL_PROTOCAL; - //internal call like `insert overwrite` not need skipAuth + //internal call like `insert overwrite` need skipAuth + // For example, `insert overwrite` only requires load permission, + // but the internal implementation will call the logic of `AlterTable`. + // In this case, `skipAuth` needs to be set to `true` to skip the permission check of `AlterTable` private boolean skipAuth = false; public void setUserQueryTimeout(int queryTimeout) { From 01848f1b8e18667bd56a69e0d6ac70c6f9c6514a Mon Sep 17 00:00:00 2001 From: zhangdong <493738387@qq.com> Date: Thu, 26 Oct 2023 21:27:17 +0800 Subject: [PATCH 06/10] 1 --- .../insert_into_table/insert_auth.groovy | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy diff --git a/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy b/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy new file mode 100644 index 00000000000000..6f02bc6c1c9cfc --- /dev/null +++ b/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy @@ -0,0 +1,71 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +suite('nereids_insert_auth') { + sql 'set enable_nereids_planner=true' + sql 'set enable_fallback_to_original_planner=false' + sql 'set enable_nereids_dml=true' + sql 'set enable_strict_consistency_dml=true' + + def db = 'nereids_insert_auth_db' + sql 'drop database if exists ${db}' + sql 'create database ${db}' + sql 'use ${db}' + + def t1 = 't1' + + sql "drop table if exists ${t1}" + + sql """ + create table ${t1} ( + id int, + c1 bigint + ) + distributed by hash(id) buckets 2 + properties( + 'replication_num'='1' + ); + """ + + String user = "nereids_insert_auth_user"; + String pwd = '123456'; + def tokens = context.config.jdbcUrl.split('/') + def url = tokens[0] + "//" + tokens[2] + "/" + "information_schema" + "?" + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + + connect(user=user, password="${pwd}", url=url) { + try { + sql """ insert into ${db}.${t1} values (1, 1) """ + fail() + } catch (Exception e) { + log.info(e.getMessage()) + } + } + + sql """GRANT LOAD_PRIV ON ${db}.${t1} TO ${user}""" + + connect(user=user, password="${pwd}", url=url) { + try { + sql """ insert into ${db}.${t1} values (1, 1) """ + sql """ insert overwrite table ${db}.${t1} values (1, 1) """ + } catch (Exception e) { + fail() + } + } + +} \ No newline at end of file From f29fcc1a36512e171ec486b1e210c30236cee3db Mon Sep 17 00:00:00 2001 From: zhangdong <493738387@qq.com> Date: Thu, 26 Oct 2023 21:37:33 +0800 Subject: [PATCH 07/10] 1 --- .../suites/nereids_p0/insert_into_table/insert_auth.groovy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy b/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy index 6f02bc6c1c9cfc..758f05514ae80d 100644 --- a/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy +++ b/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy @@ -22,9 +22,9 @@ suite('nereids_insert_auth') { sql 'set enable_strict_consistency_dml=true' def db = 'nereids_insert_auth_db' - sql 'drop database if exists ${db}' - sql 'create database ${db}' - sql 'use ${db}' + sql "drop database if exists ${db}" + sql "create database ${db}"" + sql "use ${db}" def t1 = 't1' From 74e631b9981fbb8e8300de96901e4b0a01ea6eda Mon Sep 17 00:00:00 2001 From: zhangdong <493738387@qq.com> Date: Thu, 26 Oct 2023 21:39:21 +0800 Subject: [PATCH 08/10] 1 --- .../suites/nereids_p0/insert_into_table/insert_auth.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy b/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy index 758f05514ae80d..3a698e5dbe6896 100644 --- a/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy +++ b/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy @@ -23,7 +23,7 @@ suite('nereids_insert_auth') { def db = 'nereids_insert_auth_db' sql "drop database if exists ${db}" - sql "create database ${db}"" + sql "create database ${db}" sql "use ${db}" def t1 = 't1' From b5e53cbab48d42580465281bd6d30f6c97bb3c43 Mon Sep 17 00:00:00 2001 From: zhangdong <493738387@qq.com> Date: Thu, 26 Oct 2023 21:44:06 +0800 Subject: [PATCH 09/10] 1 --- .../nereids_p0/insert_into_table/insert_auth.groovy | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy b/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy index 3a698e5dbe6896..2750807e976d61 100644 --- a/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy +++ b/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy @@ -62,10 +62,16 @@ suite('nereids_insert_auth') { connect(user=user, password="${pwd}", url=url) { try { sql """ insert into ${db}.${t1} values (1, 1) """ - sql """ insert overwrite table ${db}.${t1} values (1, 1) """ } catch (Exception e) { fail() } } + connect(user=user, password="${pwd}", url=url) { + try { + sql """ insert overwrite table ${db}.${t1} values (2, 2) """ + } catch (Exception e) { + fail() + } + } } \ No newline at end of file From eb70b94e0d613278e68edb5bf41e92af9beed4f7 Mon Sep 17 00:00:00 2001 From: zhangdong <493738387@qq.com> Date: Thu, 26 Oct 2023 21:55:31 +0800 Subject: [PATCH 10/10] 1 --- .../nereids_p0/insert_into_table/insert_auth.groovy | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy b/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy index 2750807e976d61..1a333d41d3269e 100644 --- a/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy +++ b/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy @@ -63,15 +63,17 @@ suite('nereids_insert_auth') { try { sql """ insert into ${db}.${t1} values (1, 1) """ } catch (Exception e) { + log.info(e.getMessage()) fail() } } connect(user=user, password="${pwd}", url=url) { - try { - sql """ insert overwrite table ${db}.${t1} values (2, 2) """ - } catch (Exception e) { - fail() - } + try { + sql """ insert overwrite table ${db}.${t1} values (2, 2) """ + } catch (Exception e) { + log.info(e.getMessage()) + fail() } + } } \ No newline at end of file