You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by ta...@apache.org on 2018/04/03 02:11:11 UTC

[5/9] impala git commit: IMPALA-6649: Add fine-grained ALTER privilege

IMPALA-6649: Add fine-grained ALTER privilege

Updated support and analysis files to provide ALTER privilege.

Example statements:
GRANT ALTER on SERVER svr TO ROLE testrole;
GRANT ALTER on DATABASE db TO ROLE testrole;
GRANT ALTER on TABLE tbl TO ROLE testrole;

REVOKE ALTER on SERVER svr FROM ROLE testrole;
REVOKE ALTER on DATABASE db FROM ROLE testrole;
REVOKE ALTER on TABLE tbl FROM ROLE testrole;

ALTER TABLE ... RENAME requires TABLE level privileges and
CREATE at the DATABASE level.

Tests:
Added ALTER tests to cover scope of existing ALTER tests but in
the context of only having ALTER privilege.
Ran all fe tests.

Cherry-picks: not for 2.x
Change-Id: I0b25d10a8634829fbe90e308dfc7efc8182fef2d
Reviewed-on: http://gerrit.cloudera.org:8080/9805
Reviewed-by: Alex Behm <al...@cloudera.com>
Tested-by: Impala Public Jenkins


Project: http://git-wip-us.apache.org/repos/asf/impala/repo
Commit: http://git-wip-us.apache.org/repos/asf/impala/commit/36111ce8
Tree: http://git-wip-us.apache.org/repos/asf/impala/tree/36111ce8
Diff: http://git-wip-us.apache.org/repos/asf/impala/diff/36111ce8

Branch: refs/heads/master
Commit: 36111ce885b31616fb4a10e918abc0c5f5989732
Parents: 08d386f
Author: Adam Holley <gi...@holleyism.com>
Authored: Mon Mar 26 13:40:05 2018 -0500
Committer: Impala Public Jenkins <im...@gerrit.cloudera.org>
Committed: Mon Apr 2 21:25:01 2018 +0000

----------------------------------------------------------------------
 common/thrift/CatalogObjects.thrift             |   3 +-
 fe/src/main/cup/sql-parser.cup                  |   2 +
 .../apache/impala/analysis/PrivilegeSpec.java   |   7 +-
 .../apache/impala/authorization/Privilege.java  |   3 +-
 .../impala/analysis/AnalyzeAuthStmtsTest.java   |  18 ++-
 .../impala/analysis/AuthorizationTest.java      | 161 +++++++++++++++++--
 fe/src/test/resources/authz-policy.ini.template |   9 +-
 7 files changed, 184 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/impala/blob/36111ce8/common/thrift/CatalogObjects.thrift
----------------------------------------------------------------------
diff --git a/common/thrift/CatalogObjects.thrift b/common/thrift/CatalogObjects.thrift
index 2c06c8e..703e701 100644
--- a/common/thrift/CatalogObjects.thrift
+++ b/common/thrift/CatalogObjects.thrift
@@ -469,7 +469,8 @@ enum TPrivilegeLevel {
   INSERT,
   SELECT,
   REFRESH,
-  CREATE
+  CREATE,
+  ALTER
 }
 
 // Represents a privilege in an authorization policy. Privileges contain the level

http://git-wip-us.apache.org/repos/asf/impala/blob/36111ce8/fe/src/main/cup/sql-parser.cup
----------------------------------------------------------------------
diff --git a/fe/src/main/cup/sql-parser.cup b/fe/src/main/cup/sql-parser.cup
index 11b6152..4d6abfd 100644
--- a/fe/src/main/cup/sql-parser.cup
+++ b/fe/src/main/cup/sql-parser.cup
@@ -964,6 +964,8 @@ privilege ::=
   {: RESULT = TPrivilegeLevel.REFRESH; :}
   | KW_CREATE
   {: RESULT = TPrivilegeLevel.CREATE; :}
+  | KW_ALTER
+  {: RESULT = TPrivilegeLevel.ALTER; :}
   | KW_ALL
   {: RESULT = TPrivilegeLevel.ALL; :}
   ;

http://git-wip-us.apache.org/repos/asf/impala/blob/36111ce8/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java b/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
index fcece28..b2652cc 100644
--- a/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
+++ b/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
@@ -190,9 +190,10 @@ public class PrivilegeSpec implements ParseNode {
       case SERVER:
         if (privilegeLevel_ != TPrivilegeLevel.ALL &&
             privilegeLevel_ != TPrivilegeLevel.REFRESH &&
-            privilegeLevel_ != TPrivilegeLevel.CREATE) {
-          throw new AnalysisException("Only 'ALL', 'REFRESH', or 'CREATE' privilege " +
-              "may be applied at SERVER scope in privilege spec.");
+            privilegeLevel_ != TPrivilegeLevel.CREATE &&
+            privilegeLevel_ != TPrivilegeLevel.ALTER) {
+          throw new AnalysisException("Only 'ALL', 'REFRESH', 'CREATE', or 'ALTER' " +
+              "privilege may be applied at SERVER scope in privilege spec.");
         }
         break;
       case DATABASE:

http://git-wip-us.apache.org/repos/asf/impala/blob/36111ce8/fe/src/main/java/org/apache/impala/authorization/Privilege.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/authorization/Privilege.java b/fe/src/main/java/org/apache/impala/authorization/Privilege.java
index b6fa14c..558e4bd 100644
--- a/fe/src/main/java/org/apache/impala/authorization/Privilege.java
+++ b/fe/src/main/java/org/apache/impala/authorization/Privilege.java
@@ -26,7 +26,7 @@ import org.apache.sentry.core.common.Action;
  */
 public enum Privilege {
   ALL(SentryAction.ALL, false),
-  ALTER(SentryAction.ALL, false),
+  ALTER(SentryAction.ALTER, false),
   DROP(SentryAction.ALL, false),
   CREATE(SentryAction.CREATE, false),
   INSERT(SentryAction.INSERT, false),
@@ -55,6 +55,7 @@ public enum Privilege {
     INSERT("insert"),
     REFRESH("refresh"),
     CREATE("create"),
+    ALTER("alter"),
     ALL("*");
 
     private final String value;

http://git-wip-us.apache.org/repos/asf/impala/blob/36111ce8/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
----------------------------------------------------------------------
diff --git a/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java b/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
index 825ed35..d1eae40 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
@@ -165,8 +165,8 @@ public class AnalyzeAuthStmtsTest extends AnalyzerTest {
       AnalyzesOk(String.format("%s INSERT ON DATABASE functional %s myrole",
           formatArgs));
       AnalysisError(String.format("%s INSERT ON SERVER %s myrole", formatArgs),
-          "Only 'ALL', 'REFRESH', or 'CREATE' privilege may be applied at SERVER " +
-          "scope in privilege spec.");
+          "Only 'ALL', 'REFRESH', 'CREATE', or 'ALTER' privilege may be applied at " +
+          "SERVER scope in privilege spec.");
       AnalysisError(String.format("%s INSERT ON URI 'hdfs:////abc//123' %s myrole",
           formatArgs), "Only 'ALL' privilege may be applied at URI scope in privilege " +
           "spec.");
@@ -181,8 +181,8 @@ public class AnalyzeAuthStmtsTest extends AnalyzerTest {
       AnalyzesOk(String.format("%s SELECT ON DATABASE functional %s myrole",
           formatArgs));
       AnalysisError(String.format("%s SELECT ON SERVER %s myrole", formatArgs),
-          "Only 'ALL', 'REFRESH', or 'CREATE' privilege may be applied at SERVER " +
-          "scope in privilege spec.");
+          "Only 'ALL', 'REFRESH', 'CREATE', or 'ALTER' privilege may be applied at " +
+          "SERVER scope in privilege spec.");
       AnalysisError(String.format("%s SELECT ON URI 'hdfs:////abc//123' %s myrole",
           formatArgs), "Only 'ALL' privilege may be applied at URI scope in privilege " +
           "spec.");
@@ -245,6 +245,16 @@ public class AnalyzeAuthStmtsTest extends AnalyzerTest {
       AnalysisError(String.format(
           "%s CREATE ON URI 'hdfs:////abc//123' %s myrole", formatArgs),
           "Only 'ALL' privilege may be applied at URI scope in privilege spec.");
+
+      // ALTER privilege
+      AnalyzesOk(String.format("%s ALTER ON SERVER %s myrole", formatArgs));
+      AnalyzesOk(String.format("%s ALTER ON SERVER server1 %s myrole", formatArgs));
+      AnalyzesOk(String.format("%s ALTER ON DATABASE functional %s myrole", formatArgs));
+      AnalyzesOk(String.format(
+          "%s ALTER ON TABLE functional.alltypes %s myrole", formatArgs));
+      AnalysisError(String.format(
+          "%s ALTER ON URI 'hdfs:////abc/123' %s myrole", formatArgs),
+          "Only 'ALL' privilege may be applied at URI scope in privilege spec.");
     }
 
     AnalysisContext authDisabledCtx = createAuthDisabledAnalysisCtx();

http://git-wip-us.apache.org/repos/asf/impala/blob/36111ce8/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
----------------------------------------------------------------------
diff --git a/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java b/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
index d59f55f..4daa854 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
@@ -88,8 +88,10 @@ public class AuthorizationTest extends FrontendTestBase {
   //   ALL permission on 'functional_seq_snap' database
   //   SELECT permissions on all tables in 'tpcds' database
   //   SELECT, REFRESH permissions on 'functional.alltypesagg' (no INSERT permissions)
+  //   ALTER permissions on 'functional.alltypeserror'
   //   SELECT permissions on 'functional.complex_view' (no INSERT permissions)
   //   SELECT, REFRESH permissions on 'functional.view_view' (no INSERT permissions)
+  //   ALTER permission on 'functional.alltypes_view'
   //   SELECT permissions on columns ('id', 'int_col', and 'year') on
   //   'functional.alltypessmall' (no SELECT permissions on 'functional.alltypessmall')
   //   SELECT permissions on columns ('id', 'int_struct_col', 'struct_array_col',
@@ -103,7 +105,7 @@ public class AuthorizationTest extends FrontendTestBase {
   //   No permissions on database 'functional_rc'
   //   Only column level permissions in 'functional_avro':
   //     SELECT permissions on columns ('id') on 'functional_avro.alltypessmall'
-  //   REFRESH, INSERT, CREATE permissions on 'functional_text_lzo' database
+  //   REFRESH, INSERT, CREATE, ALTER permissions on 'functional_text_lzo' database
   public final static String AUTHZ_POLICY_FILE = "/test-warehouse/authz-policy.ini";
   public final static User USER = new User(System.getProperty("user.name"));
 
@@ -111,8 +113,8 @@ public class AuthorizationTest extends FrontendTestBase {
   // column-level SELECT or INSERT permission. I.e. that should be returned by
   // 'SHOW TABLES'.
   private static final List<String> FUNCTIONAL_VISIBLE_TABLES = Lists.newArrayList(
-      "allcomplextypes", "alltypes", "alltypesagg", "alltypessmall", "alltypestiny",
-      "complex_view", "view_view");
+      "allcomplextypes", "alltypes", "alltypes_view", "alltypesagg", "alltypeserror",
+      "alltypessmall", "alltypestiny", "complex_view", "view_view");
 
   /**
    * Test context whose instances are used to parameterize this test.
@@ -301,6 +303,41 @@ public class AuthorizationTest extends FrontendTestBase {
     privilege.setTable_name(AuthorizeableTable.ANY_TABLE_NAME);
     sentryService.grantRolePrivilege(USER, roleName, privilege);
 
+    // alter_functional_text_lzo
+    roleName = "alter_functional_text_lzo";
+    sentryService.createRole(USER, roleName, true);
+    sentryService.grantRoleToGroup(USER, roleName, USER.getName());
+
+    privilege = new TPrivilege("", TPrivilegeLevel.ALTER, TPrivilegeScope.DATABASE,
+        false);
+    privilege.setServer_name("server1");
+    privilege.setDb_name("functional_text_lzo");
+    privilege.setTable_name(AuthorizeableTable.ANY_TABLE_NAME);
+    sentryService.grantRolePrivilege(USER, roleName, privilege);
+
+    // alter_functional_alltypeserror
+    roleName = "alter_functional_alltypeserror";
+    sentryService.createRole(USER, roleName, true);
+    sentryService.grantRoleToGroup(USER, roleName, USER.getName());
+
+    privilege = new TPrivilege("", TPrivilegeLevel.ALTER, TPrivilegeScope.TABLE, false);
+    privilege.setServer_name("server1");
+    privilege.setDb_name("functional");
+    privilege.setTable_name("alltypeserror");
+    sentryService.grantRolePrivilege(USER, roleName, privilege);
+
+    // alter_functional_alltypes_view
+    roleName = "alter_functional_alltypes_view";
+    sentryService.createRole(USER, roleName, true);
+    sentryService.grantRoleToGroup(USER, roleName, USER.getName());
+
+    privilege = new TPrivilege("", TPrivilegeLevel.ALTER,
+        TPrivilegeScope.TABLE, false);
+    privilege.setServer_name("server1");
+    privilege.setDb_name("functional");
+    privilege.setTable_name("alltypes_view");
+    sentryService.grantRolePrivilege(USER, roleName, privilege);
+
     // all newdb w/ all on URI
     roleName = "all_newdb";
     sentryService.createRole(USER, roleName, true);
@@ -1348,6 +1385,8 @@ public class AuthorizationTest extends FrontendTestBase {
     AuthzOk("ALTER TABLE functional_seq_snap.alltypes REPLACE COLUMNS (c1 int)");
     AuthzOk("ALTER TABLE functional_seq_snap.alltypes CHANGE int_col c1 int");
     AuthzOk("ALTER TABLE functional_seq_snap.alltypes DROP int_col");
+    // Note: ALTER ... RENAME requires ALTER privileges at the TABLE level and
+    // CREATE privileges at the DATABASE level.
     AuthzOk("ALTER TABLE functional_seq_snap.alltypes RENAME TO functional_seq_snap.t1");
     AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET FILEFORMAT PARQUET");
     AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " +
@@ -1358,11 +1397,28 @@ public class AuthorizationTest extends FrontendTestBase {
         "'hdfs://localhost:20500/test-warehouse/new_table'");
     AuthzOk("ALTER TABLE functional_seq_snap.alltypes PARTITION(year=2009, month=1) " +
         "SET LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'");
-
     AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET CACHED IN 'testPool'");
     AuthzOk("ALTER TABLE functional_seq_snap.alltypes RECOVER PARTITIONS");
 
+    // User has ALTER privilege only to modify tables.
+    AuthzOk("ALTER TABLE functional.alltypeserror ADD COLUMNS (c1 int)");
+    AuthzOk("ALTER TABLE functional.alltypeserror REPLACE COLUMNS (c1 int)");
+    AuthzOk("ALTER TABLE functional.alltypeserror CHANGE id c1 int");
+    AuthzOk("ALTER TABLE functional.alltypeserror DROP id");
+    AuthzOk("ALTER TABLE functional.alltypeserror RENAME TO functional_seq_snap.t1");
+    AuthzOk("ALTER TABLE functional.alltypeserror SET FILEFORMAT PARQUET");
+    AuthzOk("ALTER TABLE functional.alltypeserror SET LOCATION " +
+        "'/test-warehouse/new_table'");
+    AuthzOk("ALTER TABLE functional.alltypeserror SET TBLPROPERTIES ('a'='b', 'c'='d')");
+    AuthzOk("ALTER TABLE functional.alltypeserror SET LOCATION " +
+        "'hdfs://localhost:20500/test-warehouse/new_table'");
+    AuthzOk("ALTER TABLE functional.alltypeserror PARTITION(year=2009, month=1) " +
+        "SET LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'");
+    AuthzOk("ALTER TABLE functional.alltypeserror SET CACHED IN 'testPool'");
+    AuthzOk("ALTER TABLE functional.alltypeserror RECOVER PARTITIONS");
+
     // Alter table and set location to a path the user does not have access to.
+    // User needs ALTER on table and ALL on URI.
     AuthzError("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " +
         "'hdfs://localhost:20500/test-warehouse/no_access'",
         "User '%s' does not have privileges to access: " +
@@ -1376,6 +1432,19 @@ public class AuthorizationTest extends FrontendTestBase {
         "User '%s' does not have privileges to access: " +
         "hdfs://localhost:20500/test-warehouse/no_access");
 
+    AuthzError("ALTER TABLE functional.alltypeserror SET LOCATION " +
+        "'hdfs://localhost:20500/test-warehouse/no_access'",
+        "User '%s' does not have privileges to access: " +
+        "hdfs://localhost:20500/test-warehouse/no_access");
+    AuthzError("ALTER TABLE functional.alltypeserror SET LOCATION " +
+        "'/test-warehouse/no_access'",
+        "User '%s' does not have privileges to access: " +
+        "hdfs://localhost:20500/test-warehouse/no_access");
+    AuthzError("ALTER TABLE functional.alltypeserror " +
+        "PARTITION(year=2009, month=1) SET LOCATION '/test-warehouse/no_access'",
+        "User '%s' does not have privileges to access: " +
+        "hdfs://localhost:20500/test-warehouse/no_access");
+
     // Add multiple partitions. User has access to location path.
     AuthzOk("ALTER TABLE functional_seq_snap.alltypes ADD " +
         "PARTITION(year=2011, month=1) " +
@@ -1394,6 +1463,24 @@ public class AuthorizationTest extends FrontendTestBase {
         "User '%s' does not have privileges to access: " +
         "hdfs://localhost:20510/test-warehouse/new_table");
 
+    // ALTER privilege only. Add multiple partitions. User has access to location path.
+    AuthzOk("ALTER TABLE functional.alltypeserror ADD " +
+        "PARTITION(year=2011, month=1) PARTITION(year=2011, month=2) " +
+        "LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'");
+    // ALTER privilege only. For one new partition location is set to a path the user
+    // does not have access to.
+    AuthzError("ALTER TABLE functional.alltypeserror ADD " +
+        "PARTITION(year=2011, month=3) PARTITION(year=2011, month=4) " +
+        "LOCATION '/test-warehouse/no_access'",
+        "User '%s' does not have privileges to access: " +
+        "hdfs://localhost:20500/test-warehouse/no_access");
+    // ALTER privilege only.  Different filesystem, user has permission to base path.
+    AuthzError("ALTER TABLE functional.alltypeserror SET LOCATION " +
+        "'hdfs://localhost:20510/test-warehouse/new_table'",
+        "User '%s' does not have privileges to access: " +
+        "hdfs://localhost:20510/test-warehouse/new_table");
+
+    // User does not have ALTER privilege.
     AuthzError("ALTER TABLE functional.alltypes SET FILEFORMAT PARQUET",
         "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes");
     AuthzError("ALTER TABLE functional.alltypes ADD COLUMNS (c1 int)",
@@ -1434,6 +1521,11 @@ public class AuthorizationTest extends FrontendTestBase {
         "User '%s' does not have privileges to execute 'CREATE' on: " +
         "functional.alltypes");
 
+    // No privileges on target (new table).
+    AuthzError("ALTER TABLE functional_seq_snap.alltypes rename to functional.newtbl",
+        "User '%s' does not have privileges to execute 'CREATE' on: " +
+            "functional");
+
     // No privileges on target (existing view).
     AuthzError("ALTER TABLE functional_seq_snap.alltypes rename to " +
         "functional.alltypes_view",
@@ -1441,7 +1533,7 @@ public class AuthorizationTest extends FrontendTestBase {
         "functional.alltypes");
 
     // ALTER TABLE on a view does not reveal privileged information.
-    AuthzError("ALTER TABLE functional.alltypes_view rename to " +
+    AuthzError("ALTER TABLE functional.alltypes_view_sub rename to " +
         "functional_seq_snap.new_view",
         "User '%s' does not have privileges to execute 'ALTER' on: " +
         "functional.alltypes_view");
@@ -1484,6 +1576,14 @@ public class AuthorizationTest extends FrontendTestBase {
     AuthzOk("ALTER VIEW functional_seq_snap.alltypes_view rename to " +
         "functional_seq_snap.v1");
 
+    // ALTER privilege on view only. RENAME also requires CREATE privileges on the DB.
+    AuthzOk("ALTER VIEW functional.alltypes_view rename to functional_seq_snap.view_view_1");
+
+    // No create privileges on target db
+    AuthzError("ALTER VIEW functional.alltypes_view rename to functional.newview",
+        "User '%s' does not have privileges to execute 'CREATE' on: " +
+        "functional");
+
     // No privileges on target (existing table).
     AuthzError("ALTER VIEW functional_seq_snap.alltypes_view rename to " +
         "functional.alltypes",
@@ -1523,7 +1623,7 @@ public class AuthorizationTest extends FrontendTestBase {
         "User '%s' does not have privileges to execute 'ALTER' on: default.alltypes");
 
     // No permissions on target view.
-    AuthzError("alter view functional.alltypes_view as " +
+    AuthzError("alter view functional.alltypes_view_sub as " +
         "select * from functional.alltypesagg",
         "User '%s' does not have privileges to execute 'ALTER' on: " +
         "functional.alltypes_view");
@@ -1609,8 +1709,8 @@ public class AuthorizationTest extends FrontendTestBase {
     AuthzError("describe functional.complextypestbl.nested_struct",
         "User '%s' does not have privileges to access: functional.complextypestbl");
     // Insufficient privileges on view.
-    AuthzError("describe functional.alltypes_view",
-        "User '%s' does not have privileges to access: functional.alltypes_view");
+    AuthzError("describe functional.alltypes_view_sub",
+        "User '%s' does not have privileges to access: functional.alltypes_view_sub");
     // Insufficient privileges on db.
     AuthzError("describe functional_rc.alltypes",
         "User '%s' does not have privileges to access: functional_rc.alltypes");
@@ -1993,7 +2093,8 @@ public class AuthorizationTest extends FrontendTestBase {
     tables = fe_.getTableNames("functional",
         PatternMatcher.createHivePatternMatcher("alltypes*|view_view"), USER);
     List<String> expectedTables = Lists.newArrayList(
-        "alltypes", "alltypesagg", "alltypessmall", "alltypestiny", "view_view");
+        "alltypes", "alltypes_view", "alltypesagg", "alltypeserror", "alltypessmall",
+        "alltypestiny", "view_view");
     Assert.assertEquals(expectedTables, tables);
   }
 
@@ -2590,6 +2691,48 @@ public class AuthorizationTest extends FrontendTestBase {
     }
   }
 
+  @Test
+  public void TestServerLevelAlter() throws ImpalaException {
+    // TODO: Add test support for dynamically changing privileges for
+    // file-based policy.
+    if (ctx_.authzConfig.isFileBasedPolicy()) return;
+
+    SentryPolicyService sentryService =
+        new SentryPolicyService(ctx_.authzConfig.getSentryConfig());
+
+    // User has ALTER privilege on server.
+    String roleName = "alter_role";
+    try {
+      sentryService.createRole(USER, roleName, true);
+      TPrivilege privilege = new TPrivilege("", TPrivilegeLevel.ALTER,
+          TPrivilegeScope.SERVER, false);
+      privilege.setServer_name("server1");
+      sentryService.grantRolePrivilege(USER, roleName, privilege);
+      sentryService.grantRoleToGroup(USER, roleName, USER.getName());
+      ctx_.catalog.reset();
+
+      AuthzOk("ALTER TABLE functional_rc.alltypes ADD COLUMNS (c1 int)");
+      AuthzOk("ALTER TABLE functional_rc.alltypes REPLACE COLUMNS (c1 int)");
+      AuthzOk("ALTER TABLE functional_rc.alltypes CHANGE int_col c1 int");
+      AuthzOk("ALTER TABLE functional_rc.alltypes DROP int_col");
+      AuthzOk("ALTER TABLE functional_rc.alltypes RENAME TO functional_seq_snap.t1");
+      AuthzOk("ALTER TABLE functional_rc.alltypes SET FILEFORMAT PARQUET");
+      AuthzOk("ALTER TABLE functional_rc.alltypes SET LOCATION " +
+          "'/test-warehouse/new_table'");
+      AuthzOk("ALTER TABLE functional_rc.alltypes SET TBLPROPERTIES " +
+          "('a'='b', 'c'='d')");
+      AuthzOk("ALTER TABLE functional_rc.alltypes SET LOCATION " +
+          "'hdfs://localhost:20500/test-warehouse/new_table'");
+      AuthzOk("ALTER TABLE functional_rc.alltypes PARTITION(year=2009, month=1) " +
+          "SET LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'");
+      AuthzOk("ALTER TABLE functional_rc.alltypes SET CACHED IN 'testPool'");
+      AuthzOk("ALTER TABLE functional_rc.alltypes RECOVER PARTITIONS");
+    } finally {
+      sentryService.dropRole(USER, roleName, true);
+      ctx_.catalog.reset();
+    }
+  }
+
   private void TestWithIncorrectConfig(AuthorizationConfig authzConfig, User user)
       throws ImpalaException {
     Frontend fe = new Frontend(authzConfig, ctx_.catalog);

http://git-wip-us.apache.org/repos/asf/impala/blob/36111ce8/fe/src/test/resources/authz-policy.ini.template
----------------------------------------------------------------------
diff --git a/fe/src/test/resources/authz-policy.ini.template b/fe/src/test/resources/authz-policy.ini.template
index aeb3911..82b1060 100644
--- a/fe/src/test/resources/authz-policy.ini.template
+++ b/fe/src/test/resources/authz-policy.ini.template
@@ -27,7 +27,9 @@ ${USER} = all_tpch, all_newdb, all_functional_seq_snap, select_tpcds,\
           select_column_level_functional_avro, upper_case_uri,\
           refresh_functional_text_lzo, refresh_functional_alltypesagg,\
           refresh_functional_view_view, insert_functional_text_lzo,\
-          create_functional_text_lzo, libtestudfs_uri
+          create_functional_text_lzo, alter_functional_text_lzo,\
+          alter_functional_alltypeserror, alter_functional_alltypes_view,\
+          libtestudfs_uri
 auth_to_local_group = test_role
 server_admin = all_server
 
@@ -53,10 +55,15 @@ insert_parquet = server=server1->db=functional_parquet->table=*->action=insert
 refresh_functional_text_lzo = server=server1->db=functional_text_lzo->action=refresh
 refresh_functional_alltypesagg =\
     server=server1->db=functional->table=alltypesagg->action=refresh
+alter_functional_alltypeserror =\
+    server=server1->db=functional->table=alltypeserror->action=alter
 refresh_functional_view_view =\
     server=server1->db=functional->table=view_view->action=refresh
+alter_functional_alltypes_view =\
+    server=server1->db=functional->table=alltypes_view->action=alter
 insert_functional_text_lzo = server=server1->db=functional_text_lzo->action=insert
 create_functional_text_lzo = server=server1->db=functional_text_lzo->action=create
+alter_functionl_text_lzo = server=server1->db=functional_text_lzo->action=alter
 select_column_level_functional =\
     server=server1->db=functional->table=alltypessmall->column=id->action=select,\
     server=server1->db=functional->table=alltypessmall->column=int_col->action=select,\