diff --git cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java index 06c3f6c..27b8504 100644 --- cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java +++ cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java @@ -216,7 +216,7 @@ public int processCmd(String cmd) { } } else { // local mode try { - CommandProcessor proc = CommandProcessorFactory.get(tokens[0], (HiveConf) conf); + CommandProcessor proc = CommandProcessorFactory.get(tokens, (HiveConf) conf); ret = processLocalCmd(cmd, proc, ss); } catch (SQLException e) { console.printError("Failed processing command " + tokens[0] + " " + e.getLocalizedMessage(), @@ -579,8 +579,9 @@ public boolean isDelimiterChar (String buffer, int pos) { // We stack a custom Completor on top of our ArgumentCompletor // to reverse this. Completor completor = new Completor () { + @Override public int complete (String buffer, int offset, List completions) { - List comp = (List) completions; + List comp = completions; int ret = ac.complete(buffer, offset, completions); // ConsoleReader will do the substitution if and only if there // is exactly one valid completion, so we ignore other cases. diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java index 32831fa..1f77603 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java @@ -657,7 +657,7 @@ private int showGrantsV2(ShowGrantDesc showGrantDesc) throws HiveException { //only grantInfo is used HiveObjectPrivilege thriftObjectPriv = new HiveObjectPrivilege(new HiveObjectRef( AuthorizationUtils.getThriftHiveObjType(privObj.getType()),privObj.getDbname(), - privObj.getTableviewname(),null,null), principal.getName(), + privObj.getTableviewname(),null,null), principal.getName(), AuthorizationUtils.getThriftPrincipalType(principal.getType()), grantInfo); privList.add(thriftObjectPriv); } @@ -970,6 +970,17 @@ private int roleDDLV2(RoleDDLDesc roleDDLDesc) throws HiveException, IOException List allRoles = authorizer.getAllRoles(); writeListToFile(allRoles, roleDDLDesc.getResFile()); break; + case SHOW_CURRENT_ROLE: + List currentRoles = authorizer.getCurrentRoles(); + List roleNames = new ArrayList(currentRoles.size()); + for (Role role : currentRoles) { + roleNames.add(role.getRoleName()); + } + writeListToFile(roleNames, roleDDLDesc.getResFile()); + break; + case SET_ROLE: + authorizer.setCurrentRole(roleDDLDesc.getName()); + break; default: throw new HiveException("Unkown role operation " + operation.getOperationName()); diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java index 9f15609..eb423c1 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java @@ -459,11 +459,33 @@ public void analyzeInternal(ASTNode ast) throws SemanticException { case HiveParser.TOK_EXCHANGEPARTITION: analyzeExchangePartition(ast); break; + case HiveParser.TOK_SHOW_SET_ROLE: + analyzeSetShowRole(ast); + break; default: throw new SemanticException("Unsupported command."); } } + private void analyzeSetShowRole(ASTNode ast) throws SemanticException { + switch (ast.getChildCount()) { + case 0: + ctx.setResFile(ctx.getLocalTmpPath()); + rootTasks.add(hiveAuthorizationTaskFactory.createShowCurrentRoleTask( + getInputs(), getOutputs(), ctx.getResFile())); + setFetchTask(createFetchTask(RoleDDLDesc.getRoleNameSchema())); + break; + case 1: + rootTasks.add(hiveAuthorizationTaskFactory.createSetRoleTask( + BaseSemanticAnalyzer.unescapeIdentifier(ast.getChild(0).getText()), + getInputs(), getOutputs())); + break; + default: + throw new SemanticException("Internal error. ASTNode expected to have 0 or 1 child. " + + ast.dump()); + } + } + private void analyzeGrantRevokeRole(boolean grant, ASTNode ast) throws SemanticException { Task task; if(grant) { @@ -940,7 +962,7 @@ private void analyzeCreateIndex(ASTNode ast) throws SemanticException { break; case HiveParser.TOK_CREATEINDEX_INDEXTBLNAME: ASTNode ch = (ASTNode) child.getChild(0); - indexTableName = getUnescapedName((ASTNode) ch); + indexTableName = getUnescapedName(ch); break; case HiveParser.TOK_DEFERRED_REBUILDINDEX: deferredRebuild = true; @@ -2120,7 +2142,7 @@ private void analyzeShowLocks(ASTNode ast) throws SemanticException { for (int i = 0; i < ast.getChildCount(); i++) { ASTNode child = (ASTNode) ast.getChild(i); if (child.getType() == HiveParser.TOK_TABTYPE) { - ASTNode tableTypeExpr = (ASTNode) child; + ASTNode tableTypeExpr = child; tableName = QualifiedNameUtil.getFullyQualifiedName((ASTNode) tableTypeExpr.getChild(0)); // get partition metadata if partition specified @@ -2345,7 +2367,7 @@ private void analyzeAlterTableRenameCol(ASTNode ast) throws SemanticException { private void analyzeAlterTableRenamePart(ASTNode ast, String tblName, HashMap oldPartSpec) throws SemanticException { - Map newPartSpec = extractPartitionSpecs((ASTNode) ast.getChild(0)); + Map newPartSpec = extractPartitionSpecs(ast.getChild(0)); if (newPartSpec == null) { throw new SemanticException("RENAME PARTITION Missing Destination" + ast); } @@ -2514,7 +2536,7 @@ private void analyzeAlterTableAddParts(CommonTree ast, boolean expectView) } currentPart = getPartSpec(child); validatePartitionValues(currentPart); // validate reserved values - validatePartSpec(tab, currentPart, (ASTNode)child, conf, true); + validatePartSpec(tab, currentPart, child, conf, true); break; case HiveParser.TOK_PARTITIONLOCATION: // if location specified, set in partition diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g index 7e69912..273f372 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g +++ ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g @@ -281,6 +281,7 @@ TOK_GRANT_ROLE; TOK_REVOKE_ROLE; TOK_SHOW_ROLE_GRANT; TOK_SHOW_ROLES; +TOK_SHOW_SET_ROLE; TOK_SHOWINDEXES; TOK_SHOWDBLOCKS; TOK_INDEXCOMMENT; @@ -671,6 +672,8 @@ ddlStatement | showRoles | grantRole | revokeRole + | setRole + | showCurrentRole ; ifExists @@ -1376,6 +1379,20 @@ showRoles -> ^(TOK_SHOW_ROLES) ; +showCurrentRole +@init {pushMsg("show current role", state);} +@after {popMsg(state);} + : KW_SHOW KW_CURRENT KW_ROLE + -> ^(TOK_SHOW_SET_ROLE) + ; + +setRole +@init {pushMsg("set role", state);} +@after {popMsg(state);} + : KW_SET KW_ROLE roleName=identifier + -> ^(TOK_SHOW_SET_ROLE $roleName) + ; + showGrants @init {pushMsg("show grants", state);} @after {popMsg(state);} diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzerFactory.java ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzerFactory.java index 2495c40..b1d3371 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzerFactory.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzerFactory.java @@ -96,6 +96,7 @@ commandType.put(HiveParser.TOK_GRANT_ROLE, HiveOperation.GRANT_ROLE); commandType.put(HiveParser.TOK_REVOKE_ROLE, HiveOperation.REVOKE_ROLE); commandType.put(HiveParser.TOK_SHOW_ROLES, HiveOperation.SHOW_ROLES); + commandType.put(HiveParser.TOK_SHOW_SET_ROLE, HiveOperation.SHOW_ROLES); commandType.put(HiveParser.TOK_SHOW_ROLE_GRANT, HiveOperation.SHOW_ROLE_GRANT); commandType.put(HiveParser.TOK_ALTERDATABASE_PROPERTIES, HiveOperation.ALTERDATABASE); commandType.put(HiveParser.TOK_DESCDATABASE, HiveOperation.DESCDATABASE); @@ -215,6 +216,7 @@ public static BaseSemanticAnalyzer get(HiveConf conf, ASTNode tree) case HiveParser.TOK_ALTERTABLE_SKEWED: case HiveParser.TOK_TRUNCATETABLE: case HiveParser.TOK_EXCHANGEPARTITION: + case HiveParser.TOK_SHOW_SET_ROLE: return new DDLSemanticAnalyzer(conf); case HiveParser.TOK_ALTERTABLE_PARTITION: HiveOperation commandType = null; diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/authorization/HiveAuthorizationTaskFactory.java ql/src/java/org/apache/hadoop/hive/ql/parse/authorization/HiveAuthorizationTaskFactory.java index 1416c2e..bd6ef24 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/authorization/HiveAuthorizationTaskFactory.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/authorization/HiveAuthorizationTaskFactory.java @@ -56,4 +56,10 @@ public Task createRevokeTask(ASTNode node, HashSet inputs, HashSet outputs) throws SemanticException; + + public Task createSetRoleTask(String roleName, + HashSet inputs, HashSet outputs) throws SemanticException; + + public Task createShowCurrentRoleTask(HashSet inputs, + HashSet outputs, Path resFile) throws SemanticException; } diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/authorization/HiveAuthorizationTaskFactoryImpl.java ql/src/java/org/apache/hadoop/hive/ql/parse/authorization/HiveAuthorizationTaskFactoryImpl.java index e91258a..0d562e9 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/authorization/HiveAuthorizationTaskFactoryImpl.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/authorization/HiveAuthorizationTaskFactoryImpl.java @@ -370,4 +370,21 @@ private Partition getPartition(Table table, Map partSpec) private String toMessage(ErrorMsg message, Object detail) { return detail == null ? message.getMsg() : message.getMsg(detail.toString()); } + + @Override + public Task createSetRoleTask(String roleName, + HashSet inputs, HashSet outputs) + throws SemanticException { + return TaskFactory.get(new DDLWork(inputs, outputs, new RoleDDLDesc(roleName, + RoleDDLDesc.RoleOperation.SET_ROLE)), conf); + } + + @Override + public Task createShowCurrentRoleTask( + HashSet inputs, HashSet outputs, Path resFile) + throws SemanticException { + RoleDDLDesc ddlDesc = new RoleDDLDesc(null, RoleDDLDesc.RoleOperation.SHOW_CURRENT_ROLE); + ddlDesc.setResFile(resFile.toString()); + return TaskFactory.get(new DDLWork(inputs, outputs, ddlDesc), conf); + } } diff --git ql/src/java/org/apache/hadoop/hive/ql/plan/RoleDDLDesc.java ql/src/java/org/apache/hadoop/hive/ql/plan/RoleDDLDesc.java index 77853c5..e3d2b4a 100644 --- ql/src/java/org/apache/hadoop/hive/ql/plan/RoleDDLDesc.java +++ ql/src/java/org/apache/hadoop/hive/ql/plan/RoleDDLDesc.java @@ -28,15 +28,15 @@ private static final long serialVersionUID = 1L; private String name; - + private PrincipalType principalType; - + private boolean group; private RoleOperation operation; - + private String resFile; - + private String roleOwnerName; /** @@ -60,7 +60,8 @@ public static String getRoleDescSchema() { } public static enum RoleOperation { - DROP_ROLE("drop_role"), CREATE_ROLE("create_role"), SHOW_ROLE_GRANT("show_role_grant"), SHOW_ROLES("show_roles"); + DROP_ROLE("drop_role"), CREATE_ROLE("create_role"), SHOW_ROLE_GRANT("show_role_grant"), + SHOW_ROLES("show_roles"), SET_ROLE("set_role"), SHOW_CURRENT_ROLE("show_current_role"); private String operationName; private RoleOperation() { @@ -74,11 +75,12 @@ public String getOperationName() { return operationName; } + @Override public String toString () { return this.operationName; } } - + public RoleDDLDesc(){ } @@ -102,7 +104,7 @@ public String getName() { public void setName(String roleName) { this.name = roleName; } - + @Explain(displayName = "role operation") public RoleOperation getOperation() { return operation; @@ -111,7 +113,7 @@ public RoleOperation getOperation() { public void setOperation(RoleOperation operation) { this.operation = operation; } - + public PrincipalType getPrincipalType() { return principalType; } @@ -127,7 +129,7 @@ public boolean getGroup() { public void setGroup(boolean group) { this.group = group; } - + public String getResFile() { return resFile; } @@ -135,7 +137,7 @@ public String getResFile() { public void setResFile(String resFile) { this.resFile = resFile; } - + public String getRoleOwnerName() { return roleOwnerName; } diff --git ql/src/java/org/apache/hadoop/hive/ql/processors/CommandProcessorFactory.java ql/src/java/org/apache/hadoop/hive/ql/processors/CommandProcessorFactory.java index 0ad2fde..70c76b1 100644 --- ql/src/java/org/apache/hadoop/hive/ql/processors/CommandProcessorFactory.java +++ ql/src/java/org/apache/hadoop/hive/ql/processors/CommandProcessorFactory.java @@ -45,13 +45,13 @@ private CommandProcessorFactory() { public static CommandProcessor get(String cmd) throws SQLException { - return get(cmd, null); + return get(new String[]{cmd}, null); } - public static CommandProcessor getForHiveCommand(String cmd, HiveConf conf) + public static CommandProcessor getForHiveCommand(String[] cmd, HiveConf conf) throws SQLException { HiveCommand hiveCommand = HiveCommand.find(cmd); - if (hiveCommand == null || isBlank(cmd)) { + if (hiveCommand == null || isBlank(cmd[0])) { return null; } if (conf == null) { @@ -61,8 +61,8 @@ public static CommandProcessor getForHiveCommand(String cmd, HiveConf conf) for (String availableCommand : conf.getVar(HiveConf.ConfVars.HIVE_SECURITY_COMMAND_WHITELIST).split(",")) { availableCommands.add(availableCommand.toLowerCase().trim()); } - if (!availableCommands.contains(cmd.trim().toLowerCase())) { - throw new SQLException("Insufficient privileges to execute " + cmd, "42000"); + if (!availableCommands.contains(cmd[0].trim().toLowerCase())) { + throw new SQLException("Insufficient privileges to execute " + cmd[0], "42000"); } switch (hiveCommand) { case SET: @@ -83,13 +83,13 @@ public static CommandProcessor getForHiveCommand(String cmd, HiveConf conf) } } - public static CommandProcessor get(String cmd, HiveConf conf) + public static CommandProcessor get(String[] cmd, HiveConf conf) throws SQLException { CommandProcessor result = getForHiveCommand(cmd, conf); if (result != null) { return result; } - if (isBlank(cmd)) { + if (isBlank(cmd[0])) { return null; } else { if (conf == null) { diff --git ql/src/java/org/apache/hadoop/hive/ql/processors/HiveCommand.java ql/src/java/org/apache/hadoop/hive/ql/processors/HiveCommand.java index 280d94e..ae532f6 100644 --- ql/src/java/org/apache/hadoop/hive/ql/processors/HiveCommand.java +++ ql/src/java/org/apache/hadoop/hive/ql/processors/HiveCommand.java @@ -38,11 +38,18 @@ COMMANDS.add(command.name()); } } - public static HiveCommand find(String command) { - if (command != null) { - command = command.trim().toUpperCase(); - if (COMMANDS.contains(command)) { - return HiveCommand.valueOf(command); + public static HiveCommand find(String[] command) { + if (null == command){ + return null; + } + String cmd = command[0]; + if (cmd != null) { + cmd = cmd.trim().toUpperCase(); + if (command.length > 1 && "role".equalsIgnoreCase(command[1])) { + // special handling for set role r1 statement + return null; + } else if (COMMANDS.contains(cmd)) { + return HiveCommand.valueOf(cmd); } } return null; diff --git ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAccessController.java ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAccessController.java index 008efb1..194e0b0 100644 --- ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAccessController.java +++ ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAccessController.java @@ -19,6 +19,8 @@ import java.util.List; +import org.apache.hadoop.hive.metastore.api.Role; + /** * Interface that is invoked by access control commands, including grant/revoke role/privileges, * create/drop roles, and commands to read the state of authorization rules. @@ -57,4 +59,7 @@ void revokeRole(List hivePrincipals, List roles, boolean List showPrivileges(HivePrincipal principal, HivePrivilegeObject privObj) throws HiveAuthorizationPluginException; + void setCurrentRole(String roleName) throws HiveAuthorizationPluginException; + + List getCurrentRoles() throws HiveAuthorizationPluginException; } diff --git ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizer.java ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizer.java index 632901e..ca5804e 100644 --- ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizer.java +++ ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizer.java @@ -21,6 +21,7 @@ import org.apache.hadoop.hive.common.classification.InterfaceAudience.Public; import org.apache.hadoop.hive.common.classification.InterfaceStability.Evolving; +import org.apache.hadoop.hive.metastore.api.Role; import org.apache.hadoop.hive.ql.security.authorization.HiveAuthorizationProvider; /** @@ -150,7 +151,9 @@ void checkPrivileges(HiveOperationType hiveOpType, List inp List showPrivileges(HivePrincipal principal, HivePrivilegeObject privObj) throws HiveAuthorizationPluginException; + void setCurrentRole(String roleName) throws HiveAuthorizationPluginException; + List getCurrentRoles() throws HiveAuthorizationPluginException; //other functions to be added - //showUsersInRole(rolename) //isSuperuser(username) diff --git ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerFactory.java ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerFactory.java index c004105..7674d8d 100644 --- ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerFactory.java +++ ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerFactory.java @@ -39,5 +39,5 @@ * @return new instance of HiveAuthorizer */ HiveAuthorizer createHiveAuthorizer(HiveMetastoreClientFactory metastoreClientFactory, - HiveConf conf, String hiveCurrentUser); + HiveConf conf, String hiveCurrentUser) throws HiveAuthorizationPluginException; } diff --git ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java index 172746e..36296d1 100644 --- ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java +++ ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java @@ -21,6 +21,7 @@ import org.apache.hadoop.hive.common.classification.InterfaceAudience.Public; import org.apache.hadoop.hive.common.classification.InterfaceStability.Evolving; +import org.apache.hadoop.hive.metastore.api.Role; /** * Convenience implementation of HiveAuthorizer. @@ -104,6 +105,16 @@ public VERSION getVersion() { return VERSION.V1; } + @Override + public void setCurrentRole(String roleName) throws HiveAuthorizationPluginException { + accessController.setCurrentRole(roleName); + } + + @Override + public List getCurrentRoles() throws HiveAuthorizationPluginException { + return accessController.getCurrentRoles(); + } + // other access control functions diff --git ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java index 5c5d0e5..8c22cb9 100644 --- ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java +++ ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java @@ -17,6 +17,7 @@ */ package org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -26,11 +27,13 @@ import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.metastore.HiveMetaStore; import org.apache.hadoop.hive.metastore.IMetaStoreClient; import org.apache.hadoop.hive.metastore.api.HiveObjectPrivilege; import org.apache.hadoop.hive.metastore.api.HiveObjectRef; import org.apache.hadoop.hive.metastore.api.HiveObjectType; import org.apache.hadoop.hive.metastore.api.MetaException; +import org.apache.hadoop.hive.metastore.api.PrincipalType; import org.apache.hadoop.hive.metastore.api.PrivilegeBag; import org.apache.hadoop.hive.metastore.api.PrivilegeGrantInfo; import org.apache.hadoop.hive.metastore.api.Role; @@ -46,24 +49,51 @@ import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivilegeObjectType; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveRole; - /** * Implements functionality of access control statements for sql standard based authorization */ @Private public class SQLStdHiveAccessController implements HiveAccessController { - private HiveMetastoreClientFactory metastoreClientFactory; + private final IMetaStoreClient metastoreClient; private static final String [] SUPPORTED_PRIVS = {"INSERT", "UPDATE", "DELETE", "SELECT", "ALL"}; private static final Set SUPPORTED_PRIVS_SET = new HashSet(Arrays.asList(SUPPORTED_PRIVS)); - + private final List currentRoles; + private final String currentUserName; + private Role adminRole; SQLStdHiveAccessController(HiveMetastoreClientFactory metastoreClientFactory, - HiveConf conf, String hiveCurrentUser){ - this.metastoreClientFactory = metastoreClientFactory; + HiveConf conf, String hiveCurrentUser) throws HiveAuthorizationPluginException { + this.currentUserName = hiveCurrentUser; + try { + this.metastoreClient = metastoreClientFactory.getHiveMetastoreClient(); + this.currentRoles = getRolesFromMS(); + } catch (HiveAuthorizationPluginException e) { + throw e; + } catch (IOException e) { + throw new HiveAuthorizationPluginException(e); + } } + private List getRolesFromMS() throws HiveAuthorizationPluginException { + List roles; + try { + roles = metastoreClient.list_roles(currentUserName, PrincipalType.USER); + List currentRoles = new ArrayList(roles.size()); + for (Role role : roles) { + if (!HiveMetaStore.ADMIN.equalsIgnoreCase(role.getRoleName())) { + currentRoles.add(role); + } else { + this.adminRole = role; + } + } + return currentRoles; + } catch (Exception e) { + throw new HiveAuthorizationPluginException("Failed to retrieve roles for "+ + currentUserName, e); + } + } @Override public void grantPrivileges(List hivePrincipals, @@ -74,7 +104,7 @@ public void grantPrivileges(List hivePrincipals, getThriftPrivilegesBag(hivePrincipals, hivePrivileges, hivePrivObject, grantorPrincipal, grantOption); try { - metastoreClientFactory.getHiveMetastoreClient().grant_privileges(privBag); + metastoreClient.grant_privileges(privBag); } catch (Exception e) { throw new HiveAuthorizationPluginException("Error granting privileges", e); } @@ -147,7 +177,7 @@ public void revokePrivileges(List hivePrincipals, getThriftPrivilegesBag(hivePrincipals, hivePrivileges, hivePrivObject, grantorPrincipal, grantOption); try { - metastoreClientFactory.getHiveMetastoreClient().revoke_privileges(privBag); + metastoreClient.revoke_privileges(privBag); } catch (Exception e) { throw new HiveAuthorizationPluginException("Error revoking privileges", e); } @@ -158,8 +188,7 @@ public void createRole(String roleName, HivePrincipal adminGrantor) throws HiveAuthorizationPluginException { try { String grantorName = adminGrantor == null ? null : adminGrantor.getName(); - metastoreClientFactory.getHiveMetastoreClient() - .create_role(new Role(roleName, 0, grantorName)); + metastoreClient.create_role(new Role(roleName, 0, grantorName)); } catch (Exception e) { throw new HiveAuthorizationPluginException("Error create role", e); } @@ -168,7 +197,7 @@ public void createRole(String roleName, HivePrincipal adminGrantor) @Override public void dropRole(String roleName) throws HiveAuthorizationPluginException { try { - metastoreClientFactory.getHiveMetastoreClient().drop_role(roleName); + metastoreClient.drop_role(roleName); } catch (Exception e) { throw new HiveAuthorizationPluginException("Error dropping role", e); } @@ -177,7 +206,7 @@ public void dropRole(String roleName) throws HiveAuthorizationPluginException { @Override public List getRoles(HivePrincipal hivePrincipal) throws HiveAuthorizationPluginException { try { - List roles = metastoreClientFactory.getHiveMetastoreClient().list_roles( + List roles = metastoreClient.list_roles( hivePrincipal.getName(), AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType())); List roleNames = new ArrayList(roles.size()); for (Role role : roles){ @@ -197,14 +226,10 @@ public void grantRole(List hivePrincipals, List roleNames for(HivePrincipal hivePrincipal : hivePrincipals){ for(String roleName : roleNames){ try { - IMetaStoreClient mClient = metastoreClientFactory.getHiveMetastoreClient(); - mClient.grant_role(roleName, - hivePrincipal.getName(), - AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType()), - grantorPrinc.getName(), - AuthorizationUtils.getThriftPrincipalType(grantorPrinc.getType()), - grantOption - ); + metastoreClient.grant_role(roleName, hivePrincipal.getName(), + AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType()), + grantorPrinc.getName(), + AuthorizationUtils.getThriftPrincipalType(grantorPrinc.getType()),grantOption); } catch (MetaException e) { throw new HiveAuthorizationPluginException(e.getMessage(), e); } catch (Exception e) { @@ -227,10 +252,8 @@ public void revokeRole(List hivePrincipals, List roleName for(HivePrincipal hivePrincipal : hivePrincipals){ for(String roleName : roleNames){ try { - IMetaStoreClient mClient = metastoreClientFactory.getHiveMetastoreClient(); - mClient.revoke_role(roleName, - hivePrincipal.getName(), - AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType()) + metastoreClient.revoke_role(roleName,hivePrincipal.getName(), + AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType()) ); } catch (Exception e) { String msg = "Error revoking roles for " + hivePrincipal.getName() + " to role " + roleName @@ -244,7 +267,7 @@ public void revokeRole(List hivePrincipals, List roleName @Override public List getAllRoles() throws HiveAuthorizationPluginException { try { - return metastoreClientFactory.getHiveMetastoreClient().listRoleNames(); + return metastoreClient.listRoleNames(); } catch (Exception e) { throw new HiveAuthorizationPluginException("Error listing all roles", e); } @@ -257,11 +280,10 @@ public void revokeRole(List hivePrincipals, List roleName try { List resPrivInfos = new ArrayList(); - IMetaStoreClient mClient = metastoreClientFactory.getHiveMetastoreClient(); //get metastore/thrift privilege object using metastore api List msObjPrivs - = mClient.list_privileges(principal.getName(), + = metastoreClient.list_privileges(principal.getName(), AuthorizationUtils.getThriftPrincipalType(principal.getType()), getThriftHiveObjectRef(privObj)); @@ -303,7 +325,6 @@ public void revokeRole(List hivePrincipals, List roleName } - private HivePrivilegeObjectType getPluginObjType(HiveObjectType objectType) throws HiveAuthorizationPluginException { switch(objectType){ @@ -320,4 +341,31 @@ private HivePrivilegeObjectType getPluginObjType(HiveObjectType objectType) } } + @Override + public void setCurrentRole(String roleName) throws HiveAuthorizationPluginException { + if ("NONE".equalsIgnoreCase(roleName)) { + currentRoles.clear(); + currentRoles.addAll(getRolesFromMS()); + return; + } + for (Role role : getRolesFromMS()) { + if (role.getRoleName().equalsIgnoreCase(roleName)) { + currentRoles.clear(); + currentRoles.add(role); + return; + } + } + if (HiveMetaStore.ADMIN.equalsIgnoreCase(roleName) && null != this.adminRole) { + currentRoles.clear(); + currentRoles.add(adminRole); + return; + } + throw new HiveAuthorizationPluginException(currentUserName +" doesn't belong to role " + +roleName); + } + + @Override + public List getCurrentRoles() throws HiveAuthorizationPluginException { + return currentRoles; + } } diff --git ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAuthorizerFactory.java ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAuthorizerFactory.java index 7688bbf..b6846a1 100644 --- ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAuthorizerFactory.java +++ ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAuthorizerFactory.java @@ -19,6 +19,7 @@ import org.apache.hadoop.hive.common.classification.InterfaceAudience.Private; import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizationPluginException; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizer; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizerFactory; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizerImpl; @@ -28,7 +29,7 @@ public class SQLStdHiveAuthorizerFactory implements HiveAuthorizerFactory{ @Override public HiveAuthorizer createHiveAuthorizer(HiveMetastoreClientFactory metastoreClientFactory, - HiveConf conf, String hiveCurrentUser) { + HiveConf conf, String hiveCurrentUser) throws HiveAuthorizationPluginException { return new HiveAuthorizerImpl( new SQLStdHiveAccessController(metastoreClientFactory, conf, hiveCurrentUser), new SQLStdHiveAuthorizationValidator() diff --git ql/src/test/org/apache/hadoop/hive/ql/processors/TestCommandProcessorFactory.java ql/src/test/org/apache/hadoop/hive/ql/processors/TestCommandProcessorFactory.java index 732897f..ac5053a 100644 --- ql/src/test/org/apache/hadoop/hive/ql/processors/TestCommandProcessorFactory.java +++ ql/src/test/org/apache/hadoop/hive/ql/processors/TestCommandProcessorFactory.java @@ -39,25 +39,26 @@ public void setUp() throws Exception { @Test public void testInvalidCommands() throws Exception { Assert.assertNull("Null should have returned null", CommandProcessorFactory.getForHiveCommand(null, conf)); - Assert.assertNull("Blank should have returned null", CommandProcessorFactory.getForHiveCommand(" ", conf)); - Assert.assertNull("SQL should have returned null", CommandProcessorFactory.getForHiveCommand("SELECT * FROM TABLE", conf)); + Assert.assertNull("Blank should have returned null", CommandProcessorFactory.getForHiveCommand(new String[]{" "}, conf)); + Assert.assertNull("set role should have returned null", CommandProcessorFactory.getForHiveCommand(new String[]{"set role"}, conf)); + Assert.assertNull("SQL should have returned null", CommandProcessorFactory.getForHiveCommand(new String[]{"SELECT * FROM TABLE"}, conf)); } @Test public void testAvailableCommands() throws Exception { SessionState.start(conf); for (HiveCommand command : HiveCommand.values()) { String cmd = command.name(); - Assert.assertNotNull("Cmd " + cmd + " not return null", CommandProcessorFactory.getForHiveCommand(cmd, conf)); + Assert.assertNotNull("Cmd " + cmd + " not return null", CommandProcessorFactory.getForHiveCommand(new String[]{cmd}, conf)); } for (HiveCommand command : HiveCommand.values()) { String cmd = command.name().toLowerCase(); - Assert.assertNotNull("Cmd " + cmd + " not return null", CommandProcessorFactory.getForHiveCommand(cmd, conf)); + Assert.assertNotNull("Cmd " + cmd + " not return null", CommandProcessorFactory.getForHiveCommand(new String[]{cmd}, conf)); } conf.set(HiveConf.ConfVars.HIVE_SECURITY_COMMAND_WHITELIST.toString(), ""); for (HiveCommand command : HiveCommand.values()) { String cmd = command.name(); try { - CommandProcessorFactory.getForHiveCommand(cmd, conf); + CommandProcessorFactory.getForHiveCommand(new String[]{cmd}, conf); Assert.fail("Expected SQLException for " + cmd + " as available commands is empty"); } catch (SQLException e) { Assert.assertEquals("Insufficient privileges to execute " + cmd, e.getMessage()); diff --git ql/src/test/queries/clientpositive/authorization_set_show_current_role.q ql/src/test/queries/clientpositive/authorization_set_show_current_role.q new file mode 100644 index 0000000..2da41d9 --- /dev/null +++ ql/src/test/queries/clientpositive/authorization_set_show_current_role.q @@ -0,0 +1,20 @@ +set hive.security.authorization.manager=org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory; + +set hive.security.authorization.enabled=true; + +show current role; + +create role r1; +grant role r1 to user hive_test_user; +set role r1; +show current role; + +set role PUBLIC; +show current role; + +set role NONE; +show current role; + +drop role r1; + +set hive.security.authorization.enabled=false; diff --git ql/src/test/results/clientpositive/authorization_set_show_current_role.q.out ql/src/test/results/clientpositive/authorization_set_show_current_role.q.out new file mode 100644 index 0000000..47e4bf8 --- /dev/null +++ ql/src/test/results/clientpositive/authorization_set_show_current_role.q.out @@ -0,0 +1,49 @@ +PREHOOK: query: show current role +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: show current role +POSTHOOK: type: SHOW_ROLES +PUBLIC + +PREHOOK: query: create role r1 +PREHOOK: type: CREATEROLE +POSTHOOK: query: create role r1 +POSTHOOK: type: CREATEROLE +PREHOOK: query: grant role r1 to user hive_test_user +PREHOOK: type: GRANT_ROLE +POSTHOOK: query: grant role r1 to user hive_test_user +POSTHOOK: type: GRANT_ROLE +PREHOOK: query: set role r1 +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: set role r1 +POSTHOOK: type: SHOW_ROLES +PREHOOK: query: show current role +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: show current role +POSTHOOK: type: SHOW_ROLES +r1 + +PREHOOK: query: set role PUBLIC +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: set role PUBLIC +POSTHOOK: type: SHOW_ROLES +PREHOOK: query: show current role +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: show current role +POSTHOOK: type: SHOW_ROLES +PUBLIC + +PREHOOK: query: set role NONE +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: set role NONE +POSTHOOK: type: SHOW_ROLES +PREHOOK: query: show current role +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: show current role +POSTHOOK: type: SHOW_ROLES +r1 +PUBLIC + +PREHOOK: query: drop role r1 +PREHOOK: type: DROPROLE +POSTHOOK: query: drop role r1 +POSTHOOK: type: DROPROLE diff --git service/src/java/org/apache/hive/service/cli/operation/ExecuteStatementOperation.java service/src/java/org/apache/hive/service/cli/operation/ExecuteStatementOperation.java index d00db1c..e973f83 100644 --- service/src/java/org/apache/hive/service/cli/operation/ExecuteStatementOperation.java +++ service/src/java/org/apache/hive/service/cli/operation/ExecuteStatementOperation.java @@ -51,10 +51,9 @@ public static ExecuteStatementOperation newExecuteStatementOperation( HiveSession parentSession, String statement, Map confOverlay, boolean runAsync) throws HiveSQLException { String[] tokens = statement.trim().split("\\s+"); - String command = tokens[0].toLowerCase(); CommandProcessor processor = null; try { - processor = CommandProcessorFactory.getForHiveCommand(tokens[0], parentSession.getHiveConf()); + processor = CommandProcessorFactory.getForHiveCommand(tokens, parentSession.getHiveConf()); } catch (SQLException e) { throw new HiveSQLException(e.getMessage(), e.getSQLState(), e); }