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 c1afaee..cb1c4e4 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 @@ -62,6 +62,8 @@ private HiveRole adminRole; private final String ADMIN_ONLY_MSG = "User has to belong to ADMIN role and " + "have it as current role, for this action."; + private final String HAS_ADMIN_PRIV_MSG = "grantor need to have ADMIN privileges on role being" + + " granted and have it as a current role for this action."; SQLStdHiveAccessController(HiveMetastoreClientFactory metastoreClientFactory, HiveConf conf, HiveAuthenticationProvider authenticator) throws HiveAuthzPluginException { @@ -275,9 +277,9 @@ public void dropRole(String roleName) throws HiveAuthzPluginException, HiveAcces public void grantRole(List hivePrincipals, List roleNames, boolean grantOption, HivePrincipal grantorPrinc) throws HiveAuthzPluginException, HiveAccessControlException { - if (!isUserAdmin()) { + if (!(isUserAdmin() || doesUserHasAdminOption(roleNames))) { throw new HiveAccessControlException("Current user : " + currentUserName+ " is not" - + " allowed to grant role. Currently " + ADMIN_ONLY_MSG); + + " allowed to grant role. " + ADMIN_ONLY_MSG + " Otherwise, " + HAS_ADMIN_PRIV_MSG); } for (HivePrincipal hivePrincipal : hivePrincipals) { for (String roleName : roleNames) { @@ -307,9 +309,9 @@ public void revokeRole(List hivePrincipals, List roleName throw new HiveAuthzPluginException("Revoking only the admin privileges on " + "role is not currently supported"); } - if (!isUserAdmin()) { + if (!(isUserAdmin() || doesUserHasAdminOption(roleNames))) { throw new HiveAccessControlException("Current user : " + currentUserName+ " is not" - + " allowed to revoke role. " + ADMIN_ONLY_MSG); + + " allowed to revoke role. " + ADMIN_ONLY_MSG + " Otherwise, " + HAS_ADMIN_PRIV_MSG); } for (HivePrincipal hivePrincipal : hivePrincipals) { for (String roleName : roleNames) { @@ -404,6 +406,7 @@ private HivePrivilegeObjectType getPluginObjType(HiveObjectType objectType) public void setCurrentRole(String roleName) throws HiveAccessControlException, HiveAuthzPluginException { + initUserRoles(); if ("NONE".equalsIgnoreCase(roleName)) { // for set role NONE, reset roles to default roles. currentRoles.clear(); @@ -453,4 +456,30 @@ boolean isUserAdmin() throws HiveAuthzPluginException { } return false; } + + private boolean doesUserHasAdminOption(List roleNames) throws HiveAuthzPluginException { + List currentRoles; + try { + currentRoles = getCurrentRoles(); + } catch (Exception e) { + throw new HiveAuthzPluginException(e); + } + for (String roleName : roleNames) { + boolean roleFound = false; + for (HiveRole currentRole : currentRoles) { + if (roleName.equalsIgnoreCase(currentRole.getRoleName())) { + roleFound = true; + if (!currentRole.isGrantOption()) { + return false; + } else { + break; + } + } + } + if (!roleFound) { + return false; + } + } + return true; + } } diff --git ql/src/test/queries/clientnegative/authorization_role_grant.q ql/src/test/queries/clientnegative/authorization_role_grant.q new file mode 100644 index 0000000..06c23ef --- /dev/null +++ ql/src/test/queries/clientnegative/authorization_role_grant.q @@ -0,0 +1,22 @@ +set hive.users.in.admin.role=hive_admin_user; +set hive.security.authorization.manager=org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory; +set hive.security.authenticator.manager=org.apache.hadoop.hive.ql.security.SessionStateConfigUserAuthenticator; +set user.name=hive_admin_user; + +set role ADMIN; + +---------------------------------------- +-- role granting with admin option +-- since user2 doesn't have admin option for role_noadmin, last grant should fail +---------------------------------------- + +create role role_noadmin; +create role src_role_wadmin; +grant src_role_wadmin to user user2 with admin option; +grant role_noadmin to user user2; +show role grant user user2; + + +set user.name=user2; +set role role_noadmin; +grant src_role_wadmin to user user3; diff --git ql/src/test/queries/clientpositive/authorization_role_grant2.q ql/src/test/queries/clientpositive/authorization_role_grant2.q new file mode 100644 index 0000000..04fda84 --- /dev/null +++ ql/src/test/queries/clientpositive/authorization_role_grant2.q @@ -0,0 +1,21 @@ +set hive.users.in.admin.role=hive_admin_user; +set hive.security.authorization.manager=org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory; +set hive.security.authenticator.manager=org.apache.hadoop.hive.ql.security.SessionStateConfigUserAuthenticator; +set user.name=hive_admin_user; + +set role ADMIN; + +---------------------------------------- +-- role granting with admin option +---------------------------------------- + +create role src_role_wadmin; +grant src_role_wadmin to user user2 with admin option; +show role grant user user2; + +set user.name=user2; +set role src_role_wadmin; +grant src_role_wadmin to user user3; +show role grant user user3; +revoke src_role_wadmin from user user3; +show role grant user user3; diff --git ql/src/test/results/clientnegative/authorization_role_grant.q.out ql/src/test/results/clientnegative/authorization_role_grant.q.out new file mode 100644 index 0000000..de17ae9 --- /dev/null +++ ql/src/test/results/clientnegative/authorization_role_grant.q.out @@ -0,0 +1,44 @@ +PREHOOK: query: set role ADMIN +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: set role ADMIN +POSTHOOK: type: SHOW_ROLES +PREHOOK: query: ---------------------------------------- +-- role granting with admin option +-- since user2 doesn't have admin option for role_noadmin, last grant should fail +---------------------------------------- + +create role role_noadmin +PREHOOK: type: CREATEROLE +POSTHOOK: query: ---------------------------------------- +-- role granting with admin option +-- since user2 doesn't have admin option for role_noadmin, last grant should fail +---------------------------------------- + +create role role_noadmin +POSTHOOK: type: CREATEROLE +PREHOOK: query: create role src_role_wadmin +PREHOOK: type: CREATEROLE +POSTHOOK: query: create role src_role_wadmin +POSTHOOK: type: CREATEROLE +PREHOOK: query: grant src_role_wadmin to user user2 with admin option +PREHOOK: type: GRANT_ROLE +POSTHOOK: query: grant src_role_wadmin to user user2 with admin option +POSTHOOK: type: GRANT_ROLE +PREHOOK: query: grant role_noadmin to user user2 +PREHOOK: type: GRANT_ROLE +POSTHOOK: query: grant role_noadmin to user user2 +POSTHOOK: type: GRANT_ROLE +PREHOOK: query: show role grant user user2 +PREHOOK: type: SHOW_ROLE_GRANT +POSTHOOK: query: show role grant user user2 +POSTHOOK: type: SHOW_ROLE_GRANT +PUBLIC -1 false -1 +role_noadmin -1 user2 USER false -1 hive_admin_user +src_role_wadmin -1 user2 USER true -1 hive_admin_user +PREHOOK: query: set role role_noadmin +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: set role role_noadmin +POSTHOOK: type: SHOW_ROLES +PREHOOK: query: grant src_role_wadmin to user user3 +PREHOOK: type: GRANT_ROLE +FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAccessControlException: Current user : user2 is not allowed to grant role. User has to belong to ADMIN role and have it as current role, for this action. Otherwise, grantor need to have ADMIN privileges on role being granted and have it as a current role for this action. diff --git ql/src/test/results/clientnegative/authorization_set_role_neg2.q.out ql/src/test/results/clientnegative/authorization_set_role_neg2.q.out index eec684d..ee03c0e 100644 --- ql/src/test/results/clientnegative/authorization_set_role_neg2.q.out +++ ql/src/test/results/clientnegative/authorization_set_role_neg2.q.out @@ -16,4 +16,12 @@ POSTHOOK: query: grant role rset_role_neg to user user2 POSTHOOK: type: GRANT_ROLE PREHOOK: query: set role rset_role_neg PREHOOK: type: SHOW_ROLES -FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. hive_admin_user doesn't belong to role rset_role_neg +POSTHOOK: query: set role rset_role_neg +POSTHOOK: type: SHOW_ROLES +PREHOOK: query: set role public +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: set role public +POSTHOOK: type: SHOW_ROLES +PREHOOK: query: set role nosuchroleexists +PREHOOK: type: SHOW_ROLES +FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. user2 doesn't belong to role nosuchroleexists diff --git ql/src/test/results/clientpositive/authorization_role_grant2.q.out ql/src/test/results/clientpositive/authorization_role_grant2.q.out new file mode 100644 index 0000000..81ef8d5 --- /dev/null +++ ql/src/test/results/clientpositive/authorization_role_grant2.q.out @@ -0,0 +1,49 @@ +PREHOOK: query: set role ADMIN +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: set role ADMIN +POSTHOOK: type: SHOW_ROLES +PREHOOK: query: ---------------------------------------- +-- role granting with admin option +---------------------------------------- + +create role src_role_wadmin +PREHOOK: type: CREATEROLE +POSTHOOK: query: ---------------------------------------- +-- role granting with admin option +---------------------------------------- + +create role src_role_wadmin +POSTHOOK: type: CREATEROLE +PREHOOK: query: grant src_role_wadmin to user user2 with admin option +PREHOOK: type: GRANT_ROLE +POSTHOOK: query: grant src_role_wadmin to user user2 with admin option +POSTHOOK: type: GRANT_ROLE +PREHOOK: query: show role grant user user2 +PREHOOK: type: SHOW_ROLE_GRANT +POSTHOOK: query: show role grant user user2 +POSTHOOK: type: SHOW_ROLE_GRANT +PUBLIC -1 false -1 +src_role_wadmin -1 user2 USER true -1 hive_admin_user +PREHOOK: query: set role src_role_wadmin +PREHOOK: type: SHOW_ROLES +POSTHOOK: query: set role src_role_wadmin +POSTHOOK: type: SHOW_ROLES +PREHOOK: query: grant src_role_wadmin to user user3 +PREHOOK: type: GRANT_ROLE +POSTHOOK: query: grant src_role_wadmin to user user3 +POSTHOOK: type: GRANT_ROLE +PREHOOK: query: show role grant user user3 +PREHOOK: type: SHOW_ROLE_GRANT +POSTHOOK: query: show role grant user user3 +POSTHOOK: type: SHOW_ROLE_GRANT +PUBLIC -1 false -1 +src_role_wadmin -1 user3 USER false -1 user2 +PREHOOK: query: revoke src_role_wadmin from user user3 +PREHOOK: type: REVOKE_ROLE +POSTHOOK: query: revoke src_role_wadmin from user user3 +POSTHOOK: type: REVOKE_ROLE +PREHOOK: query: show role grant user user3 +PREHOOK: type: SHOW_ROLE_GRANT +POSTHOOK: query: show role grant user user3 +POSTHOOK: type: SHOW_ROLE_GRANT +PUBLIC -1 false -1