This is an automated email from the ASF dual-hosted git repository.
kxiao pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.0 by this push:
new 05ec11c703f [fix](auth)fix create table like need create_priv of
existed table #37879 #25711 (#38569)
05ec11c703f is described below
commit 05ec11c703f7f8a94353cb48608df907525a8b10
Author: zhangdong <[email protected]>
AuthorDate: Sat Aug 3 06:23:38 2024 +0800
[fix](auth)fix create table like need create_priv of existed table #37879
#25711 (#38569)
---
.../apache/doris/datasource/InternalCatalog.java | 24 +++++--
.../mysql/privilege/AccessControllerManager.java | 3 +
.../java/org/apache/doris/qe/ConnectContext.java | 14 ++++
.../java/org/apache/doris/qe/StmtExecutor.java | 21 ++++--
.../insert_into_table/insert_auth.groovy | 79 ++++++++++++++++++++++
5 files changed, 128 insertions(+), 13 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
index 285d60d3316..60cda366e77 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
@@ -186,6 +186,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@@ -1136,6 +1137,8 @@ public class InternalCatalog implements
CatalogIf<Database> {
}
public void createTableLike(CreateTableLikeStmt stmt) throws DdlException {
+ ConnectContext ctx = ConnectContext.get();
+ Objects.requireNonNull(ctx, "ConnectContext.get() can not be null.");
try {
DatabaseIf db = getDbOrDdlException(stmt.getExistedDbName());
TableIf table =
db.getTableOrDdlException(stmt.getExistedTableName());
@@ -1169,14 +1172,23 @@ public class InternalCatalog implements
CatalogIf<Database> {
} finally {
table.readUnlock();
}
- CreateTableStmt parsedCreateTableStmt = (CreateTableStmt)
SqlParserUtils.parseAndAnalyzeStmt(
- createTableStmt.get(0), ConnectContext.get());
- parsedCreateTableStmt.setTableName(stmt.getTableName());
- parsedCreateTableStmt.setIfNotExists(stmt.isIfNotExists());
- createTable(parsedCreateTableStmt);
+ boolean originalSkipAuth = ctx.isSkipAuth();
+ try {
+ // analyze CreateTableStmt will check create_priv of
existedTable, create table like only need
+ // create_priv of newTable, and select_priv of existedTable,
and priv check has done in
+ // CreateTableStmt/CreateTableCommand, so we skip it
+ ctx.setSkipAuth(true);
+ CreateTableStmt parsedCreateTableStmt = (CreateTableStmt)
SqlParserUtils.parseAndAnalyzeStmt(
+ createTableStmt.get(0), ctx);
+ parsedCreateTableStmt.setTableName(stmt.getTableName());
+ parsedCreateTableStmt.setIfNotExists(stmt.isIfNotExists());
+ createTable(parsedCreateTableStmt);
+ } finally {
+ ctx.setSkipAuth(originalSkipAuth);
+ }
} catch (UserException e) {
throw new DdlException("Failed to execute CREATE TABLE LIKE " +
stmt.getExistedTableName() + ". Reason: "
- + e.getMessage());
+ + e.getMessage(), e);
}
}
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 257a6e88bc5..db88ee34b7d 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 class AccessControllerManager {
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 9a2dcb176e4..a10f8a49a39 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
@@ -194,6 +194,12 @@ public class ConnectContext {
// it's default thread-safe
private boolean isProxy = false;
+ //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) {
if (queryTimeout > 0) {
sessionVariable.setQueryTimeoutS(queryTimeout);
@@ -938,5 +944,13 @@ public class ConnectContext {
public boolean isProxy() {
return isProxy;
}
+
+ 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 59475658783..8dda65e81f7 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
@@ -1068,6 +1068,7 @@ public class StmtExecutor {
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) {
@@ -2506,13 +2507,19 @@ public class StmtExecutor {
}
private void handleIotStmt() {
- InsertOverwriteTableStmt iotStmt = (InsertOverwriteTableStmt)
this.parsedStmt;
- if (iotStmt.getPartitionNames().size() == 0) {
- // insert overwrite table
- handleOverwriteTable(iotStmt);
- } else {
- // insert overwrite table with partition
- handleOverwritePartition(iotStmt);
+ boolean originalSkipAuth = context.isSkipAuth();
+ context.setSkipAuth(true);
+ 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 {
+ context.setSkipAuth(originalSkipAuth);
}
}
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 00000000000..1a333d41d32
--- /dev/null
+++ b/regression-test/suites/nereids_p0/insert_into_table/insert_auth.groovy
@@ -0,0 +1,79 @@
+// 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) """
+ } 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) {
+ log.info(e.getMessage())
+ fail()
+ }
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]