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]

Reply via email to