Repository: incubator-sentry Updated Branches: refs/heads/master 66e425f20 -> 1785f0ee5
SENTRY-314: Metastore plugin should verify the storage descriptor before referencing ( Prasad Mujumdar via Sravya Tirukkovalur) Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/1785f0ee Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/1785f0ee Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/1785f0ee Branch: refs/heads/master Commit: 1785f0ee59dacd6e26eb4596b79907f6b778d3d8 Parents: 66e425f Author: Sravya Tirukkovalur <[email protected]> Authored: Thu Jun 26 14:51:59 2014 -0700 Committer: Sravya Tirukkovalur <[email protected]> Committed: Thu Jun 26 14:51:59 2014 -0700 ---------------------------------------------------------------------- .../metastore/MetastoreAuthzBinding.java | 48 +++++++++++++------ ...actMetastoreTestWithStaticConfiguration.java | 2 +- .../e2e/metastore/TestMetastoreEndToEnd.java | 49 ++++++++++++++++++++ 3 files changed, 83 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/1785f0ee/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBinding.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBinding.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBinding.java index 5d7d9a4..5c43095 100644 --- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBinding.java +++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBinding.java @@ -35,6 +35,7 @@ import org.apache.hadoop.hive.metastore.MetaStorePreEventListener; import org.apache.hadoop.hive.metastore.api.InvalidOperationException; import org.apache.hadoop.hive.metastore.api.MetaException; import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; +import org.apache.hadoop.hive.metastore.api.StorageDescriptor; import org.apache.hadoop.hive.metastore.events.PreAddPartitionEvent; import org.apache.hadoop.hive.metastore.events.PreAlterPartitionEvent; import org.apache.hadoop.hive.metastore.events.PreAlterTableEvent; @@ -164,6 +165,9 @@ public class MetastoreAuthzBinding extends MetaStorePreEventListener { public void onEvent(PreEventContext context) throws MetaException, NoSuchObjectException, InvalidOperationException { + if (!needsAuthorization(getUserName())) { + return; + } switch (context.getEventType()) { case CREATE_TABLE: authorizeCreateTable((PreCreateTableEvent) context); @@ -221,8 +225,8 @@ public class MetastoreAuthzBinding extends MetaStorePreEventListener { if (!StringUtils.isEmpty(context.getTable().getSd().getLocation())) { String uriPath; try { - uriPath = PathUtils.parseDFSURI(warehouseDir, context.getTable().getSd() - .getLocation()); + uriPath = PathUtils.parseDFSURI(warehouseDir, + getSdLocation(context.getTable().getSd())); } catch(URISyntaxException e) { throw new MetaException(e.getMessage()); } @@ -262,10 +266,10 @@ public class MetastoreAuthzBinding extends MetaStorePreEventListener { String oldLocationUri; String newLocationUri; try { - oldLocationUri = PathUtils.parseDFSURI(warehouseDir, context - .getOldTable().getSd().getLocation()); - newLocationUri = PathUtils.parseDFSURI(warehouseDir, context - .getNewTable().getSd().getLocation()); + oldLocationUri = PathUtils.parseDFSURI(warehouseDir, + getSdLocation(context.getOldTable().getSd())); + newLocationUri = PathUtils.parseDFSURI(warehouseDir, + getSdLocation(context.getNewTable().getSd())); } catch (URISyntaxException e) { throw new MetaException(e.getMessage()); } @@ -288,7 +292,7 @@ public class MetastoreAuthzBinding extends MetaStorePreEventListener { .getDbName(), context.getPartition().getTableName()); // check if we need to validate URI permissions when storage location is // non-default, ie something not under the parent table - String partitionLocation = context.getPartition().getSd().getLocation(); + String partitionLocation = getSdLocation(context.getPartition().getSd()); if (!StringUtils.isEmpty(partitionLocation)) { String tableLocation = context .getHandler() @@ -335,7 +339,7 @@ public class MetastoreAuthzBinding extends MetaStorePreEventListener { */ HierarcyBuilder inputBuilder = new HierarcyBuilder().addTableToOutput( getAuthServer(), context.getDbName(), context.getTableName()); - String partitionLocation = context.getNewPartition().getSd().getLocation(); + String partitionLocation = getSdLocation(context.getNewPartition().getSd()); if (!StringUtils.isEmpty(partitionLocation)) { String uriPath; try { @@ -372,13 +376,9 @@ public class MetastoreAuthzBinding extends MetaStorePreEventListener { throws InvalidOperationException { try { HiveAuthzBinding hiveAuthzBinding = getHiveAuthzBinding(); - String userName = ShimLoader.getHadoopShims().getUGIForConf(hiveConf) - .getShortUserName(); - if (needsAuthorization(userName)) { - hiveAuthzBinding.authorize(hiveOp, HiveAuthzPrivilegesMap - .getHiveAuthzPrivileges(hiveOp), new Subject(userName), - inputHierarchy, outputHierarchy); - } + hiveAuthzBinding.authorize(hiveOp, HiveAuthzPrivilegesMap + .getHiveAuthzPrivileges(hiveOp), new Subject(getUserName()), + inputHierarchy, outputHierarchy); } catch (AuthorizationException e1) { throw invalidOperationException(e1); } catch (LoginException e1) { @@ -414,4 +414,22 @@ public class MetastoreAuthzBinding extends MetaStorePreEventListener { return hiveAuthzBinding; } + private String getUserName() throws MetaException { + try { + return ShimLoader.getHadoopShims().getUGIForConf(hiveConf) + .getShortUserName(); + } catch (LoginException e) { + throw new MetaException("Failed to get username " + e.getMessage()); + } catch (IOException e) { + throw new MetaException("Failed to get username " + e.getMessage()); + } + } + + private String getSdLocation(StorageDescriptor sd) { + if (sd == null) { + return ""; + } else { + return sd.getLocation(); + } + } } http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/1785f0ee/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java index 549a0fa..45d24f9 100644 --- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java @@ -152,7 +152,7 @@ public abstract class AbstractMetastoreTestWithStaticConfiguration extends List<String> ptnVals, Table tbl) { Partition part = makeMetastoreBasePartitionObject(dbName, tblName, ptnVals, tbl); - part.getSd().setLocation(""); + part.getSd().setLocation(null); return part; } http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/1785f0ee/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/TestMetastoreEndToEnd.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/TestMetastoreEndToEnd.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/TestMetastoreEndToEnd.java index 52a2b1e..b376c37 100644 --- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/TestMetastoreEndToEnd.java +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/TestMetastoreEndToEnd.java @@ -22,8 +22,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.File; +import java.io.FileOutputStream; import java.util.ArrayList; +import junit.framework.Assert; + import org.apache.hadoop.hive.metastore.HiveMetaStoreClient; import org.apache.hadoop.hive.metastore.api.FieldSchema; import org.apache.hadoop.hive.metastore.api.MetaException; @@ -38,11 +41,13 @@ import org.junit.Before; import org.junit.Test; import com.google.common.collect.Lists; +import com.google.common.io.Resources; public class TestMetastoreEndToEnd extends AbstractMetastoreTestWithStaticConfiguration { private PolicyFile policyFile; + private File dataFile; private static final String dbName = "db_1"; private static final String db_all_role = "all_db1"; private static final String uri_role = "uri_role"; @@ -77,6 +82,11 @@ public class TestMetastoreEndToEnd extends .setUserGroupMapping(StaticUserGroup.getStaticMapping()); writePolicyFile(policyFile); + dataFile = new File(dataDir, SINGLE_TYPE_DATA_FILE_NAME); + FileOutputStream to = new FileOutputStream(dataFile); + Resources.copy(Resources.getResource(SINGLE_TYPE_DATA_FILE_NAME), to); + to.close(); + HiveMetaStoreClient client = context.getMetaStoreClient(ADMIN1); client.dropDatabase(dbName, true, true, true); createMetastoreDB(client, dbName); @@ -462,4 +472,43 @@ public class TestMetastoreEndToEnd extends } + /** + * Verify data load into new partition using INSERT .. PARTITION statement + */ + @Test + public void testPartionInsert() throws Exception { + String partVal1 = "part1", partVal2 = "part2", partVal3 = "part3"; + + policyFile.addRolesToGroup(USERGROUP1, uri_role).addPermissionsToRole( + uri_role, "server=server1->uri=file://" + dataFile.getPath()); + writePolicyFile(policyFile); + + execHiveSQL("CREATE TABLE " + dbName + "." + tabName1 + + " (id int) PARTITIONED BY (part_col string)", USER1_1); + execHiveSQL("CREATE TABLE " + dbName + "." + tabName2 + " (id int)", + USER1_1); + execHiveSQL("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + + "' INTO TABLE " + dbName + "." + tabName2, USER1_1); + + // verify that user with DB all can add partition using INSERT .. PARTITION + execHiveSQL("INSERT OVERWRITE TABLE " + dbName + "." + tabName1 + + " PARTITION (part_col='" + partVal1 + "') SELECT * FROM " + dbName + + "." + tabName2, USER1_1); + verifyPartitionExists(dbName, tabName1, partVal1); + + // verify that user with Table all can add partition using INSERT + execHiveSQL("INSERT OVERWRITE TABLE " + dbName + "." + tabName1 + + " PARTITION (part_col='" + partVal2 + "') SELECT * FROM " + dbName + + "." + tabName2, USER2_1); + verifyPartitionExists(dbName, tabName1, partVal2); + } + + private void verifyPartitionExists(String dbName, String tabName, + String partVal) throws Exception { + HiveMetaStoreClient client = context.getMetaStoreClient(ADMIN1); + Partition newPartition = client.getPartition(dbName, tabName, + Lists.newArrayList(partVal)); + Assert.assertNotNull(newPartition); + client.close(); + } }
