You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by ka...@apache.org on 2020/01/02 16:45:11 UTC

[sentry] branch branch-2.2.0 updated: SENTRY-2540: Only use SELECT action for filter SHOW DATABASES and SHOW TABLES command based on configuration (Na Li, reviewed by Kalyan Kumar Kalvagadda)

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

kalyan pushed a commit to branch branch-2.2.0
in repository https://gitbox.apache.org/repos/asf/sentry.git


The following commit(s) were added to refs/heads/branch-2.2.0 by this push:
     new 641d7d8  SENTRY-2540: Only use SELECT action for filter SHOW DATABASES and SHOW TABLES command based on configuration (Na Li, reviewed by Kalyan Kumar Kalvagadda)
641d7d8 is described below

commit 641d7d8c6042310884806526dc273b3116b169c8
Author: lina.li <li...@cloudera.com>
AuthorDate: Fri Dec 20 16:48:18 2019 -0600

    SENTRY-2540: Only use SELECT action for filter SHOW DATABASES and SHOW TABLES command based on configuration (Na Li, reviewed by Kalyan Kumar Kalvagadda)
---
 .../sentry/binding/hive/conf/HiveAuthzConf.java    |  2 +
 .../hive/authz/MetastoreAuthzObjectFilter.java     | 48 +++++++++++++++++--
 .../hive/AbstractTestWithStaticConfiguration.java  |  9 ++++
 .../tests/e2e/hive/TestShowMetadataPrivileges.java | 51 +++++++++++++++++---
 .../TestShowMetadataPrivilegesOnSelectOnly.java    | 54 ++++++++++++++++++++++
 5 files changed, 154 insertions(+), 10 deletions(-)

diff --git a/sentry-binding/sentry-binding-hive-conf/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java b/sentry-binding/sentry-binding-hive-conf/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
index d555027..95e6ef1 100644
--- a/sentry-binding/sentry-binding-hive-conf/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
+++ b/sentry-binding/sentry-binding-hive-conf/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
@@ -103,6 +103,8 @@ public class HiveAuthzConf extends Configuration {
                 "org.apache.sentry.binding.hive.SentryIniPolicyFileFormatter"),
         AUTHZ_SERVER_NAME("sentry.hive.server", SENTRY_HIVE_SERVER_DEFAULT),
         AUTHZ_RESTRICT_DEFAULT_DB("sentry.hive.restrict.defaultDB", "false"),
+        SHOWDATABASES_ON_SELECT_ONLY("sentry.showdatabases.select.only", "false"),
+        SHOWTABLES_ON_SELECT_ONLY("sentry.showtables.select.only", "false"),
         SENTRY_TESTING_MODE("sentry.hive.testing.mode", "false"),
         AUTHZ_ALLOW_HIVE_IMPERSONATION("sentry.hive.allow.hive.impersonation", "false"),
         AUTHZ_ONFAILURE_HOOKS("sentry.hive.failure.hooks", ""),
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/MetastoreAuthzObjectFilter.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/MetastoreAuthzObjectFilter.java
index e64d1a5..9f323f4 100644
--- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/MetastoreAuthzObjectFilter.java
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/MetastoreAuthzObjectFilter.java
@@ -30,6 +30,7 @@ import org.apache.hadoop.hive.ql.plan.HiveOperation;
 import org.apache.sentry.binding.hive.authz.HiveAuthzPrivileges.HiveOperationScope;
 import org.apache.sentry.binding.hive.authz.HiveAuthzPrivileges.HiveOperationType;
 import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
+import org.apache.sentry.binding.hive.conf.HiveAuthzConf.AuthzConfVars;
 import org.apache.sentry.core.common.Subject;
 import org.apache.sentry.core.model.db.Column;
 import org.apache.sentry.core.model.db.DBModelAction;
@@ -67,6 +68,15 @@ public class MetastoreAuthzObjectFilter<T> {
     .setOperationType(HiveOperationType.QUERY)
     .build();
 
+  private static final HiveAuthzPrivileges LIST_DATABASES_PRIVILEGES_ON_SELECT = new HiveAuthzPrivileges.AuthzPrivilegeBuilder()
+      .addInputObjectPriviledge(
+          AuthorizableType.Column,
+          EnumSet.of(DBModelAction.SELECT))
+      .addInputObjectPriviledge(AuthorizableType.URI, EnumSet.of(DBModelAction.SELECT))
+      .setOperationScope(HiveOperationScope.CONNECT)
+      .setOperationType(HiveOperationType.QUERY)
+      .build();
+
   private static final HiveAuthzPrivileges LIST_TABLES_PRIVILEGES = new HiveAuthzPrivileges.AuthzPrivilegeBuilder()
     .addInputObjectPriviledge(
       AuthorizableType.Column,
@@ -78,7 +88,18 @@ public class MetastoreAuthzObjectFilter<T> {
       HiveAuthzPrivileges.HiveOperationType.INFO)
     .build();
 
+  private static final HiveAuthzPrivileges LIST_TABLES_PRIVILEGES_ON_SELECT = new HiveAuthzPrivileges.AuthzPrivilegeBuilder()
+      .addInputObjectPriviledge(
+          AuthorizableType.Column,
+          EnumSet.of(DBModelAction.SELECT))
+      .setOperationScope(HiveOperationScope.TABLE)
+      .setOperationType(
+          HiveAuthzPrivileges.HiveOperationType.INFO)
+      .build();
+
   private final boolean DEFAULT_DATABASE_RESTRICTED;
+  private final boolean SHOWDATABASES_ON_SELECT_ONLY;
+  private final boolean SHOWTABLES_ON_SELECT_ONLY;
   private final DBModelAuthorizable AUTH_SERVER;
   private HiveAuthzBinding authzBinding;
   private ObjectExtractor extractor;
@@ -89,6 +110,12 @@ public class MetastoreAuthzObjectFilter<T> {
     this.AUTH_SERVER = authzBinding.getAuthServer();
     this.DEFAULT_DATABASE_RESTRICTED = authzBinding.getAuthzConf()
       .getBoolean(HiveAuthzConf.AuthzConfVars.AUTHZ_RESTRICT_DEFAULT_DB.getVar(), false);
+
+    this.SHOWDATABASES_ON_SELECT_ONLY = authzBinding.getAuthzConf()
+        .getBoolean(HiveAuthzConf.AuthzConfVars.SHOWDATABASES_ON_SELECT_ONLY.getVar(), false);
+
+    this.SHOWTABLES_ON_SELECT_ONLY = authzBinding.getAuthzConf()
+        .getBoolean(AuthzConfVars.SHOWTABLES_ON_SELECT_ONLY.getVar(), false);
   }
 
   /**
@@ -103,7 +130,11 @@ public class MetastoreAuthzObjectFilter<T> {
    * Return the required privileges for listing tables in a database
    * @return the required privileges for authorizing listing tables in a database
    */
-  public static HiveAuthzPrivileges getListTablePrivileges() {
+  public HiveAuthzPrivileges getListTablePrivileges() {
+    if (SHOWTABLES_ON_SELECT_ONLY) {
+      return LIST_TABLES_PRIVILEGES_ON_SELECT;
+    }
+
     return LIST_TABLES_PRIVILEGES;
   }
 
@@ -170,7 +201,14 @@ public class MetastoreAuthzObjectFilter<T> {
       AUTH_SERVER, database, Table.ALL, Column.ALL
     );
 
-    return authorize(HiveOperation.SHOWDATABASES, LIST_DATABASES_PRIVILEGES, username, authorizable);
+    if (SHOWDATABASES_ON_SELECT_ONLY) {
+      return authorize(HiveOperation.SHOWDATABASES, LIST_DATABASES_PRIVILEGES_ON_SELECT, username,
+          authorizable);
+
+    } else {
+      return authorize(HiveOperation.SHOWDATABASES, LIST_DATABASES_PRIVILEGES, username,
+          authorizable);
+    }
   }
 
   /**
@@ -185,7 +223,11 @@ public class MetastoreAuthzObjectFilter<T> {
       AUTH_SERVER, database, table, Column.ALL
     );
 
-    return authorize(HiveOperation.SHOWTABLES, LIST_TABLES_PRIVILEGES, username, authorizable);
+    if (SHOWTABLES_ON_SELECT_ONLY) {
+      return authorize(HiveOperation.SHOWTABLES, LIST_TABLES_PRIVILEGES_ON_SELECT, username, authorizable);
+    } else {
+      return authorize(HiveOperation.SHOWTABLES, LIST_TABLES_PRIVILEGES, username, authorizable);
+    }
   }
 
   /**
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
index 8690a35..86e7d14 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
@@ -35,6 +35,7 @@ import java.util.HashSet;
 
 import com.google.common.collect.Sets;
 import org.apache.hive.hcatalog.listener.DbNotificationListener;
+import org.apache.sentry.binding.hive.conf.HiveAuthzConf.AuthzConfVars;
 import org.apache.sentry.binding.metastore.messaging.json.SentryJSONMessageFactory;
 import org.apache.sentry.api.common.ApiConstants.ClientConfig;
 import org.apache.sentry.tests.e2e.hive.fs.TestFSContants;
@@ -143,6 +144,9 @@ public abstract class AbstractTestWithStaticConfiguration extends RulesForE2ETes
   protected static int hmsFollowerIntervalInMilliseconds = 10000;
   // indicate if the database need to be clear for every test case in one test class
   protected static boolean clearDbPerTest = true;
+  protected static boolean showDbOnSelectOnly = false;
+  protected static boolean showTableOnSelectOnly = false;
+  protected static boolean restrictDefaultDatabase = false;
 
   protected static File baseDir;
   protected static File logDir;
@@ -312,6 +316,11 @@ public abstract class AbstractTestWithStaticConfiguration extends RulesForE2ETes
       properties.put(HiveConf.ConfVars.HIVE_LOCK_MANAGER.varname,
           "org.apache.hadoop.hive.ql.lockmgr.EmbeddedLockManager");
     }
+
+    properties.put(AuthzConfVars.SHOWDATABASES_ON_SELECT_ONLY.getVar(), String.valueOf(showDbOnSelectOnly));
+    properties.put(AuthzConfVars.SHOWTABLES_ON_SELECT_ONLY.getVar(), String.valueOf(showTableOnSelectOnly));
+    properties.put(AuthzConfVars.AUTHZ_RESTRICT_DEFAULT_DB.getVar(), String.valueOf(restrictDefaultDatabase));
+
     if (useSentryService && (!startSentry)) {
       configureHiveAndMetastoreForSentry();
       setupSentryService();
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestShowMetadataPrivileges.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestShowMetadataPrivileges.java
index 6a88d0b..0837c7f 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestShowMetadataPrivileges.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestShowMetadataPrivileges.java
@@ -34,15 +34,15 @@ import org.junit.runners.Parameterized;
 
 @RunWith(Parameterized.class)
 public class TestShowMetadataPrivileges extends AbstractTestWithStaticConfiguration {
-  private static final boolean ALLOWED = true;
-  private static final boolean NOT_ALLOWED = false;
-  private static final String SERVER1 = "server1";
+  protected static final boolean ALLOWED = true;
+  protected static final boolean NOT_ALLOWED = false;
+  protected static final String SERVER1 = "server1";
 
-  private static Connection adminCon, user1Con;
-  private static Statement adminStmt, user1Stmt;
+  protected static Connection adminCon, user1Con;
+  protected static Statement adminStmt, user1Stmt;
 
-  private DBModelAction action;
-  private boolean allowed;
+  protected DBModelAction action;
+  protected boolean allowed;
 
   @Parameterized.Parameters
   public static Collection describePrivileges() {
@@ -62,6 +62,7 @@ public class TestShowMetadataPrivileges extends AbstractTestWithStaticConfigurat
   @BeforeClass
   public static void setupTestStaticConfiguration() throws Exception{
     useSentryService = true;
+    restrictDefaultDatabase = true;
     AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
     setupAdmin();
 
@@ -151,4 +152,40 @@ public class TestShowMetadataPrivileges extends AbstractTestWithStaticConfigurat
         user1Stmt.getResultSet().next());
     }
   }
+
+  @Test
+  public void testShowDatabasesWithGrantOnDatabase() throws Exception {
+    if (action != null) {
+      adminStmt.execute("GRANT " + action + " ON DATABASE " + DB1 + " TO ROLE role1");
+    }
+
+    user1Stmt.execute("SHOW DATABASES");
+    if (!allowed) {
+      assertFalse(
+          "SHOW DATABASES should NOT display databases with " + action + " privileges on the database.",
+          user1Stmt.getResultSet().next());
+    } else {
+      assertTrue(
+          "SHOW DATABASES should display databases with " + action + " privileges on the database.",
+          user1Stmt.getResultSet().next());
+    }
+  }
+
+  @Test
+  public void testShowDatabasesWithGrantOnServer() throws Exception {
+    if (action != null) {
+      adminStmt.execute("GRANT " + action + " ON SERVER " + SERVER1 + " TO ROLE role1");
+    }
+
+    user1Stmt.execute("SHOW DATABASES");
+    if (!allowed) {
+      assertFalse(
+          "SHOW DATABASES should NOT display databases with " + action + " privileges on the server.",
+          user1Stmt.getResultSet().next());
+    } else {
+      assertTrue(
+          "SHOW DATABASES should display databases with " + action + " privileges on the server.",
+          user1Stmt.getResultSet().next());
+    }
+  }
 }
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestShowMetadataPrivilegesOnSelectOnly.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestShowMetadataPrivilegesOnSelectOnly.java
new file mode 100644
index 0000000..b89e941
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestShowMetadataPrivilegesOnSelectOnly.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+package org.apache.sentry.tests.e2e.hive;
+
+
+import java.util.Arrays;
+import java.util.Collection;
+import org.apache.sentry.core.model.db.DBModelAction;
+import org.junit.BeforeClass;
+import org.junit.runners.Parameterized;
+
+public class TestShowMetadataPrivilegesOnSelectOnly extends TestShowMetadataPrivileges {
+
+    @Parameterized.Parameters
+    public static Collection describePrivilegesOnSelect() {
+        return Arrays.asList(new Object[][] {
+            { null,                  NOT_ALLOWED }, // Means no privileges
+            { DBModelAction.ALL,     ALLOWED },
+            { DBModelAction.CREATE,  NOT_ALLOWED },
+            { DBModelAction.SELECT,  ALLOWED },
+            { DBModelAction.INSERT,  NOT_ALLOWED },
+            { DBModelAction.ALTER,   NOT_ALLOWED },
+            { DBModelAction.DROP,    NOT_ALLOWED },
+            { DBModelAction.INDEX,   NOT_ALLOWED },
+            { DBModelAction.LOCK,    NOT_ALLOWED },
+        });
+    }
+
+    @BeforeClass
+    public static void setupSelectOnlyTestStaticConfiguration() throws Exception {
+        showDbOnSelectOnly = true;
+        showTableOnSelectOnly = true;
+        setupTestStaticConfiguration();
+    }
+
+    public TestShowMetadataPrivilegesOnSelectOnly(DBModelAction action, boolean allowed) {
+        super(action, allowed);
+    }
+
+}