Repository: impala Updated Branches: refs/heads/master 0a901fcb2 -> d29300281
IMPALA-6989: Implement SHOW GRANT USER statement This patch implements SHOW GRANT USER command to show the list of privileges for a given user. Syntax: SHOW GRANT USER <user> SHOW GRANT USER <user> ON SERVER SHOW GRANT USER <user> ON DATABASE <db> SHOW GRANT USER <user> ON TABLE <table> SHOW GRANT USER <user> ON URI <uri> Testing: - Add FE tests - Ran all FE tests Change-Id: Ia96fcf02d249501c471d03511c22625ae2fec225 Reviewed-on: http://gerrit.cloudera.org:8080/11244 Reviewed-by: Impala Public Jenkins <[email protected]> Tested-by: Impala Public Jenkins <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/impala/repo Commit: http://git-wip-us.apache.org/repos/asf/impala/commit/73d37d6e Tree: http://git-wip-us.apache.org/repos/asf/impala/tree/73d37d6e Diff: http://git-wip-us.apache.org/repos/asf/impala/diff/73d37d6e Branch: refs/heads/master Commit: 73d37d6ebbccba7045fff2f228f7364cc1302582 Parents: 0a901fc Author: Fredy Wijaya <[email protected]> Authored: Wed Jul 25 17:35:52 2018 -0500 Committer: Impala Public Jenkins <[email protected]> Committed: Mon Aug 20 01:50:54 2018 +0000 ---------------------------------------------------------------------- be/src/service/client-request-state.cc | 6 +- be/src/service/frontend.cc | 6 +- be/src/service/frontend.h | 7 +- common/thrift/Frontend.thrift | 21 +++-- fe/src/main/cup/sql-parser.cup | 42 ++++++--- .../apache/impala/analysis/AnalysisContext.java | 6 +- .../impala/analysis/ShowGrantPrincipalStmt.java | 95 ++++++++++++++++++++ .../impala/analysis/ShowGrantRoleStmt.java | 86 ------------------ .../impala/catalog/AuthorizationPolicy.java | 24 +---- .../org/apache/impala/service/Frontend.java | 17 ++-- .../org/apache/impala/service/JniFrontend.java | 17 ++-- .../impala/analysis/AnalyzeAuthStmtsTest.java | 33 ++++--- .../impala/analysis/AuthorizationStmtTest.java | 16 ++-- .../org/apache/impala/analysis/ParserTest.java | 35 ++++---- 14 files changed, 223 insertions(+), 188 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/be/src/service/client-request-state.cc ---------------------------------------------------------------------- diff --git a/be/src/service/client-request-state.cc b/be/src/service/client-request-state.cc index 5839e9c..0db511d 100644 --- a/be/src/service/client-request-state.cc +++ b/be/src/service/client-request-state.cc @@ -346,8 +346,8 @@ Status ClientRequestState::ExecLocalCatalogOp( SetResultSet(result.role_names); return Status::OK(); } - case TCatalogOpType::SHOW_GRANT_ROLE: { - const TShowGrantRoleParams& params = catalog_op.show_grant_role_params; + case TCatalogOpType::SHOW_GRANT_PRINCIPAL: { + const TShowGrantPrincipalParams& params = catalog_op.show_grant_principal_params; if (params.is_admin_op) { // Verify the user has privileges to perform this operation by checking against // the Sentry Service (via the Catalog Server). @@ -361,7 +361,7 @@ Status ClientRequestState::ExecLocalCatalogOp( } TResultSet response; - RETURN_IF_ERROR(frontend_->GetRolePrivileges(params, &response)); + RETURN_IF_ERROR(frontend_->GetPrincipalPrivileges(params, &response)); // Set the result set and its schema from the response. request_result_set_.reset(new vector<TResultRow>(response.rows)); result_metadata_ = response.schema; http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/be/src/service/frontend.cc ---------------------------------------------------------------------- diff --git a/be/src/service/frontend.cc b/be/src/service/frontend.cc index ca3f79f..aec92f7 100644 --- a/be/src/service/frontend.cc +++ b/be/src/service/frontend.cc @@ -93,7 +93,7 @@ Frontend::Frontend() { {"getFunctions", "([B)[B", &get_functions_id_}, {"getCatalogObject", "([B)[B", &get_catalog_object_id_}, {"getRoles", "([B)[B", &show_roles_id_}, - {"getRolePrivileges", "([B)[B", &get_role_privileges_id_}, + {"getPrincipalPrivileges", "([B)[B", &get_principal_privileges_id_}, {"execHiveServer2MetadataOp", "([B)[B", &exec_hs2_metadata_op_id_}, {"setCatalogIsReady", "()V", &set_catalog_is_ready_id_}, {"waitForCatalog", "()V", &wait_for_catalog_id_}, @@ -186,9 +186,9 @@ Status Frontend::GetStats(const TShowStatsParams& params, return JniUtil::CallJniMethod(fe_, get_stats_id_, params, result); } -Status Frontend::GetRolePrivileges(const TShowGrantRoleParams& params, +Status Frontend::GetPrincipalPrivileges(const TShowGrantPrincipalParams& params, TResultSet* result) { - return JniUtil::CallJniMethod(fe_, get_role_privileges_id_, params, result); + return JniUtil::CallJniMethod(fe_, get_principal_privileges_id_, params, result); } Status Frontend::GetFunctions(TFunctionCategory::type fn_category, const string& db, http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/be/src/service/frontend.h ---------------------------------------------------------------------- diff --git a/be/src/service/frontend.h b/be/src/service/frontend.h index 2327e8f..3788fa5 100644 --- a/be/src/service/frontend.h +++ b/be/src/service/frontend.h @@ -92,8 +92,9 @@ class Frontend { /// Call FE to get the table/column stats. Status GetStats(const TShowStatsParams& params, TResultSet* result); - /// Call FE to get the privileges granted to a role. - Status GetRolePrivileges(const TShowGrantRoleParams& params, TResultSet* result); + /// Call FE to get the privileges granted to a principal. + Status GetPrincipalPrivileges(const TShowGrantPrincipalParams& params, + TResultSet* result); /// Return all functions of 'category' that match the optional argument 'pattern'. /// If pattern is NULL match all functions, otherwise match only those functions that @@ -208,7 +209,7 @@ class Frontend { jmethodID get_functions_id_; // JniFrontend.getFunctions jmethodID get_catalog_object_id_; // JniFrontend.getCatalogObject jmethodID show_roles_id_; // JniFrontend.getRoles - jmethodID get_role_privileges_id_; // JniFrontend.getRolePrivileges + jmethodID get_principal_privileges_id_; // JniFrontend.getPrincipalPrivileges jmethodID exec_hs2_metadata_op_id_; // JniFrontend.execHiveServer2MetadataOp jmethodID load_table_data_id_; // JniFrontend.loadTableData jmethodID set_catalog_is_ready_id_; // JniFrontend.setCatalogIsReady http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/common/thrift/Frontend.thrift ---------------------------------------------------------------------- diff --git a/common/thrift/Frontend.thrift b/common/thrift/Frontend.thrift index abb2d77..a7d56d7 100644 --- a/common/thrift/Frontend.thrift +++ b/common/thrift/Frontend.thrift @@ -265,20 +265,23 @@ struct TShowRolesResult { 1: required list<string> role_names } -// Parameters for SHOW GRANT ROLE commands -struct TShowGrantRoleParams { +// Parameters for SHOW GRANT ROLE/USER commands +struct TShowGrantPrincipalParams { // The effective user who submitted this request. 1: optional string requesting_user - // The target role name. - 2: required string role_name + // The target name. + 2: required string name + + // The principal type. + 3: required CatalogObjects.TPrincipalType principal_type; // True if this operation requires admin privileges on the Sentry Service (when // the requesting user has not been granted the target role name). - 3: required bool is_admin_op + 4: required bool is_admin_op // An optional filter to show grants that match a specific privilege spec. - 4: optional CatalogObjects.TPrivilege privilege + 5: optional CatalogObjects.TPrivilege privilege } // Arguments to getFunctions(), which returns a list of non-qualified function @@ -436,7 +439,7 @@ enum TCatalogOpType { SHOW_CREATE_TABLE, SHOW_DATA_SRCS, SHOW_ROLES, - SHOW_GRANT_ROLE, + SHOW_GRANT_PRINCIPAL, SHOW_FILES, SHOW_CREATE_FUNCTION } @@ -473,8 +476,8 @@ struct TCatalogOpRequest { // Parameters for SHOW ROLES 10: optional TShowRolesParams show_roles_params - // Parameters for SHOW GRANT ROLE - 11: optional TShowGrantRoleParams show_grant_role_params + // Parameters for SHOW GRANT ROLE/USER + 11: optional TShowGrantPrincipalParams show_grant_principal_params // Parameters for DDL requests executed using the CatalogServer // such as CREATE, ALTER, and DROP. See CatalogService.TDdlExecRequest http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/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 94b69e4..e334591 100644 --- a/fe/src/main/cup/sql-parser.cup +++ b/fe/src/main/cup/sql-parser.cup @@ -54,6 +54,7 @@ import org.apache.impala.thrift.TOwnerType; import org.apache.impala.thrift.TPrivilegeLevel; import org.apache.impala.thrift.TShowStatsOp; import org.apache.impala.thrift.TTablePropertyType; +import org.apache.impala.thrift.TPrincipalType; parser code {: private Symbol errorToken_; @@ -497,7 +498,8 @@ nonterminal Map<Option, Object> column_options_map; // For GRANT/REVOKE/AUTH DDL statements nonterminal ShowRolesStmt show_roles_stmt; -nonterminal ShowGrantRoleStmt show_grant_role_stmt; +nonterminal ShowGrantPrincipalStmt show_grant_principal_stmt; +nonterminal TPrincipalType principal_type; nonterminal CreateDropRoleStmt create_drop_role_stmt; nonterminal GrantRevokeRoleStmt grant_role_stmt; nonterminal GrantRevokeRoleStmt revoke_role_stmt; @@ -655,8 +657,8 @@ stmt ::= {: RESULT = set; :} | show_roles_stmt:show_roles {: RESULT = show_roles; :} - | show_grant_role_stmt:show_grant_role - {: RESULT = show_grant_role; :} + | show_grant_principal_stmt:show_grant_principal + {: RESULT = show_grant_principal; :} | create_drop_role_stmt:create_drop_role {: RESULT = create_drop_role; :} | grant_role_stmt:grant_role @@ -903,29 +905,31 @@ show_roles_stmt ::= {: RESULT = new ShowRolesStmt(true, null); :} ; -show_grant_role_stmt ::= - KW_SHOW KW_GRANT KW_ROLE ident_or_default:role - {: RESULT = new ShowGrantRoleStmt(role, null); :} - | KW_SHOW KW_GRANT KW_ROLE ident_or_default:role KW_ON server_ident:server_kw +show_grant_principal_stmt ::= + KW_SHOW KW_GRANT principal_type:type ident_or_default:name + {: RESULT = new ShowGrantPrincipalStmt(name, type, null); :} + | KW_SHOW KW_GRANT principal_type:type ident_or_default:name KW_ON + server_ident:server_kw {: - RESULT = new ShowGrantRoleStmt(role, + RESULT = new ShowGrantPrincipalStmt(name, type, PrivilegeSpec.createServerScopedPriv(TPrivilegeLevel.ALL)); :} - | KW_SHOW KW_GRANT KW_ROLE ident_or_default:role KW_ON + | KW_SHOW KW_GRANT principal_type:type ident_or_default:name KW_ON KW_DATABASE ident_or_default:db_name {: - RESULT = new ShowGrantRoleStmt(role, + RESULT = new ShowGrantPrincipalStmt(name, type, PrivilegeSpec.createDbScopedPriv(TPrivilegeLevel.ALL, db_name)); :} - | KW_SHOW KW_GRANT KW_ROLE ident_or_default:role KW_ON KW_TABLE table_name:tbl_name + | KW_SHOW KW_GRANT principal_type:type ident_or_default:name KW_ON KW_TABLE + table_name:tbl_name {: - RESULT = new ShowGrantRoleStmt(role, + RESULT = new ShowGrantPrincipalStmt(name, type, PrivilegeSpec.createTableScopedPriv(TPrivilegeLevel.ALL, tbl_name)); :} - | KW_SHOW KW_GRANT KW_ROLE ident_or_default:role KW_ON uri_ident:uri_kw + | KW_SHOW KW_GRANT principal_type:type ident_or_default:name KW_ON uri_ident:uri_kw STRING_LITERAL:uri {: - RESULT = new ShowGrantRoleStmt(role, + RESULT = new ShowGrantPrincipalStmt(name, type, PrivilegeSpec.createUriScopedPriv(TPrivilegeLevel.ALL, new HdfsUri(uri))); :} ; @@ -991,6 +995,16 @@ privilege ::= {: RESULT = TPrivilegeLevel.ALL; :} ; +principal_type ::= + KW_ROLE + {: RESULT = TPrincipalType.ROLE; :} + | IDENT:user + {: + parser.checkIdentKeyword("USER", user); + RESULT = TPrincipalType.USER; + :} + ; + opt_grantopt_for ::= KW_GRANT option_ident:option KW_FOR {: RESULT = true; :} http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java b/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java index 47fe8a7..2f51c71 100644 --- a/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java +++ b/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java @@ -137,7 +137,9 @@ public class AnalysisContext { public boolean isResetMetadataStmt() { return stmt_ instanceof ResetMetadataStmt; } public boolean isExplainStmt() { return stmt_.isExplain(); } public boolean isShowRolesStmt() { return stmt_ instanceof ShowRolesStmt; } - public boolean isShowGrantRoleStmt() { return stmt_ instanceof ShowGrantRoleStmt; } + public boolean isShowGrantPrincipalStmt() { + return stmt_ instanceof ShowGrantPrincipalStmt; + } public boolean isCreateDropRoleStmt() { return stmt_ instanceof CreateDropRoleStmt; } public boolean isGrantRevokeRoleStmt() { return stmt_ instanceof GrantRevokeRoleStmt; @@ -171,7 +173,7 @@ public class AnalysisContext { private boolean isViewMetadataStmt() { return isShowFilesStmt() || isShowTablesStmt() || isShowDbsStmt() || - isShowFunctionsStmt() || isShowRolesStmt() || isShowGrantRoleStmt() || + isShowFunctionsStmt() || isShowRolesStmt() || isShowGrantPrincipalStmt() || isShowCreateTableStmt() || isShowDataSrcsStmt() || isShowStatsStmt() || isDescribeTableStmt() || isDescribeDbStmt() || isShowCreateFunctionStmt(); } http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java b/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java new file mode 100644 index 0000000..6e84acc --- /dev/null +++ b/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java @@ -0,0 +1,95 @@ +// 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.impala.analysis; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import org.apache.impala.catalog.Principal; +import org.apache.impala.common.AnalysisException; +import org.apache.impala.common.InternalException; +import org.apache.impala.thrift.TPrincipalType; +import org.apache.impala.thrift.TShowGrantPrincipalParams; + +import java.util.List; + +/** + * Represents "SHOW GRANT ROLE <role>" [ON <privilegeSpec>]" and + * "SHOW GRANT USER <user> [ON <privilegeSpec>]" statements. + */ +public class ShowGrantPrincipalStmt extends AuthorizationStmt { + private final PrivilegeSpec privilegeSpec_; + private final String name_; + private final TPrincipalType principalType_; + + // Set/modified during analysis. + private Principal principal_; + + public ShowGrantPrincipalStmt(String name, TPrincipalType principalType, + PrivilegeSpec privilegeSpec) { + Preconditions.checkNotNull(name); + Preconditions.checkNotNull(principalType); + name_ = name; + principalType_ = principalType; + privilegeSpec_ = privilegeSpec; + } + + @Override + public void analyze(Analyzer analyzer) throws AnalysisException { + super.analyze(analyzer); + if (Strings.isNullOrEmpty(name_)) { + throw new AnalysisException(String.format("%s name in SHOW GRANT %s cannot be " + + "empty.", Principal.toString(principalType_), + Principal.toString(principalType_).toUpperCase())); + } + principal_ = analyzer.getCatalog().getAuthPolicy().getPrincipal(name_, + principalType_); + if (principal_ == null) { + throw new AnalysisException(String.format("%s '%s' does not exist.", + Principal.toString(principalType_), name_)); + } + if (privilegeSpec_ != null) privilegeSpec_.analyze(analyzer); + } + + @Override + public String toSql() { + StringBuilder sb = new StringBuilder(String.format("SHOW GRANT %s ", + Principal.toString(principalType_).toUpperCase())); + sb.append(name_); + if (privilegeSpec_ != null) sb.append(" " + privilegeSpec_.toSql()); + return sb.toString(); + } + + @Override + public void collectTableRefs(List<TableRef> tblRefs) { + if (privilegeSpec_ != null) privilegeSpec_.collectTableRefs(tblRefs); + } + + public TShowGrantPrincipalParams toThrift() throws InternalException { + TShowGrantPrincipalParams params = new TShowGrantPrincipalParams(); + params.setName(name_); + params.setPrincipal_type(principalType_); + params.setRequesting_user(requestingUser_.getShortName()); + if (privilegeSpec_ != null) { + params.setPrivilege(privilegeSpec_.toThrift().get(0)); + params.getPrivilege().setPrincipal_id(principal_.getId()); + } + return params; + } + + public Principal getPrincipal() { return principal_; } +} http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/analysis/ShowGrantRoleStmt.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/analysis/ShowGrantRoleStmt.java b/fe/src/main/java/org/apache/impala/analysis/ShowGrantRoleStmt.java deleted file mode 100644 index 749bcc2..0000000 --- a/fe/src/main/java/org/apache/impala/analysis/ShowGrantRoleStmt.java +++ /dev/null @@ -1,86 +0,0 @@ -// 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.impala.analysis; - -import java.util.List; - -import org.apache.impala.catalog.Role; -import org.apache.impala.common.AnalysisException; -import org.apache.impala.common.InternalException; -import org.apache.impala.thrift.TShowGrantRoleParams; - -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; - -/** - * Represents a "SHOW GRANT ROLE <role> [ON <privilegeSpec>]" statement. - */ -public class ShowGrantRoleStmt extends AuthorizationStmt { - private final PrivilegeSpec privilegeSpec_; - private final String roleName_; - - // Set/modified during analysis - private Role role_; - - public ShowGrantRoleStmt(String roleName, PrivilegeSpec privilegeSpec) { - Preconditions.checkNotNull(roleName); - roleName_ = roleName; - privilegeSpec_ = privilegeSpec; - } - - public TShowGrantRoleParams toThrift() throws InternalException { - TShowGrantRoleParams params = new TShowGrantRoleParams(); - params.setRole_name(roleName_); - params.setRequesting_user(requestingUser_.getShortName()); - if (privilegeSpec_ != null) { - params.setPrivilege(privilegeSpec_.toThrift().get(0)); - params.getPrivilege().setPrincipal_id(role_.getId()); - params.getPrivilege().setPrincipal_type(role_.getPrincipalType()); - } - return params; - } - - @Override - public String toSql() { - StringBuilder sb = new StringBuilder("SHOW GRANT ROLE "); - sb.append(roleName_); - if (privilegeSpec_ != null) sb.append(" " + privilegeSpec_.toSql()); - return sb.toString(); - } - - @Override - public void collectTableRefs(List<TableRef> tblRefs) { - if (privilegeSpec_ != null) privilegeSpec_.collectTableRefs(tblRefs); - } - - @Override - public void analyze(Analyzer analyzer) throws AnalysisException { - super.analyze(analyzer); - if (Strings.isNullOrEmpty(roleName_)) { - throw new AnalysisException("Role name in SHOW GRANT ROLE cannot be " + - "empty."); - } - role_ = analyzer.getCatalog().getAuthPolicy().getRole(roleName_); - if (role_ == null) { - throw new AnalysisException(String.format("Role '%s' does not exist.", roleName_)); - } - if (privilegeSpec_ != null) privilegeSpec_.analyze(analyzer); - } - - public Role getRole() { return role_; } -} http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/catalog/AuthorizationPolicy.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/catalog/AuthorizationPolicy.java b/fe/src/main/java/org/apache/impala/catalog/AuthorizationPolicy.java index a151eb4..ffb8cfd 100644 --- a/fe/src/main/java/org/apache/impala/catalog/AuthorizationPolicy.java +++ b/fe/src/main/java/org/apache/impala/catalog/AuthorizationPolicy.java @@ -413,30 +413,12 @@ public class AuthorizationPolicy implements PrivilegeCache { } /** - * Returns the privileges that have been granted to a role as a tabular result set. - * Allows for filtering based on a specific privilege spec or showing all privileges - * granted to the role. Used by the SHOW GRANT ROLE statement. - */ - public synchronized TResultSet getRolePrivileges(String roleName, TPrivilege filter) { - return getPrincipalPrivileges(roleName, filter, TPrincipalType.ROLE); - } - - /** - * Returns the privileges that have been granted to a user as a tabular result set. - * Allows for filtering based on a specific privilege spec or showing all privileges - * granted to the user. Used by the SHOW GRANT USER statement. - */ - public synchronized TResultSet getUserPrivileges(String userName, TPrivilege filter) { - return getPrincipalPrivileges(userName, filter, TPrincipalType.USER); - } - - /** * Returns the privileges that have been granted to a principal as a tabular result set. * Allows for filtering based on a specific privilege spec or showing all privileges - * granted to the principal. + * granted to the principal. Used by the SHOW GRANT ROLE/USER statement. */ - private TResultSet getPrincipalPrivileges(String principalName, TPrivilege filter, - TPrincipalType type) { + public synchronized TResultSet getPrincipalPrivileges(String principalName, + TPrivilege filter, TPrincipalType type) { TResultSet result = new TResultSet(); result.setSchema(new TResultSetMetadata()); result.getSchema().addToColumns(new TColumn("scope", Type.STRING.toThrift())); http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/service/Frontend.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/service/Frontend.java b/fe/src/main/java/org/apache/impala/service/Frontend.java index 29d917e..fcb5ce2 100644 --- a/fe/src/main/java/org/apache/impala/service/Frontend.java +++ b/fe/src/main/java/org/apache/impala/service/Frontend.java @@ -55,7 +55,7 @@ import org.apache.impala.analysis.InsertStmt; import org.apache.impala.analysis.QueryStmt; import org.apache.impala.analysis.ResetMetadataStmt; import org.apache.impala.analysis.ShowFunctionsStmt; -import org.apache.impala.analysis.ShowGrantRoleStmt; +import org.apache.impala.analysis.ShowGrantPrincipalStmt; import org.apache.impala.analysis.ShowRolesStmt; import org.apache.impala.analysis.SqlParser; import org.apache.impala.analysis.SqlScanner; @@ -472,16 +472,17 @@ public class Frontend { } metadata.setColumns(Arrays.asList( new TColumn("role_name", Type.STRING.toThrift()))); - } else if (analysis.isShowGrantRoleStmt()) { - ddl.op_type = TCatalogOpType.SHOW_GRANT_ROLE; - ShowGrantRoleStmt showGrantRoleStmt = (ShowGrantRoleStmt) analysis.getStmt(); - ddl.setShow_grant_role_params(showGrantRoleStmt.toThrift()); + } else if (analysis.isShowGrantPrincipalStmt()) { + ddl.op_type = TCatalogOpType.SHOW_GRANT_PRINCIPAL; + ShowGrantPrincipalStmt showGrantPrincipalStmt = + (ShowGrantPrincipalStmt) analysis.getStmt(); + ddl.setShow_grant_principal_params(showGrantPrincipalStmt.toThrift()); Set<String> groupNames = getAuthzChecker().getUserGroups(analysis.getAnalyzer().getUser()); // User must be an admin to execute this operation if they have not been granted - // this role. - ddl.getShow_grant_role_params().setIs_admin_op(Sets.intersection(groupNames, - showGrantRoleStmt.getRole().getGrantGroups()).isEmpty()); + // this principal. + ddl.getShow_grant_principal_params().setIs_admin_op(Sets.intersection(groupNames, + showGrantPrincipalStmt.getPrincipal().getGrantGroups()).isEmpty()); metadata.setColumns(Arrays.asList( new TColumn("name", Type.STRING.toThrift()))); } else if (analysis.isCreateDropRoleStmt()) { http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/service/JniFrontend.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/service/JniFrontend.java b/fe/src/main/java/org/apache/impala/service/JniFrontend.java index ce16b51..2781865 100644 --- a/fe/src/main/java/org/apache/impala/service/JniFrontend.java +++ b/fe/src/main/java/org/apache/impala/service/JniFrontend.java @@ -87,7 +87,7 @@ import org.apache.impala.thrift.TMetadataOpRequest; import org.apache.impala.thrift.TQueryCtx; import org.apache.impala.thrift.TResultSet; import org.apache.impala.thrift.TShowFilesParams; -import org.apache.impala.thrift.TShowGrantRoleParams; +import org.apache.impala.thrift.TShowGrantPrincipalParams; import org.apache.impala.thrift.TShowRolesParams; import org.apache.impala.thrift.TShowRolesResult; import org.apache.impala.thrift.TShowStatsOp; @@ -551,11 +551,16 @@ public class JniFrontend { } } - public byte[] getRolePrivileges(byte[] showGrantRolesParams) throws ImpalaException { - TShowGrantRoleParams params = new TShowGrantRoleParams(); - JniUtil.deserializeThrift(protocolFactory_, params, showGrantRolesParams); - TResultSet result = frontend_.getCatalog().getAuthPolicy().getRolePrivileges( - params.getRole_name(), params.getPrivilege()); + /** + * Gets the principal privileges for the given principal. + */ + public byte[] getPrincipalPrivileges(byte[] showGrantPrincipalParams) + throws ImpalaException { + TShowGrantPrincipalParams params = new TShowGrantPrincipalParams(); + JniUtil.deserializeThrift(protocolFactory_, params, showGrantPrincipalParams); + TResultSet result; + result = frontend_.getCatalog().getAuthPolicy().getPrincipalPrivileges( + params.getName(), params.getPrivilege(), params.getPrincipal_type()); TSerializer serializer = new TSerializer(protocolFactory_); try { return serializer.serialize(result); http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/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 dd58131..580434a 100644 --- a/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java +++ b/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java @@ -22,6 +22,7 @@ import java.util.HashSet; import org.apache.impala.authorization.AuthorizationConfig; import org.apache.impala.catalog.Catalog; import org.apache.impala.catalog.Role; +import org.apache.impala.catalog.User; import org.apache.impala.common.AnalysisException; import org.apache.impala.testutil.TestUtils; import org.apache.impala.thrift.TQueryCtx; @@ -32,6 +33,8 @@ public class AnalyzeAuthStmtsTest extends AnalyzerTest { public AnalyzeAuthStmtsTest() { catalog_.getAuthPolicy().addPrincipal( new Role("myRole", new HashSet<String>())); + catalog_.getAuthPolicy().addPrincipal( + new User("myUser", new HashSet<String>())); } @Override @@ -70,22 +73,30 @@ public class AnalyzeAuthStmtsTest extends AnalyzerTest { } @Test - public void AnalyzeShowGrantRole() { - AnalyzesOk("SHOW GRANT ROLE myRole"); - AnalyzesOk("SHOW GRANT ROLE myRole ON SERVER"); - AnalyzesOk("SHOW GRANT ROLE myRole ON DATABASE functional"); - AnalyzesOk("SHOW GRANT ROLE myRole ON TABLE functional.alltypes"); - AnalyzesOk("SHOW GRANT ROLE myRole ON URI 'hdfs:////test-warehouse//foo'"); + public void AnalyzeShowGrantPrincipal() { + for (String type: new String[]{"ROLE myRole", "USER myUser"}) { + AnalyzesOk(String.format("SHOW GRANT %s", type)); + AnalyzesOk(String.format("SHOW GRANT %s ON SERVER", type)); + AnalyzesOk(String.format("SHOW GRANT %s ON DATABASE functional", type)); + AnalyzesOk(String.format("SHOW GRANT %s ON TABLE functional.alltypes", type)); + AnalyzesOk(String.format("SHOW GRANT %s ON URI 'hdfs:////test-warehouse//foo'", + type)); + + AnalysisContext authDisabledCtx = createAuthDisabledAnalysisCtx(); + AnalysisError("SHOW GRANT ROLE myRole", authDisabledCtx, + "Authorization is not enabled."); + AnalysisError("SHOW GRANT ROLE myRole ON SERVER", authDisabledCtx, + "Authorization is not enabled."); + } AnalysisError("SHOW GRANT ROLE does_not_exist", "Role 'does_not_exist' does not exist."); AnalysisError("SHOW GRANT ROLE does_not_exist ON SERVER", "Role 'does_not_exist' does not exist."); - AnalysisContext authDisabledCtx = createAuthDisabledAnalysisCtx(); - AnalysisError("SHOW GRANT ROLE myRole", authDisabledCtx, - "Authorization is not enabled."); - AnalysisError("SHOW GRANT ROLE myRole ON SERVER", authDisabledCtx, - "Authorization is not enabled."); + AnalysisError("SHOW GRANT USER does_not_exist", + "User 'does_not_exist' does not exist."); + AnalysisError("SHOW GRANT USER does_not_exist ON SERVER", + "User 'does_not_exist' does not exist."); } @Test http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java ---------------------------------------------------------------------- diff --git a/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java b/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java index 7e10eee..a750c6f 100644 --- a/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java +++ b/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java @@ -1093,16 +1093,20 @@ public class AuthorizationStmtTest extends FrontendTestBase { // Show role grant group should always be allowed. authorize(String.format("show role grant group `%s`", USER.getName())).ok(); - // Show grant role should always be allowed. + // Show grant role/user should always be allowed. try { authzCatalog_.addRole("test_role"); - authorize("show grant role test_role").ok(); - authorize("show grant role test_role on server").ok(); - authorize("show grant role test_role on database functional").ok(); - authorize("show grant role test_role on table functional.alltypes").ok(); - authorize("show grant role test_role on uri '/test-warehouse'").ok(); + authzCatalog_.addUser("test_user"); + for (String type : new String[]{"role test_role", "user test_user"}) { + authorize(String.format("show grant %s", type)).ok(); + authorize(String.format("show grant %s on server", type)).ok(); + authorize(String.format("show grant %s on database functional", type)).ok(); + authorize(String.format("show grant %s on table functional.alltypes", type)).ok(); + authorize(String.format("show grant %s on uri '/test-warehouse'", type)).ok(); + } } finally { authzCatalog_.removeRole("test_role"); + authzCatalog_.removeUser("test_user"); } // Show create table. http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/test/java/org/apache/impala/analysis/ParserTest.java ---------------------------------------------------------------------- diff --git a/fe/src/test/java/org/apache/impala/analysis/ParserTest.java b/fe/src/test/java/org/apache/impala/analysis/ParserTest.java index a86f467..be97d67 100644 --- a/fe/src/test/java/org/apache/impala/analysis/ParserTest.java +++ b/fe/src/test/java/org/apache/impala/analysis/ParserTest.java @@ -3675,22 +3675,25 @@ public class ParserTest extends FrontendTestBase { } @Test - public void TestShowGrantRole() { - // Show all grants on a role - ParsesOk("SHOW GRANT ROLE foo"); - - // Show grants on a specific object - ParsesOk("SHOW GRANT ROLE foo ON SERVER"); - ParsesOk("SHOW GRANT ROLE foo ON DATABASE foo"); - ParsesOk("SHOW GRANT ROLE foo ON TABLE foo"); - ParsesOk("SHOW GRANT ROLE foo ON TABLE foo.bar"); - ParsesOk("SHOW GRANT ROLE foo ON URI '/abc/123'"); - - ParserError("SHOW GRANT ROLE"); - ParserError("SHOW GRANT ROLE foo ON SERVER foo"); - ParserError("SHOW GRANT ROLE foo ON DATABASE"); - ParserError("SHOW GRANT ROLE foo ON TABLE"); - ParserError("SHOW GRANT ROLE foo ON URI abc"); + public void TestShowGrantPrincipal() { + for (String type: new String[]{"ROLE", "USER"}) { + // Show all grants on a particular principal type. + ParsesOk(String.format("SHOW GRANT %s foo", type)); + + // Show grants on a specific object + ParsesOk(String.format("SHOW GRANT %s foo ON SERVER", type)); + ParsesOk(String.format("SHOW GRANT %s foo ON DATABASE foo", type)); + ParsesOk(String.format("SHOW GRANT %s foo ON TABLE foo", type)); + ParsesOk(String.format("SHOW GRANT %s foo ON TABLE foo.bar", type)); + ParsesOk(String.format("SHOW GRANT %s foo ON URI '/abc/123'", type)); + + ParserError(String.format("SHOW GRANT %s", type)); + ParserError(String.format("SHOW GRANT %s foo ON SERVER foo", type)); + ParserError(String.format("SHOW GRANT %s foo ON DATABASE", type)); + ParserError(String.format("SHOW GRANT %s foo ON TABLE", type)); + ParserError(String.format("SHOW GRANT %s foo ON URI abc", type)); + } + ParserError("SHOW GRANT FOO bar"); } @Test
