This is an automated email from the ASF dual-hosted git repository.

dkuzmenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git


The following commit(s) were added to refs/heads/master by this push:
     new ff8e710013b HIVE-28804: The user does not have the permission for the 
table hdfs, but can delete the metadata (#5975)
ff8e710013b is described below

commit ff8e710013b941aaebfebc326e3930c80a62268e
Author: zxl-333 <zengxinliang...@163.com>
AuthorDate: Wed Jul 23 21:53:22 2025 +0800

    HIVE-28804: The user does not have the permission for the table hdfs, but 
can delete the metadata (#5975)
---
 .../metastore/TestHiveMetaStoreAuthorizer.java     | 33 ++++++++++++++++++++--
 .../apache/hadoop/hive/metastore/HMSHandler.java   | 18 ++++++++----
 2 files changed, 44 insertions(+), 7 deletions(-)

diff --git 
a/ql/src/test/org/apache/hadoop/hive/ql/security/authorization/plugin/metastore/TestHiveMetaStoreAuthorizer.java
 
b/ql/src/test/org/apache/hadoop/hive/ql/security/authorization/plugin/metastore/TestHiveMetaStoreAuthorizer.java
index 52cc1d10726..8975c605c17 100644
--- 
a/ql/src/test/org/apache/hadoop/hive/ql/security/authorization/plugin/metastore/TestHiveMetaStoreAuthorizer.java
+++ 
b/ql/src/test/org/apache/hadoop/hive/ql/security/authorization/plugin/metastore/TestHiveMetaStoreAuthorizer.java
@@ -23,6 +23,7 @@
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hive.common.FileUtils;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.metastore.ColumnType;
@@ -70,6 +71,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 /*
 Test whether HiveAuthorizer for MetaStore operation is trigger and 
HiveMetaStoreAuthzInfo is created by HiveMetaStoreAuthorizer
@@ -94,6 +96,7 @@ public class TestHiveMetaStoreAuthorizer {
   private RawStore rawStore;
   private Configuration conf;
   private HMSHandler hmsHandler;
+  private Warehouse wh;
 
   static HiveAuthorizer mockHiveAuthorizer;
   static final List<String> allowedUsers = Arrays.asList("sam", "rob");
@@ -116,9 +119,10 @@ public void setUp() throws Exception {
     conf.set("hadoop.proxyuser.hive.users", "*");
 
     MetaStoreTestUtils.setConfForStandloneMode(conf);
+    wh = Mockito.spy(new Warehouse(conf));
 
     hmsHandler = new HMSHandler("test", conf);
-    hmsHandler.init();
+    hmsHandler.init(wh);
     rawStore = new ObjectStore();
     rawStore.setConf(hmsHandler.getConf());
     // Create the 'hive' catalog with new warehouse directory
@@ -128,7 +132,7 @@ public void setUp() throws Exception {
       dropDcReq.setIfNotExists(true);
       dropDcReq.setCheckReferences(true);
       hmsHandler.drop_dataconnector_req(dropDcReq);
-      hmsHandler.drop_table(dbName, tblName, true);
+      hmsHandler.drop_table("default", tblName, true);
       hmsHandler.drop_database(dbName, true, false);
       hmsHandler.drop_catalog(new DropCatalogRequest(catalogName));
       FileUtils.deleteDirectory(new File(TEST_DATA_DIR));
@@ -829,4 +833,29 @@ public void testUnAuthorizedCause() {
       }
     }
   }
+
+  @Test
+  public void testDropTableNoTablePathWritePermissionShouldFail() throws 
Exception {
+    UserGroupInformation.setLoginUser(
+            UserGroupInformation.createRemoteUser(authorizedUser));
+
+    Table table = new TableBuilder()
+        .setTableName(tblName)
+        .addCol("name", ColumnType.STRING_TYPE_NAME)
+        .setOwner(authorizedUser)
+        .build(conf);
+    hmsHandler.create_table(table);
+
+    Path tablePath = new Path(table.getSd().getLocation());
+    when(wh.isWritable(Mockito.eq(tablePath.getParent()))).thenReturn(true);
+    when(wh.isWritable(Mockito.eq(tablePath))).thenReturn(false);
+
+    try {
+      hmsHandler.drop_table("default", tblName, true);
+    } catch (MetaException e) {
+      String expected = "%s metadata not deleted since %s is not writable by 
%s"
+          .formatted("Table", tablePath.toString(), authorizedUser);
+      assertEquals(expected, e.getMessage());
+    }
+  }
 }
diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
index fff5c7d660c..e4bcb21d6a4 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
@@ -311,6 +311,11 @@ public List<MetaStoreEventListener> getListeners() {
 
   @Override
   public void init() throws MetaException {
+    init(new Warehouse(conf));
+  }
+
+  @VisibleForTesting
+  public void init(Warehouse wh) throws MetaException {
     Metrics.initialize(conf);
     initListeners = MetaStoreServerUtils.getMetaStoreListeners(
         MetaStoreInitListener.class, conf, MetastoreConf.getVar(conf, 
ConfVars.INIT_HOOKS));
@@ -322,7 +327,7 @@ public void init() throws MetaException {
     String alterHandlerName = MetastoreConf.getVar(conf, 
ConfVars.ALTER_HANDLER);
     alterHandler = ReflectionUtils.newInstance(JavaUtils.getClass(
         alterHandlerName, AlterHandler.class), conf);
-    wh = new Warehouse(conf);
+    this.wh = wh;
 
     synchronized (HMSHandler.class) {
       if (currentUrl == null || 
!currentUrl.equals(MetaStoreInit.getConnectionURL(conf))) {
@@ -3047,11 +3052,14 @@ private boolean drop_table_core(final RawStore ms, 
final String catName, final S
       tableDataShouldBeDeleted = checkTableDataShouldBeDeleted(tbl, 
deleteData);
       if (tableDataShouldBeDeleted && tbl.getSd().getLocation() != null) {
         tblPath = new Path(tbl.getSd().getLocation());
+        String target = indexName == null ? "Table" : "Index table";
+        // HIVE-28804 drop table user should have table path and parent path 
permission
         if (!wh.isWritable(tblPath.getParent())) {
-          String target = indexName == null ? "Table" : "Index table";
-          throw new MetaException(target + " metadata not deleted since " +
-              tblPath.getParent() + " is not writable by " +
-              SecurityUtils.getUser());
+          throw new MetaException("%s metadata not deleted since %s is not 
writable by %s"
+              .formatted(target, tblPath.getParent(), 
SecurityUtils.getUser()));
+        } else if (!wh.isWritable(tblPath)) {
+          throw new MetaException("%s metadata not deleted since %s is not 
writable by %s"
+              .formatted(target, tblPath, SecurityUtils.getUser()));
         }
       }
 

Reply via email to