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())); } }