diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java b/metastore/src/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java index 377709f..7af4368 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Map; -import java.util.Set; import org.apache.hadoop.hive.metastore.api.AlreadyExistsException; import org.apache.hadoop.hive.metastore.api.ColumnStatistics; @@ -931,6 +930,8 @@ public boolean revoke_role(String role_name, String user_name, throws MetaException, TException; /** + * Return the privileges that the user, group have directly and indirectly through roles + * on the given hiveObject * @param hiveObject * @param user_name * @param group_names @@ -943,6 +944,7 @@ public PrincipalPrivilegeSet get_privilege_set(HiveObjectRef hiveObject, TException; /** + * Return the privileges that this principal has directly over the object (not through roles). * @param principal_name * @param principal_type * @param hiveObject diff --git a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java index 6705ec4..cbd9e59 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java @@ -55,6 +55,7 @@ import org.apache.hadoop.hive.ql.exec.Utilities; import org.apache.hadoop.hive.ql.history.HiveHistory.Keys; import org.apache.hadoop.hive.ql.hooks.Entity; +import org.apache.hadoop.hive.ql.hooks.Entity.Type; import org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext; import org.apache.hadoop.hive.ql.hooks.Hook; import org.apache.hadoop.hive.ql.hooks.HookContext; @@ -185,6 +186,7 @@ private void createLockManager() throws SemanticException { } } + @Override public void init() { Operator.resetId(); } @@ -728,7 +730,7 @@ private void doAuthorizationV2(SessionState ss, HiveOperation op, HashSet hiveLocks) { perfLogger.PerfLogEnd(CLASS_NAME, PerfLogger.RELEASE_LOCKS); } + @Override public CommandProcessorResponse run(String command) throws CommandNeedRetryException { return run(command, false); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/SessionStateAuthenticator.java b/ql/src/java/org/apache/hadoop/hive/ql/security/SessionStateAuthenticator.java new file mode 100644 index 0000000..8e0ba4c --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/SessionStateAuthenticator.java @@ -0,0 +1,30 @@ +/** + * 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.hadoop.hive.ql.security; + +import org.apache.hadoop.hive.common.classification.InterfaceAudience.Private; +import org.apache.hadoop.hive.ql.session.SessionState; + +/** + * Interface for authenticators that need access to SessionState + */ +@Private +public interface SessionStateAuthenticator extends HiveAuthenticationProvider { + public void setSessionState(SessionState ss); +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/SessionStateConfigUserAuthenticator.java b/ql/src/java/org/apache/hadoop/hive/ql/security/SessionStateConfigUserAuthenticator.java new file mode 100644 index 0000000..37aeb15 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/SessionStateConfigUserAuthenticator.java @@ -0,0 +1,70 @@ +/** + * 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.hadoop.hive.ql.security; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.session.SessionState; + +/** + * Authenticator to be used for testing and debugging. This picks the user.name + * set in SessionState config, if that is null, it returns value of + * System property user.name + */ +public class SessionStateConfigUserAuthenticator implements SessionStateAuthenticator { + + private final List groupNames = new ArrayList(); + + protected Configuration conf; + private SessionState sessionState; + + @Override + public List getGroupNames() { + return groupNames; + } + + @Override + public String getUserName() { + String newUserName = sessionState.getConf().get("user.name"); + return newUserName != null ? newUserName : System.getProperty("user.name"); + } + + @Override + public void destroy() throws HiveException { + return; + } + + @Override + public Configuration getConf() { + return null; + } + + @Override + public void setConf(Configuration arg0) { + } + + @Override + public void setSessionState(SessionState sessionState) { + this.sessionState = sessionState; + } + +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/SessionStateUserAuthenticator.java b/ql/src/java/org/apache/hadoop/hive/ql/security/SessionStateUserAuthenticator.java new file mode 100644 index 0000000..e5434f9 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/SessionStateUserAuthenticator.java @@ -0,0 +1,72 @@ +/** + * 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.hadoop.hive.ql.security; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.session.SessionState; + +/** + * Authenticator that returns the userName set in SessionState. For use when authorizing with HS2 + * so that HS2 can set the user for the session through SessionState + */ +public class SessionStateUserAuthenticator implements SessionStateAuthenticator { + + private final List groupNames = new ArrayList(); + + protected Configuration conf; + private SessionState sessionState; + + public SessionStateUserAuthenticator(SessionState sessionState){ + this.sessionState = sessionState; + } + + @Override + public List getGroupNames() { + return groupNames; + } + + @Override + public String getUserName() { + return sessionState.getUserName(); + } + + @Override + public void destroy() throws HiveException { + return; + } + + @Override + public Configuration getConf() { + return null; + } + + @Override + public void setConf(Configuration arg0) { + } + + @Override + public void setSessionState(SessionState sessionState) { + this.sessionState = sessionState; + } + +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/PrivilegeRegistry.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/PrivilegeRegistry.java index 12aa4ff..6ae2d99 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/PrivilegeRegistry.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/PrivilegeRegistry.java @@ -30,31 +30,16 @@ public class PrivilegeRegistry { protected static Map Registry = null; + protected static Map RegistryV2 = null; public static Privilege getPrivilege(PrivilegeType privilegeType) { - initializeRegistry(); return Registry.get(privilegeType); } - private static void initializeRegistry() { - if(Registry != null){ - //already initialized, nothing to do - return; - } - //population of registry done in separate synchronized call - populateRegistry(); - } - /** - * Add entries to registry. This needs to be synchronized to avoid Registry being populated - * multiple times. + * Add entries to registry. */ - private static synchronized void populateRegistry() { - //do check again in synchronized block - if(Registry != null){ - //already initialized, nothing to do - return; - } + static { Registry = new HashMap(); //add the privileges supported in authorization mode V1 @@ -68,23 +53,28 @@ private static synchronized void populateRegistry() { Registry.put(Privilege.SELECT.getPriv(), Privilege.SELECT); Registry.put(Privilege.SHOW_DATABASE.getPriv(), Privilege.SHOW_DATABASE); - if(SessionState.get().isAuthorizationModeV2()){ - //add the privileges not supported in V1 - //The list of privileges supported in V2 is implementation defined, - //so just pass everything that syntax supports. - Registry.put(Privilege.INSERT.getPriv(), Privilege.INSERT); - Registry.put(Privilege.DELETE.getPriv(), Privilege.DELETE); - } + + //add the privileges not supported in V1 + //The list of privileges supported in V2 is implementation defined, + //so just pass everything that syntax supports. + RegistryV2 = new HashMap(); + RegistryV2.putAll(Registry); + RegistryV2.put(Privilege.INSERT.getPriv(), Privilege.INSERT); + RegistryV2.put(Privilege.DELETE.getPriv(), Privilege.DELETE); } public static Privilege getPrivilege(int privilegeToken) { - initializeRegistry(); - return Registry.get(PrivilegeType.getPrivTypeByToken(privilegeToken)); + PrivilegeType ptype = PrivilegeType.getPrivTypeByToken(privilegeToken); + return getPrivilegeFromRegistry(ptype); } public static Privilege getPrivilege(String privilegeName) { - initializeRegistry(); - return Registry.get(PrivilegeType.getPrivTypeByName(privilegeName)); + PrivilegeType ptype = PrivilegeType.getPrivTypeByName(privilegeName); + return getPrivilegeFromRegistry(ptype); + } + + private static Privilege getPrivilegeFromRegistry(PrivilegeType ptype) { + return SessionState.get().isAuthorizationModeV2() ? RegistryV2.get(ptype) : Registry.get(ptype); } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/PrivilegeType.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/PrivilegeType.java index 484861b..5c2f389 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/PrivilegeType.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/PrivilegeType.java @@ -67,9 +67,7 @@ public Integer getToken() { * @return corresponding PrivilegeType */ public static PrivilegeType getPrivTypeByToken(int token) { - if(token2Type == null){ - populateToken2Type(); - } + populateToken2Type(); PrivilegeType privType = token2Type.get(token); if(privType != null){ return privType; @@ -93,9 +91,7 @@ private static synchronized void populateToken2Type() { * @return corresponding PrivilegeType */ public static PrivilegeType getPrivTypeByName(String privilegeName) { - if(name2Type == null){ - populateName2Type(); - } + populateName2Type(); String canonicalizedName = privilegeName.toLowerCase(); PrivilegeType privType = name2Type.get(canonicalizedName); if(privType != null){ diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAccessController.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAccessController.java index 008efb1..c29ea70 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAccessController.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAccessController.java @@ -28,33 +28,33 @@ void grantPrivileges(List hivePrincipals, List hivePrivileges, HivePrivilegeObject hivePrivObject, HivePrincipal grantorPrincipal, boolean grantOption) - throws HiveAuthorizationPluginException;; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; void revokePrivileges(List hivePrincipals, List hivePrivileges, HivePrivilegeObject hivePrivObject, HivePrincipal grantorPrincipal, boolean grantOption) - throws HiveAuthorizationPluginException;; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; void createRole(String roleName, HivePrincipal adminGrantor) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; void dropRole(String roleName) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; List getRoles(HivePrincipal hivePrincipal) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; void grantRole(List hivePrincipals, List roles, boolean grantOption, HivePrincipal grantorPrinc) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; void revokeRole(List hivePrincipals, List roles, boolean grantOption, HivePrincipal grantorPrinc) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; List getAllRoles() - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; List showPrivileges(HivePrincipal principal, HivePrivilegeObject privObj) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizationPluginException.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizationPluginException.java deleted file mode 100644 index 3ab8a9a..0000000 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizationPluginException.java +++ /dev/null @@ -1,47 +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.hadoop.hive.ql.security.authorization.plugin; - -import org.apache.hadoop.hive.common.classification.InterfaceAudience.Public; -import org.apache.hadoop.hive.ql.metadata.HiveException; - -/** - * Exception thrown by the Authorization plugin api (v2) - */ -@Public -public class HiveAuthorizationPluginException extends HiveException{ - - private static final long serialVersionUID = 1L; - - public HiveAuthorizationPluginException(){ - } - - public HiveAuthorizationPluginException(String msg){ - super(msg); - } - - public HiveAuthorizationPluginException(String msg, Throwable cause){ - super(msg, cause); - } - - public HiveAuthorizationPluginException(Throwable cause){ - super(cause); - } - -} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizationValidator.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizationValidator.java index 59367dd..2bcdc1d 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizationValidator.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizationValidator.java @@ -29,14 +29,18 @@ @Public @Evolving public interface HiveAuthorizationValidator { + /** - * Check if current user has privileges to perform given operation type hiveOpType on the given - * input and output objects + * Check if current user has privileges to perform given operation type + * hiveOpType on the given input and output objects + * * @param hiveOpType * @param inputHObjs * @param outputHObjs + * @throws HiveAuthzPluginException + * @throws HiveAuthzPluginDeniedException */ void checkPrivileges(HiveOperationType hiveOpType, List inputHObjs, - List outputHObjs) throws HiveAuthorizationPluginException; + List outputHObjs) throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizer.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizer.java index 632901e..437a7a3 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizer.java @@ -51,11 +51,12 @@ * @param hivePrivObject * @param grantorPrincipal * @param grantOption - * @throws HiveAuthorizationPluginException + * @throws HiveAuthzPluginException + * @throws HiveAuthzPluginDeniedException */ void grantPrivileges(List hivePrincipals, List hivePrivileges, HivePrivilegeObject hivePrivObject, HivePrincipal grantorPrincipal, boolean grantOption) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; /** * Revoke privileges for principals on the object @@ -64,38 +65,42 @@ void grantPrivileges(List hivePrincipals, List hiv * @param hivePrivObject * @param grantorPrincipal * @param grantOption - * @throws HiveAuthorizationPluginException + * @throws HiveAuthzPluginException + * @throws HiveAuthzPluginDeniedException */ void revokePrivileges(List hivePrincipals, List hivePrivileges, HivePrivilegeObject hivePrivObject, HivePrincipal grantorPrincipal, boolean grantOption) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; /** * Create role * @param roleName * @param adminGrantor - The user in "[ WITH ADMIN ]" clause of "create role" - * @throws HiveAuthorizationPluginException + * @throws HiveAuthzPluginException + * @throws HiveAuthzPluginDeniedException */ void createRole(String roleName, HivePrincipal adminGrantor) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; /** * Drop role * @param roleName - * @throws HiveAuthorizationPluginException + * @throws HiveAuthzPluginException + * @throws HiveAuthzPluginDeniedException */ void dropRole(String roleName) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; /** * Get roles that this user/role belongs to * @param hivePrincipal - user or role * @return list of roles - * @throws HiveAuthorizationPluginException + * @throws HiveAuthzPluginException + * @throws HiveAuthzPluginDeniedException */ List getRoles(HivePrincipal hivePrincipal) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; /** * Grant roles in given roles list to principals in given hivePrincipals list @@ -103,11 +108,12 @@ void dropRole(String roleName) * @param roles * @param grantOption * @param grantorPrinc - * @throws HiveAuthorizationPluginException + * @throws HiveAuthzPluginException + * @throws HiveAuthzPluginDeniedException */ void grantRole(List hivePrincipals, List roles, boolean grantOption, HivePrincipal grantorPrinc) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; /** @@ -116,39 +122,43 @@ void grantRole(List hivePrincipals, List roles, boolean g * @param roles * @param grantOption * @param grantorPrinc - * @throws HiveAuthorizationPluginException + * @throws HiveAuthzPluginException + * @throws HiveAuthzPluginDeniedException */ void revokeRole(List hivePrincipals, List roles, boolean grantOption, HivePrincipal grantorPrinc) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; /** * Check if user has privileges to do this action on these objects * @param hiveOpType * @param inputsHObjs * @param outputHObjs - * @throws HiveAuthorizationPluginException + * @throws HiveAuthzPluginException + * @throws HiveAuthzPluginDeniedException */ void checkPrivileges(HiveOperationType hiveOpType, List inputsHObjs, List outputHObjs) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; /** * @return all existing roles - * @throws HiveAuthorizationPluginException + * @throws HiveAuthzPluginException + * @throws HiveAuthzPluginDeniedException */ List getAllRoles() - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; /** * Show privileges for given principal on given object * @param principal * @param privObj * @return - * @throws HiveAuthorizationPluginException + * @throws HiveAuthzPluginException + * @throws HiveAuthzPluginDeniedException */ List showPrivileges(HivePrincipal principal, HivePrivilegeObject privObj) - throws HiveAuthorizationPluginException; + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException; //other functions to be added - diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerFactory.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerFactory.java index c004105..a8612b4 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerFactory.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerFactory.java @@ -20,6 +20,7 @@ import org.apache.hadoop.hive.common.classification.InterfaceAudience.Public; import org.apache.hadoop.hive.common.classification.InterfaceStability.Evolving; import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider; /** * Implementation of this interface specified through hive configuration will be used to @@ -35,9 +36,9 @@ * for the current thread. Each invocation of method in HiveAuthorizer can happen in * different thread, so get the current instance in each method invocation. * @param conf - current HiveConf - * @param hiveCurrentUser - user for current session + * @param hiveAuthenticator - authenticator, provides user name * @return new instance of HiveAuthorizer */ HiveAuthorizer createHiveAuthorizer(HiveMetastoreClientFactory metastoreClientFactory, - HiveConf conf, String hiveCurrentUser); + HiveConf conf, HiveAuthenticationProvider hiveAuthenticator); } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java index 172746e..f291c01 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthorizerImpl.java @@ -42,7 +42,7 @@ public HiveAuthorizerImpl(HiveAccessController accessController, HiveAuthorizati @Override public void grantPrivileges(List hivePrincipals, List hivePrivileges, HivePrivilegeObject hivePrivObject, - HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthorizationPluginException { + HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { accessController.grantPrivileges(hivePrincipals, hivePrivileges, hivePrivObject, grantorPrincipal, grantOption); } @@ -50,52 +50,52 @@ public void grantPrivileges(List hivePrincipals, @Override public void revokePrivileges(List hivePrincipals, List hivePrivileges, HivePrivilegeObject hivePrivObject, - HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthorizationPluginException { + HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { accessController.revokePrivileges(hivePrincipals, hivePrivileges, hivePrivObject, grantorPrincipal, grantOption); } @Override - public void createRole(String roleName, HivePrincipal adminGrantor) throws HiveAuthorizationPluginException { + public void createRole(String roleName, HivePrincipal adminGrantor) throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { accessController.createRole(roleName, adminGrantor); } @Override - public void dropRole(String roleName) throws HiveAuthorizationPluginException { + public void dropRole(String roleName) throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { accessController.dropRole(roleName); } @Override - public List getRoles(HivePrincipal hivePrincipal) throws HiveAuthorizationPluginException { + public List getRoles(HivePrincipal hivePrincipal) throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { return accessController.getRoles(hivePrincipal); } @Override public void grantRole(List hivePrincipals, List roles, - boolean grantOption, HivePrincipal grantorPrinc) throws HiveAuthorizationPluginException { + boolean grantOption, HivePrincipal grantorPrinc) throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { accessController.grantRole(hivePrincipals, roles, grantOption, grantorPrinc); } @Override public void revokeRole(List hivePrincipals, List roles, - boolean grantOption, HivePrincipal grantorPrinc) throws HiveAuthorizationPluginException { + boolean grantOption, HivePrincipal grantorPrinc) throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { accessController.revokeRole(hivePrincipals, roles, grantOption, grantorPrinc); } @Override public void checkPrivileges(HiveOperationType hiveOpType, List inputHObjs, - List outputHObjs) throws HiveAuthorizationPluginException { + List outputHObjs) throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { authValidator.checkPrivileges(hiveOpType, inputHObjs, outputHObjs); } @Override - public List getAllRoles() throws HiveAuthorizationPluginException { + public List getAllRoles() throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { return accessController.getAllRoles(); } @Override public List showPrivileges(HivePrincipal principal, - HivePrivilegeObject privObj) throws HiveAuthorizationPluginException { + HivePrivilegeObject privObj) throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { return accessController.showPrivileges(principal, privObj); } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthzPluginDeniedException.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthzPluginDeniedException.java new file mode 100644 index 0000000..12b9756 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthzPluginDeniedException.java @@ -0,0 +1,49 @@ +/** + * 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.hadoop.hive.ql.security.authorization.plugin; + +import org.apache.hadoop.hive.common.classification.InterfaceAudience.Public; +import org.apache.hadoop.hive.ql.metadata.HiveException; + +/** + * Exception thrown by the Authorization plugin api (v2). Indicates + * an error while performing authorization, and not a authorization being + * denied. + */ +@Public +public class HiveAuthzPluginDeniedException extends HiveException{ + + private static final long serialVersionUID = 1L; + + public HiveAuthzPluginDeniedException(){ + } + + public HiveAuthzPluginDeniedException(String msg){ + super(msg); + } + + public HiveAuthzPluginDeniedException(String msg, Throwable cause){ + super(msg, cause); + } + + public HiveAuthzPluginDeniedException(Throwable cause){ + super(cause); + } + +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthzPluginException.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthzPluginException.java new file mode 100644 index 0000000..37cd952 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveAuthzPluginException.java @@ -0,0 +1,49 @@ +/** + * 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.hadoop.hive.ql.security.authorization.plugin; + +import org.apache.hadoop.hive.common.classification.InterfaceAudience.Public; +import org.apache.hadoop.hive.ql.metadata.HiveException; + +/** + * Exception thrown by the Authorization plugin api (v2). Indicates + * an error while performing authorization, and not a authorization being + * denied. + */ +@Public +public class HiveAuthzPluginException extends HiveException{ + + private static final long serialVersionUID = 1L; + + public HiveAuthzPluginException(){ + } + + public HiveAuthzPluginException(String msg){ + super(msg); + } + + public HiveAuthzPluginException(String msg, Throwable cause){ + super(msg, cause); + } + + public HiveAuthzPluginException(Throwable cause){ + super(cause); + } + +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveMetastoreClientFactory.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveMetastoreClientFactory.java index 4208b2d..86fb086 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveMetastoreClientFactory.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveMetastoreClientFactory.java @@ -17,8 +17,6 @@ */ package org.apache.hadoop.hive.ql.security.authorization.plugin; -import java.io.IOException; - import org.apache.hadoop.hive.common.classification.InterfaceAudience.Public; import org.apache.hadoop.hive.metastore.IMetaStoreClient; /** @@ -26,5 +24,5 @@ */ @Public public interface HiveMetastoreClientFactory { - IMetaStoreClient getHiveMetastoreClient() throws IOException; + IMetaStoreClient getHiveMetastoreClient() throws HiveAuthzPluginException; } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveMetastoreClientFactoryImpl.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveMetastoreClientFactoryImpl.java index 1fadb3e..019f600 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveMetastoreClientFactoryImpl.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveMetastoreClientFactoryImpl.java @@ -18,8 +18,6 @@ package org.apache.hadoop.hive.ql.security.authorization.plugin; -import java.io.IOException; - import org.apache.hadoop.hive.common.classification.InterfaceAudience.Private; import org.apache.hadoop.hive.metastore.IMetaStoreClient; import org.apache.hadoop.hive.metastore.api.MetaException; @@ -32,13 +30,14 @@ public class HiveMetastoreClientFactoryImpl implements HiveMetastoreClientFactory{ @Override - public IMetaStoreClient getHiveMetastoreClient() throws IOException { + public IMetaStoreClient getHiveMetastoreClient() throws HiveAuthzPluginException { + String errMsg = "Error getting metastore client"; try { return Hive.get().getMSC(); } catch (MetaException e) { - throw new IOException(e); + throw new HiveAuthzPluginException(errMsg, e); } catch (HiveException e) { - throw new IOException(e); + throw new HiveAuthzPluginException(errMsg, e); } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrincipal.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrincipal.java index 42e9f23..75101ac 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrincipal.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrincipal.java @@ -26,6 +26,11 @@ USER, ROLE, UNKNOWN } + @Override + public String toString() { + return "Principal [name=" + name + ", type=" + type + "]"; + } + private final String name; private final HivePrincipalType type; @@ -40,4 +45,32 @@ public HivePrincipalType getType() { return type; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + HivePrincipal other = (HivePrincipal) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (type != other.type) + return false; + return true; + } + } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilege.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilege.java index 4b9d133..207c683 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilege.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilege.java @@ -18,16 +18,22 @@ package org.apache.hadoop.hive.ql.security.authorization.plugin; import java.util.List; +import java.util.Locale; /** * Represents the hive privilege being granted/revoked */ public class HivePrivilege { + @Override + public String toString() { + return "Privilege [name=" + name + ", columns=" + columns + "]"; + } + private final String name; private final List columns; public HivePrivilege(String name, List columns){ - this.name = name; + this.name = name.toUpperCase(Locale.US); this.columns = columns; } @@ -39,4 +45,37 @@ public String getName() { return columns; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((columns == null) ? 0 : columns.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + HivePrivilege other = (HivePrivilege) obj; + if (columns == null) { + if (other.columns != null) + return false; + } else if (!columns.equals(other.columns)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + + } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilegeObject.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilegeObject.java index 5b101c2..ad0bd4e 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilegeObject.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilegeObject.java @@ -27,6 +27,12 @@ @Unstable public class HivePrivilegeObject { + @Override + public String toString() { + return "Hive Object [type=" + type + ", dbname=" + dbname + ", table/viewname=" + + tableviewname + "]"; + } + public enum HivePrivilegeObjectType { DATABASE, TABLE, VIEW, PARTITION, URI}; private final HivePrivilegeObjectType type; private final String dbname; diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/package-info.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/package-info.java new file mode 100644 index 0000000..3927608 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/package-info.java @@ -0,0 +1,32 @@ +/* + * This package provides interfaces and classes that can be used to implement custom authorization for hive. + * + * How hive code uses this interface: + * The interface that hive code invokes is HiveAuthorizer class. + * The classes HivePrincipal, HivePrivilege, HivePrivilegeObject, HivePrivilegeInfo, HiveOperationType + * are arguments used in the authorization interface. + * The methods in the interface throws two types of exceptions - HiveAuthzPluginException (in + * case of internal errors), and HiveAuthzPluginDeniedException (when action is not permitted + * because authorization has failed). + * + * Hive uses the HiveAuthorizerFactory interface, whose implementing class is configurable through + * hive configuration, to instantiate an instance of this interface. + * + * + * Guide on implementing the interface: + * There are two categories of operations to be done by the authorization interface, one is the + * actions performed by the access control statements, which updates the privileges that have + * been granted (and stores in some where like metastore database), and also retrieves the current + * state of privileges. You may choose not to implement this part and juse a no-op implementation + * if you are going to manage the authorization externally (eg, if you base it on mapping to + * file system permissions). + * The 2nd category of operation is authorizing the hive actions by checking against the privileges + * the user has on the objects. + * HiveAccessController has the interface for the first type of operations and + * HiveAuthorizationValidator has interface for second type of operations. + * + * HiveAuthorizerImpl is a convenience class that you can use by just passing the implementations + * of these two interfaces (HiveAuthorizerImpl, HiveAuthorizationValidator) in the constructor. + * + */ +package org.apache.hadoop.hive.ql.security.authorization.plugin; diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/GrantPrivilegeAuthorizer.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/GrantPrivilegeAuthorizer.java new file mode 100644 index 0000000..35bbf79 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/GrantPrivilegeAuthorizer.java @@ -0,0 +1,88 @@ +/** + * 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.hadoop.hive.ql.security.authorization.plugin.sqlstd; + +import java.util.Collection; +import java.util.List; + +import org.apache.hadoop.hive.metastore.IMetaStoreClient; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginDeniedException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal.HivePrincipalType; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilege; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject; + +/** + * Utility class to authorize grant/revoke privileges + */ +public class GrantPrivilegeAuthorizer { + + static void authorize(List hivePrincipals, List hivePrivileges, + HivePrivilegeObject hivePrivObject, boolean grantOption, IMetaStoreClient metastoreClient, + String userName) + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { + + // check if this user has grant privileges for this privileges on this + // object + + // map priv being granted to required privileges + RequiredPrivileges reqPrivs = getGrantRequiredPrivileges(hivePrivileges); + + // api for checking required privileges for a user + checkRequiredPrivileges(hivePrincipals, reqPrivs, hivePrivObject, metastoreClient, userName); + } + + private static void checkRequiredPrivileges(List hivePrincipals, + RequiredPrivileges reqPrivs, HivePrivilegeObject hivePrivObject, + IMetaStoreClient metastoreClient, String userName) + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { + + for (HivePrincipal hivePrincipal : hivePrincipals) { + checkRequiredPrivileges(hivePrincipal, reqPrivs, hivePrivObject, metastoreClient, userName); + } + } + + private static void checkRequiredPrivileges(HivePrincipal hivePrincipal, + RequiredPrivileges reqPrivileges, HivePrivilegeObject hivePrivObject, + IMetaStoreClient metastoreClient, String userName) + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { + + // keep track of the principals on which privileges have been checked for + // this object + + // get privileges for this user and its roles on this object + RequiredPrivileges availPrivs = SQLAuthorizationUtils.getPrivilegesFromMetaStore( + metastoreClient, userName, hivePrivObject); + + // check if required privileges is subset of available privileges + Collection missingPrivs = reqPrivileges.findMissingPrivs(availPrivs); + SQLAuthorizationUtils.assertNoMissingPrivilege(missingPrivs, new HivePrincipal(userName, + HivePrincipalType.USER), hivePrivObject); + } + + private static RequiredPrivileges getGrantRequiredPrivileges(List hivePrivileges) + throws HiveAuthzPluginException { + RequiredPrivileges reqPrivs = new RequiredPrivileges(); + for (HivePrivilege hivePriv : hivePrivileges) { + reqPrivs.addPrivilege(hivePriv.getName(), true /* grant priv required */); + } + return reqPrivs; + } + +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/Operation2Privilege.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/Operation2Privilege.java new file mode 100644 index 0000000..e448cba --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/Operation2Privilege.java @@ -0,0 +1,204 @@ +/** + * 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.hadoop.hive.ql.security.authorization.plugin.sqlstd; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType; + +/** + * Mapping of operation to its required input and output privileges + */ +public class Operation2Privilege { + + private static class InOutPrivs { + private final SQLPrivTypeGrant[] inputPrivs; + private final SQLPrivTypeGrant[] outputPrivs; + + InOutPrivs(SQLPrivTypeGrant[] inputPrivs, SQLPrivTypeGrant[] outputPrivs) { + this.inputPrivs = inputPrivs; + this.outputPrivs = outputPrivs; + } + + private SQLPrivTypeGrant[] getInputPrivs() { + return inputPrivs; + } + + private SQLPrivTypeGrant[] getOutputPrivs() { + return outputPrivs; + } + } + + private static Map op2Priv; + + private static SQLPrivTypeGrant[] OWNER_PRIV_AR = arr(SQLPrivTypeGrant.OWNER_PRIV); + private static SQLPrivTypeGrant[] SEL_NOGRANT_AR = arr(SQLPrivTypeGrant.SELECT_NOGRANT); + private static SQLPrivTypeGrant[] SEL_GRANT_AR = arr(SQLPrivTypeGrant.SELECT_WGRANT); + private static SQLPrivTypeGrant[] ADMIN_PRIV_AR = arr(SQLPrivTypeGrant.ADMIN_PRIV); + + static { + op2Priv = new HashMap(); + + op2Priv.put(HiveOperationType.EXPLAIN, new InOutPrivs(SEL_NOGRANT_AR, + SEL_NOGRANT_AR)); //?? + op2Priv.put(HiveOperationType.LOAD, new InOutPrivs(ADMIN_PRIV_AR, null)); + // select with grant for exporting contents + op2Priv.put(HiveOperationType.EXPORT, new InOutPrivs(SEL_GRANT_AR, null)); + + op2Priv.put(HiveOperationType.IMPORT, new InOutPrivs(ADMIN_PRIV_AR, null)); + + op2Priv.put(HiveOperationType.CREATEDATABASE, new InOutPrivs(ADMIN_PRIV_AR, null)); + op2Priv.put(HiveOperationType.DROPDATABASE, new InOutPrivs(ADMIN_PRIV_AR, null)); + //this should be database usage privilege once it is supported + op2Priv.put(HiveOperationType.SWITCHDATABASE, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.LOCKDB, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.UNLOCKDB, new InOutPrivs(null, null)); + + op2Priv.put(HiveOperationType.DROPTABLE, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.DESCTABLE, new InOutPrivs(SEL_NOGRANT_AR, null)); + op2Priv.put(HiveOperationType.DESCFUNCTION, new InOutPrivs(null, null)); + + //meta store check command - require admin priv + op2Priv.put(HiveOperationType.MSCK, new InOutPrivs(ADMIN_PRIV_AR, null)); + + //alter table commands require table ownership + op2Priv.put(HiveOperationType.ALTERTABLE_ADDCOLS, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_REPLACECOLS, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_RENAMECOL, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_RENAMEPART, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_RENAME, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_DROPPARTS, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_ADDPARTS, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_TOUCH, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_ARCHIVE, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_UNARCHIVE, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_PROPERTIES, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_SERIALIZER, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_PARTCOLTYPE, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERPARTITION_SERIALIZER, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_SERDEPROPERTIES, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERPARTITION_SERDEPROPERTIES, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_CLUSTER_SORT, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_BUCKETNUM, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERPARTITION_BUCKETNUM, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_PROTECTMODE, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERPARTITION_PROTECTMODE, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_FILEFORMAT, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERPARTITION_FILEFORMAT, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_LOCATION, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERPARTITION_LOCATION, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_MERGEFILES, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.ALTERPARTITION_MERGEFILES, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.ALTERTABLE_SKEWED, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.ALTERTBLPART_SKEWED_LOCATION, new InOutPrivs(null, null)); + + op2Priv.put(HiveOperationType.ANALYZE_TABLE, new InOutPrivs(arr(SQLPrivTypeGrant.SELECT_NOGRANT, SQLPrivTypeGrant.INSERT_NOGRANT), null)); + op2Priv.put(HiveOperationType.SHOWDATABASES, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.SHOWTABLES, new InOutPrivs(null, null)); + + op2Priv.put(HiveOperationType.SHOWCOLUMNS, new InOutPrivs(SEL_NOGRANT_AR, null)); + op2Priv.put(HiveOperationType.SHOW_TABLESTATUS, new InOutPrivs(SEL_NOGRANT_AR, null)); + op2Priv.put(HiveOperationType.SHOW_TBLPROPERTIES, new InOutPrivs(SEL_NOGRANT_AR, null)); + + //show create table is more sensitive information, includes table properties etc + // for now require select WITH GRANT + op2Priv.put(HiveOperationType.SHOW_CREATETABLE, new InOutPrivs(SEL_GRANT_AR, null)); + + op2Priv.put(HiveOperationType.SHOWFUNCTIONS, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.SHOWINDEXES, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.SHOWPARTITIONS, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.SHOWLOCKS, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.CREATEFUNCTION, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.DROPFUNCTION, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.CREATEMACRO, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.DROPMACRO, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.CREATEVIEW, new InOutPrivs(SEL_GRANT_AR, null)); + + // require view ownership + op2Priv.put(HiveOperationType.DROPVIEW, new InOutPrivs(OWNER_PRIV_AR, null)); + + //table ownership for create/drop/alter index + op2Priv.put(HiveOperationType.CREATEINDEX, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.DROPINDEX, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERINDEX_REBUILD, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERINDEX_PROPS, new InOutPrivs(OWNER_PRIV_AR, null)); + + // require view ownership for alter/drop view + op2Priv.put(HiveOperationType.ALTERVIEW_PROPERTIES, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.DROPVIEW_PROPERTIES, new InOutPrivs(OWNER_PRIV_AR, null)); + op2Priv.put(HiveOperationType.ALTERVIEW_RENAME, new InOutPrivs(OWNER_PRIV_AR, null)); + + op2Priv.put(HiveOperationType.LOCKTABLE, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.UNLOCKTABLE, new InOutPrivs(null, null)); + + // require db ownership + op2Priv.put(HiveOperationType.CREATETABLE, new InOutPrivs(OWNER_PRIV_AR, null)); + + // require table ownership + op2Priv.put(HiveOperationType.TRUNCATETABLE, new InOutPrivs(OWNER_PRIV_AR, null)); + + op2Priv.put(HiveOperationType.CREATETABLE_AS_SELECT, new InOutPrivs(OWNER_PRIV_AR, SEL_NOGRANT_AR)); + op2Priv.put(HiveOperationType.QUERY, new InOutPrivs(SEL_NOGRANT_AR, null)); + + op2Priv.put(HiveOperationType.ALTERDATABASE, new InOutPrivs(ADMIN_PRIV_AR, null)); + op2Priv.put(HiveOperationType.DESCDATABASE, new InOutPrivs(null, null)); + + // The following actions are authorized through SQLStdHiveAccessController, + // and it is not using this privilege mapping, but it might make sense to move it here + op2Priv.put(HiveOperationType.CREATEROLE, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.DROPROLE, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.GRANT_PRIVILEGE, new InOutPrivs(null, + null)); + op2Priv.put(HiveOperationType.REVOKE_PRIVILEGE, new InOutPrivs(null, + null)); + op2Priv.put(HiveOperationType.SHOW_GRANT, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.GRANT_ROLE, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.REVOKE_ROLE, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.SHOW_ROLES, new InOutPrivs(null, null)); + op2Priv.put(HiveOperationType.SHOW_ROLE_GRANT, new InOutPrivs(null, + null)); + + } + + /** + * Convenience method so that creation of this array in InOutPrivs constructor + * is not too verbose + * + * @param grantList + * @return grantList + */ + private static SQLPrivTypeGrant[] arr(SQLPrivTypeGrant... grantList) { + return grantList; + } + + public static SQLPrivTypeGrant[] getInputPrivs(HiveOperationType opType) { + return op2Priv.get(opType).getInputPrivs(); + } + + public static SQLPrivTypeGrant[] getOutputPrivs(HiveOperationType opType) { + return op2Priv.get(opType).getOutputPrivs(); + } + + // for unit tests + public static Set getOperationTypes() { + return op2Priv.keySet(); + } + +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/RequiredPrivileges.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/RequiredPrivileges.java new file mode 100644 index 0000000..ee06335 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/RequiredPrivileges.java @@ -0,0 +1,112 @@ +/** + * 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.hadoop.hive.ql.security.authorization.plugin.sqlstd; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException; + +/** + * Captures privilege sets, and can be used to compare required and available privileges + * to find missing privileges (if any). + */ +public class RequiredPrivileges { + + private final Set privilegeGrantSet = new HashSet(); + + public void addPrivilege(String priv, boolean withGrant) throws HiveAuthzPluginException { + SQLPrivTypeGrant privType = SQLPrivTypeGrant.getSQLPrivTypeGrant(priv, withGrant); + addPrivilege(privType); + privilegeGrantSet.add(privType); + if(withGrant){ + //as with grant also implies without grant privilege, add without privilege as well + addPrivilege(priv, false); + } + } + + public Set getRequiredPrivilegeSet() { + return privilegeGrantSet; + } + + /** + * Find the missing privileges in availPrivs + * + * @param availPrivs + * - available privileges + * @return missing privileges as RequiredPrivileges object + */ + public Collection findMissingPrivs(RequiredPrivileges availPrivs) { + MissingPrivilegeCapturer missingPrivCapturer = new MissingPrivilegeCapturer(); + for (SQLPrivTypeGrant requiredPriv : privilegeGrantSet) { + if (!availPrivs.privilegeGrantSet.contains(requiredPriv)) { + missingPrivCapturer.addMissingPrivilege(requiredPriv); + } + } + return missingPrivCapturer.getMissingPrivileges(); + } + + void addPrivilege(SQLPrivTypeGrant requiredPriv) { + privilegeGrantSet.add(requiredPriv); + } + + Set getPrivilegeWithGrants() { + return privilegeGrantSet; + } + + /** + * Capture privileges that are missing. If privilege "X with grant" and "X without grant" + * are reported missing, capture only "X with grant". This is useful for better error messages. + */ + class MissingPrivilegeCapturer { + + private final Map priv2privWithGrant = new HashMap(); + + void addMissingPrivilege(SQLPrivTypeGrant newPrivWGrant) { + SQLPrivTypeGrant matchingPrivWGrant = priv2privWithGrant.get(newPrivWGrant.getPrivType()); + if (matchingPrivWGrant != null) { + if (matchingPrivWGrant.isWithGrant() || !newPrivWGrant.isWithGrant()) { + // the existing entry already has grant, or new priv does not have + // grant + // no update needs to be done. + return; + } + } + // add the new entry + priv2privWithGrant.put(newPrivWGrant.getPrivType(), newPrivWGrant); + } + + Collection getMissingPrivileges() { + return priv2privWithGrant.values(); + } + + } + + public void addAll(SQLPrivTypeGrant[] inputPrivs) { + if (inputPrivs == null) { + return; + } + for (SQLPrivTypeGrant privType : inputPrivs) { + addPrivilege(privType); + } + } + +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/RevokePrivilegeAuthorizer.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/RevokePrivilegeAuthorizer.java new file mode 100644 index 0000000..3ca6fec --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/RevokePrivilegeAuthorizer.java @@ -0,0 +1,84 @@ +package org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.hadoop.hive.metastore.IMetaStoreClient; +import org.apache.hadoop.hive.metastore.api.HiveObjectPrivilege; +import org.apache.hadoop.hive.metastore.api.MetaException; +import org.apache.hadoop.hive.metastore.api.PrincipalType; +import org.apache.hadoop.hive.metastore.api.PrivilegeGrantInfo; +import org.apache.hadoop.hive.ql.security.authorization.AuthorizationUtils; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginDeniedException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilege; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject; +import org.apache.thrift.TException; + +public class RevokePrivilegeAuthorizer { + + public static List authorizeAndGetRevokePrivileges(List principals, + List hivePrivileges, HivePrivilegeObject hivePrivObject, boolean grantOption, + IMetaStoreClient mClient, String userName) + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { + + List matchingPrivs = new ArrayList(); + + StringBuilder errMsg = new StringBuilder(); + for (HivePrincipal principal : principals) { + + // get metastore/thrift privilege object for this principal and object, not looking at + // privileges obtained indirectly via roles + List msObjPrivs; + try { + msObjPrivs = mClient.list_privileges(principal.getName(), + AuthorizationUtils.getThriftPrincipalType(principal.getType()), + SQLAuthorizationUtils.getThriftHiveObjectRef(hivePrivObject)); + } catch (MetaException e) { + throw new HiveAuthzPluginException(e); + } catch (TException e) { + throw new HiveAuthzPluginException(e); + } + + // the resulting privileges need to be filtered on privilege type and + // username + + // create a Map to capture object privileges corresponding to privilege + // type + Map priv2privObj = new HashMap(); + + for (HiveObjectPrivilege msObjPriv : msObjPrivs) { + PrivilegeGrantInfo grantInfo = msObjPriv.getGrantInfo(); + // check if the grantor matches current user + if (grantInfo.getGrantor() != null && grantInfo.getGrantor().equals(userName) + && grantInfo.getGrantorType() == PrincipalType.USER) { + // add to the map + priv2privObj.put(grantInfo.getPrivilege(), msObjPriv); + } + // else skip this one + } + + // find the privileges that we are looking for + for (HivePrivilege hivePrivilege : hivePrivileges) { + HiveObjectPrivilege matchedPriv = priv2privObj.get(hivePrivilege.getName()); + if (matchedPriv != null) { + matchingPrivs.add(matchedPriv); + } else { + errMsg.append("Cannot find privilege ").append(hivePrivilege).append(" for ") + .append(principal).append(" on ").append(hivePrivObject).append(" granted by ") + .append(userName).append(System.getProperty("line.separator")); + } + } + + } + + if (errMsg.length() != 0) { + throw new HiveAuthzPluginDeniedException(errMsg.toString()); + } + return matchingPrivs; + } + +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLAuthorizationUtils.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLAuthorizationUtils.java new file mode 100644 index 0000000..e5ca309 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLAuthorizationUtils.java @@ -0,0 +1,279 @@ +/** + * 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.hadoop.hive.ql.security.authorization.plugin.sqlstd; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +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.NoSuchObjectException; +import org.apache.hadoop.hive.metastore.api.PrincipalPrivilegeSet; +import org.apache.hadoop.hive.metastore.api.PrivilegeBag; +import org.apache.hadoop.hive.metastore.api.PrivilegeGrantInfo; +import org.apache.hadoop.hive.metastore.api.Table; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.security.authorization.AuthorizationUtils; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginDeniedException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilege; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivilegeObjectType; +import org.apache.thrift.TException; + +public class SQLAuthorizationUtils { + + private static final String[] SUPPORTED_PRIVS = { "INSERT", "UPDATE", "DELETE", "SELECT" }; + private static final Set SUPPORTED_PRIVS_SET = new HashSet( + Arrays.asList(SUPPORTED_PRIVS)); + + /** + * Create thrift privileges bag + * + * @param hivePrincipals + * @param hivePrivileges + * @param hivePrivObject + * @param grantorPrincipal + * @param grantOption + * @return + * @throws HiveAuthzPluginException + */ + static PrivilegeBag getThriftPrivilegesBag(List hivePrincipals, + List hivePrivileges, HivePrivilegeObject hivePrivObject, + HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthzPluginException { + HiveObjectRef privObj = getThriftHiveObjectRef(hivePrivObject); + PrivilegeBag privBag = new PrivilegeBag(); + for (HivePrivilege privilege : hivePrivileges) { + if (privilege.getColumns() != null && privilege.getColumns().size() > 0) { + throw new HiveAuthzPluginException("Privileges on columns not supported currently" + + " in sql standard authorization mode"); + } + if (!SUPPORTED_PRIVS_SET.contains(privilege.getName().toUpperCase(Locale.US))) { + throw new HiveAuthzPluginException("Privilege: " + privilege.getName() + + " is not supported in sql standard authorization mode"); + } + PrivilegeGrantInfo grantInfo = getThriftPrivilegeGrantInfo(privilege, grantorPrincipal, + grantOption); + for (HivePrincipal principal : hivePrincipals) { + HiveObjectPrivilege objPriv = new HiveObjectPrivilege(privObj, principal.getName(), + AuthorizationUtils.getThriftPrincipalType(principal.getType()), grantInfo); + privBag.addToPrivileges(objPriv); + } + } + return privBag; + } + + static PrivilegeGrantInfo getThriftPrivilegeGrantInfo(HivePrivilege privilege, + HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthzPluginException { + try { + return AuthorizationUtils.getThriftPrivilegeGrantInfo(privilege, grantorPrincipal, + grantOption); + } catch (HiveException e) { + throw new HiveAuthzPluginException(e); + } + } + + /** + * Create a thrift privilege object from the plugin interface privilege object + * + * @param privObj + * @return + * @throws HiveAuthzPluginException + */ + static HiveObjectRef getThriftHiveObjectRef(HivePrivilegeObject privObj) + throws HiveAuthzPluginException { + try { + return AuthorizationUtils.getThriftHiveObjectRef(privObj); + } catch (HiveException e) { + throw new HiveAuthzPluginException(e); + } + } + + static HivePrivilegeObjectType getPluginObjType(HiveObjectType objectType) + throws HiveAuthzPluginException { + switch (objectType) { + case DATABASE: + return HivePrivilegeObjectType.DATABASE; + case TABLE: + return HivePrivilegeObjectType.TABLE; + case COLUMN: + case GLOBAL: + case PARTITION: + throw new HiveAuthzPluginException("Unsupported object type " + objectType); + default: + throw new AssertionError("Unexpected object type " + objectType); + } + } + + /** + * Check if the privileges are acceptable for SQL Standard authorization implementation + * @param hivePrivileges + * @throws HiveAuthzPluginException + */ + public static void validatePrivileges(List hivePrivileges) throws HiveAuthzPluginException { + for (HivePrivilege hivePrivilege : hivePrivileges) { + if (hivePrivilege.getColumns() != null && hivePrivilege.getColumns().size() != 0) { + throw new HiveAuthzPluginException( + "Privilege with columns are not currently supported with sql standard authorization:" + + hivePrivilege); + } + } + } + + /** + * Get the privileges this user(userName argument) has on the object + * (hivePrivObject argument) + * + * @param metastoreClient + * @param userName + * @param hivePrivObject + * @return + * @throws HiveAuthzPluginException + */ + static RequiredPrivileges getPrivilegesFromMetaStore(IMetaStoreClient metastoreClient, + String userName, HivePrivilegeObject hivePrivObject) throws HiveAuthzPluginException { + + // get privileges for this user and its role on this object + PrincipalPrivilegeSet thrifPrivs = null; + try { + thrifPrivs = metastoreClient.get_privilege_set( + AuthorizationUtils.getThriftHiveObjectRef(hivePrivObject), userName, null); + } catch (MetaException e) { + throwGetPrivErr(e, hivePrivObject, userName); + } catch (TException e) { + throwGetPrivErr(e, hivePrivObject, userName); + } catch (HiveException e) { + throwGetPrivErr(e, hivePrivObject, userName); + } + + // convert to RequiredPrivileges + RequiredPrivileges privs = getRequiredPrivsFromThrift(thrifPrivs); + + // add owner privilege if user is owner of the object + if (isOwner(metastoreClient, userName, hivePrivObject)) { + privs.addPrivilege(SQLPrivTypeGrant.OWNER_PRIV); + } + + return privs; + } + + /** + * Check if user is owner of the given object + * + * @param metastoreClient + * @param userName + * user + * @param hivePrivObject + * given object + * @return true if user is owner + * @throws HiveAuthzPluginException + */ + private static boolean isOwner(IMetaStoreClient metastoreClient, String userName, + HivePrivilegeObject hivePrivObject) throws HiveAuthzPluginException { + //for now, check only table + if(hivePrivObject.getType() == HivePrivilegeObjectType.TABLE){ + Table thriftTableObj = null; + try { + thriftTableObj = metastoreClient.getTable(hivePrivObject.getDbname(), hivePrivObject.getTableviewname()); + } catch (MetaException e) { + throwGetTableErr(e, hivePrivObject); + } catch (NoSuchObjectException e) { + throwGetTableErr(e, hivePrivObject); + } catch (TException e) { + throwGetTableErr(e, hivePrivObject); + } + return userName.equals(thriftTableObj.getOwner()); + } + return false; + } + + private static void throwGetTableErr(Exception e, HivePrivilegeObject hivePrivObject) + throws HiveAuthzPluginException { + String msg = "Error getting table object from metastore for" + hivePrivObject; + throw new HiveAuthzPluginException(msg, e); + } + + private static void throwGetPrivErr(Exception e, HivePrivilegeObject hivePrivObject, + String userName) throws HiveAuthzPluginException { + String msg = "Error getting privileges on " + hivePrivObject + " for " + userName; + throw new HiveAuthzPluginException(msg, e); + } + + private static RequiredPrivileges getRequiredPrivsFromThrift(PrincipalPrivilegeSet thrifPrivs) + throws HiveAuthzPluginException { + + RequiredPrivileges reqPrivs = new RequiredPrivileges(); + // add user privileges + Map> userPrivs = thrifPrivs.getUserPrivileges(); + if (userPrivs != null && userPrivs.size() != 1) { + throw new HiveAuthzPluginException("Invalid number of user privilege objects: " + + userPrivs.size()); + } + addRequiredPrivs(reqPrivs, userPrivs); + + // add role privileges + Map> rolePrivs = thrifPrivs.getRolePrivileges(); + addRequiredPrivs(reqPrivs, rolePrivs); + return reqPrivs; + } + + /** + * Add privileges to RequiredPrivileges object reqPrivs from thrift availPrivs + * object + * @param reqPrivs + * @param availPrivs + * @throws HiveAuthzPluginException + */ + private static void addRequiredPrivs(RequiredPrivileges reqPrivs, + Map> availPrivs) throws HiveAuthzPluginException { + if(availPrivs == null){ + return; + } + for (Map.Entry> userPriv : availPrivs.entrySet()) { + List userPrivGInfos = userPriv.getValue(); + for (PrivilegeGrantInfo userPrivGInfo : userPrivGInfos) { + reqPrivs.addPrivilege(userPrivGInfo.getPrivilege(), userPrivGInfo.isGrantOption()); + } + } + } + + public static void assertNoMissingPrivilege(Collection missingPrivs, + HivePrincipal hivePrincipal, HivePrivilegeObject hivePrivObject) + throws HiveAuthzPluginDeniedException { + if (missingPrivs.size() != 0) { + // there are some required privileges missing, create error message + StringBuilder errMsg = new StringBuilder("Permission denied. " + hivePrincipal + + " does not have following privileges on " + hivePrivObject + " :"); + for (SQLPrivTypeGrant reqPriv : missingPrivs) { + errMsg.append(reqPriv.toInfoString()).append(", "); + } + throw new HiveAuthzPluginDeniedException(errMsg.toString()); + } + } + + +} diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLPrivTypeGrant.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLPrivTypeGrant.java new file mode 100644 index 0000000..76f44b6 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLPrivTypeGrant.java @@ -0,0 +1,98 @@ +/** + * 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.hadoop.hive.ql.security.authorization.plugin.sqlstd; + +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException; + + +public enum SQLPrivTypeGrant { + SELECT_NOGRANT(SQLPrivilegeType.SELECT, false), + SELECT_WGRANT(SQLPrivilegeType.SELECT, true), + INSERT_NOGRANT(SQLPrivilegeType.INSERT, false), + INSERT_WGRANT(SQLPrivilegeType.INSERT, true), + UPDATE_NOGRANT(SQLPrivilegeType.UPDATE, false), + UPDATE_WGRANT(SQLPrivilegeType.UPDATE, true), + DELETE_NOGRANT(SQLPrivilegeType.DELETE, false), + DELETE_WGRANT(SQLPrivilegeType.DELETE, true), + OWNER_PRIV("Object ownership"), + ADMIN_PRIV("Admin privilege"); // This one can be used to deny permission for performing the operation + + private final SQLPrivilegeType privType; + private final boolean withGrant; + + private final String privDesc; + SQLPrivTypeGrant(SQLPrivilegeType privType, boolean isGrant){ + this.privType = privType; + this.withGrant = isGrant; + this.privDesc = privType.toString() + (withGrant ? " with grant" : ""); + } + + /** + * Constructor for privileges that are not the standard sql types, but are used by + * authorization rules + * @param privDesc + */ + SQLPrivTypeGrant(String privDesc){ + this.privDesc = privDesc; + this.privType = null; + this.withGrant = false; + } + + /** + * Find matching enum + * @param privType + * @param isGrant + * @return + */ + public static SQLPrivTypeGrant getSQLPrivTypeGrant( + SQLPrivilegeType privType, boolean isGrant) { + String typeName = privType.name() + (isGrant ? "_WGRANT" : "_NOGRANT"); + return SQLPrivTypeGrant.valueOf(typeName); + } + + /** + * Find matching enum + * + * @param privTypeStr + * privilege type string + * @param isGrant + * @return + * @throws HiveAuthzPluginException + */ + public static SQLPrivTypeGrant getSQLPrivTypeGrant(String privTypeStr, boolean isGrant) + throws HiveAuthzPluginException { + SQLPrivilegeType ptype = SQLPrivilegeType.getRequirePrivilege(privTypeStr); + return getSQLPrivTypeGrant(ptype, isGrant); + } + + public SQLPrivilegeType getPrivType() { + return privType; + } + + public boolean isWithGrant() { + return withGrant; + } + + /** + * @return String representation for use in error messages + */ + public String toInfoString(){ + return privDesc; + } + +}; diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLPrivilegeType.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLPrivilegeType.java new file mode 100644 index 0000000..faaa353 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLPrivilegeType.java @@ -0,0 +1,42 @@ +/** + * 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.hadoop.hive.ql.security.authorization.plugin.sqlstd; + +import java.util.Locale; + +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException; + +public enum SQLPrivilegeType { + //ALL privilege is expanded to these, so it is not needed here + SELECT, INSERT, UPDATE, DELETE; + + public static SQLPrivilegeType getRequirePrivilege(String priv) + throws HiveAuthzPluginException { + SQLPrivilegeType reqPriv; + try { + reqPriv = SQLPrivilegeType.valueOf(priv.toUpperCase(Locale.US)); + } catch (IllegalArgumentException e) { + throw new HiveAuthzPluginException("Invalid privilege " + priv, e); + } catch (NullPointerException e) { + throw new HiveAuthzPluginException("Null privilege obtained", e); + } + return reqPriv; + } + + +}; diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java index 5c5d0e5..d092cd4 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java @@ -35,9 +35,11 @@ import org.apache.hadoop.hive.metastore.api.PrivilegeGrantInfo; import org.apache.hadoop.hive.metastore.api.Role; import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider; import org.apache.hadoop.hive.ql.security.authorization.AuthorizationUtils; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAccessController; -import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizationPluginException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginDeniedException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveMetastoreClientFactory; import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal; import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilege; @@ -46,66 +48,97 @@ 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 + * Implements functionality of access control statements for sql standard based + * authorization */ @Private public class SQLStdHiveAccessController implements HiveAccessController { - private HiveMetastoreClientFactory metastoreClientFactory; - 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 HiveMetastoreClientFactory metastoreClientFactory; + private final HiveConf conf; + private final HiveAuthenticationProvider authenticator; + private static final String[] SUPPORTED_PRIVS = { "INSERT", "UPDATE", "DELETE", "SELECT" }; + private static final Set SUPPORTED_PRIVS_SET = new HashSet( + Arrays.asList(SUPPORTED_PRIVS)); - SQLStdHiveAccessController(HiveMetastoreClientFactory metastoreClientFactory, - HiveConf conf, String hiveCurrentUser){ + SQLStdHiveAccessController(HiveMetastoreClientFactory metastoreClientFactory, HiveConf conf, + HiveAuthenticationProvider authenticator) { this.metastoreClientFactory = metastoreClientFactory; + this.conf = conf; + this.authenticator = authenticator; } - @Override public void grantPrivileges(List hivePrincipals, List hivePrivileges, HivePrivilegeObject hivePrivObject, - HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthorizationPluginException { + HivePrincipal grantorPrincipal, boolean grantOption) + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { + + SQLAuthorizationUtils.validatePrivileges(hivePrivileges); + + // expand ALL privileges, if any + hivePrivileges = expandAllPrivileges(hivePrivileges); - PrivilegeBag privBag = - getThriftPrivilegesBag(hivePrincipals, hivePrivileges, hivePrivObject, grantorPrincipal, - grantOption); + IMetaStoreClient metastoreClient = metastoreClientFactory.getHiveMetastoreClient(); + // authorize the grant + GrantPrivilegeAuthorizer.authorize(hivePrincipals, hivePrivileges, hivePrivObject, grantOption, + metastoreClient, authenticator.getUserName()); + + // grant + PrivilegeBag privBag = 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); + throw new HiveAuthzPluginException("Error granting privileges", e); } } + private List expandAllPrivileges(List hivePrivileges) { + Set hivePrivSet = new HashSet(); + for (HivePrivilege hivePrivilege : hivePrivileges) { + if (hivePrivilege.getName().equals("ALL")) { + // expand to all supported privileges + for (SQLPrivilegeType privType : SQLPrivilegeType.values()) { + hivePrivSet.add(new HivePrivilege(privType.name(), hivePrivilege.getColumns())); + } + } else { + hivePrivSet.add(hivePrivilege); + } + } + return new ArrayList(hivePrivSet); + } + /** * Create thrift privileges bag + * * @param hivePrincipals * @param hivePrivileges * @param hivePrivObject * @param grantorPrincipal * @param grantOption * @return - * @throws HiveAuthorizationPluginException + * @throws HiveAuthzPluginException */ private PrivilegeBag getThriftPrivilegesBag(List hivePrincipals, List hivePrivileges, HivePrivilegeObject hivePrivObject, - HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthorizationPluginException { - HiveObjectRef privObj = getThriftHiveObjectRef(hivePrivObject); + HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthzPluginException { + HiveObjectRef privObj = SQLAuthorizationUtils.getThriftHiveObjectRef(hivePrivObject); PrivilegeBag privBag = new PrivilegeBag(); - for(HivePrivilege privilege : hivePrivileges){ - if(privilege.getColumns() != null && privilege.getColumns().size() > 0){ - throw new HiveAuthorizationPluginException("Privileges on columns not supported currently" + for (HivePrivilege privilege : hivePrivileges) { + if (privilege.getColumns() != null && privilege.getColumns().size() > 0) { + throw new HiveAuthzPluginException("Privileges on columns not supported currently" + " in sql standard authorization mode"); } - if(!SUPPORTED_PRIVS_SET.contains(privilege.getName().toUpperCase(Locale.US))){ - throw new HiveAuthorizationPluginException("Privilege: " + privilege.getName() + - " is not supported in sql standard authorization mode"); + if (!SUPPORTED_PRIVS_SET.contains(privilege.getName().toUpperCase(Locale.US))) { + throw new HiveAuthzPluginException("Privilege: " + privilege.getName() + + " is not supported in sql standard authorization mode"); } - PrivilegeGrantInfo grantInfo = getThriftPrivilegeGrantInfo(privilege, grantorPrincipal, grantOption); - for(HivePrincipal principal : hivePrincipals){ + PrivilegeGrantInfo grantInfo = getThriftPrivilegeGrantInfo(privilege, grantorPrincipal, + grantOption); + for (HivePrincipal principal : hivePrincipals) { HiveObjectPrivilege objPriv = new HiveObjectPrivilege(privObj, principal.getName(), AuthorizationUtils.getThriftPrincipalType(principal.getType()), grantInfo); privBag.addToPrivileges(objPriv); @@ -115,102 +148,95 @@ private PrivilegeBag getThriftPrivilegesBag(List hivePrincipals, } private PrivilegeGrantInfo getThriftPrivilegeGrantInfo(HivePrivilege privilege, - HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthorizationPluginException { + HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthzPluginException { try { - return AuthorizationUtils.getThriftPrivilegeGrantInfo(privilege, grantorPrincipal, grantOption); + return AuthorizationUtils.getThriftPrivilegeGrantInfo(privilege, grantorPrincipal, + grantOption); } catch (HiveException e) { - throw new HiveAuthorizationPluginException(e); - } - } - - /** - * Create a thrift privilege object from the plugin interface privilege object - * @param privObj - * @return - * @throws HiveAuthorizationPluginException - */ - private HiveObjectRef getThriftHiveObjectRef(HivePrivilegeObject privObj) - throws HiveAuthorizationPluginException { - try { - return AuthorizationUtils.getThriftHiveObjectRef(privObj); - } catch (HiveException e) { - throw new HiveAuthorizationPluginException(e); + throw new HiveAuthzPluginException(e); } } @Override public void revokePrivileges(List hivePrincipals, List hivePrivileges, HivePrivilegeObject hivePrivObject, - HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthorizationPluginException { + HivePrincipal grantorPrincipal, boolean grantOption) + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { + SQLAuthorizationUtils.validatePrivileges(hivePrivileges); + + IMetaStoreClient metastoreClient = metastoreClientFactory.getHiveMetastoreClient(); + // authorize the revoke, and get the set of privileges to be revoked + List revokePrivs = RevokePrivilegeAuthorizer + .authorizeAndGetRevokePrivileges(hivePrincipals, hivePrivileges, hivePrivObject, + grantOption, metastoreClient, authenticator.getUserName()); - PrivilegeBag privBag = - getThriftPrivilegesBag(hivePrincipals, hivePrivileges, hivePrivObject, grantorPrincipal, - grantOption); try { - metastoreClientFactory.getHiveMetastoreClient().revoke_privileges(privBag); + // unfortunately, the metastore api revokes all privileges that match on + // principal, privilege object type it does not filter on the grator + // username. + // So this will revoke privileges that are granted by other users.This is + // not SQL compliant behavior. Need to change/add a metastore api + // that has desired behavior. + metastoreClient.revoke_privileges(new PrivilegeBag(revokePrivs)); } catch (Exception e) { - throw new HiveAuthorizationPluginException("Error revoking privileges", e); + throw new HiveAuthzPluginException("Error revoking privileges", e); } } @Override public void createRole(String roleName, HivePrincipal adminGrantor) - throws HiveAuthorizationPluginException { + throws HiveAuthzPluginException { try { String grantorName = adminGrantor == null ? null : adminGrantor.getName(); - metastoreClientFactory.getHiveMetastoreClient() - .create_role(new Role(roleName, 0, grantorName)); + metastoreClientFactory.getHiveMetastoreClient().create_role( + new Role(roleName, 0, grantorName)); } catch (Exception e) { - throw new HiveAuthorizationPluginException("Error create role", e); + throw new HiveAuthzPluginException("Error create role", e); } } @Override - public void dropRole(String roleName) throws HiveAuthorizationPluginException { + public void dropRole(String roleName) throws HiveAuthzPluginException { try { metastoreClientFactory.getHiveMetastoreClient().drop_role(roleName); } catch (Exception e) { - throw new HiveAuthorizationPluginException("Error dropping role", e); + throw new HiveAuthzPluginException("Error dropping role", e); } } @Override - public List getRoles(HivePrincipal hivePrincipal) throws HiveAuthorizationPluginException { + public List getRoles(HivePrincipal hivePrincipal) throws HiveAuthzPluginException { try { List roles = metastoreClientFactory.getHiveMetastoreClient().list_roles( hivePrincipal.getName(), AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType())); - List roleNames = new ArrayList(roles.size()); + List hiveRoles = new ArrayList(roles.size()); for (Role role : roles){ - ; - roleNames.add(new HiveRole(role)); + hiveRoles.add(new HiveRole(role)); } - return roleNames; + return hiveRoles; } catch (Exception e) { - throw new HiveAuthorizationPluginException( - "Error listing roles for user" + hivePrincipal.getName(), e); + throw new HiveAuthzPluginException("Error listing roles for user" + + hivePrincipal.getName(), e); } } @Override public void grantRole(List hivePrincipals, List roleNames, - boolean grantOption, HivePrincipal grantorPrinc) throws HiveAuthorizationPluginException { - for(HivePrincipal hivePrincipal : hivePrincipals){ - for(String roleName : roleNames){ + boolean grantOption, HivePrincipal grantorPrinc) throws HiveAuthzPluginException { + for (HivePrincipal hivePrincipal : hivePrincipals) { + for (String roleName : roleNames) { try { IMetaStoreClient mClient = metastoreClientFactory.getHiveMetastoreClient(); - mClient.grant_role(roleName, - hivePrincipal.getName(), + mClient.grant_role(roleName, hivePrincipal.getName(), AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType()), grantorPrinc.getName(), - AuthorizationUtils.getThriftPrincipalType(grantorPrinc.getType()), - grantOption - ); + AuthorizationUtils.getThriftPrincipalType(grantorPrinc.getType()), grantOption); } catch (MetaException e) { - throw new HiveAuthorizationPluginException(e.getMessage(), e); + throw new HiveAuthzPluginException(e.getMessage(), e); } catch (Exception e) { - String msg = "Error granting roles for " + hivePrincipal.getName() + " to role " + String msg = "Error granting roles for " + hivePrincipal.getName() + " to role " + roleName + ": " + e.getMessage(); - throw new HiveAuthorizationPluginException(msg, e); + throw new HiveAuthzPluginException(msg, e); } } } @@ -218,77 +244,68 @@ public void grantRole(List hivePrincipals, List roleNames @Override public void revokeRole(List hivePrincipals, List roleNames, - boolean grantOption, HivePrincipal grantorPrinc) throws HiveAuthorizationPluginException { - if(grantOption){ - //removing grant privileges only is not supported in metastore api - throw new HiveAuthorizationPluginException("Revoking only the admin privileges on " + boolean grantOption, HivePrincipal grantorPrinc) throws HiveAuthzPluginException { + if (grantOption) { + // removing grant privileges only is not supported in metastore api + throw new HiveAuthzPluginException("Revoking only the admin privileges on " + "role is not currently supported"); } - for(HivePrincipal hivePrincipal : hivePrincipals){ - for(String roleName : roleNames){ + for (HivePrincipal hivePrincipal : hivePrincipals) { + for (String roleName : roleNames) { try { IMetaStoreClient mClient = metastoreClientFactory.getHiveMetastoreClient(); - mClient.revoke_role(roleName, - hivePrincipal.getName(), - AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType()) - ); - } catch (Exception e) { - String msg = "Error revoking roles for " + hivePrincipal.getName() + " to role " + roleName - + hivePrincipal.getName(); - throw new HiveAuthorizationPluginException(msg, e); + mClient.revoke_role(roleName, hivePrincipal.getName(), + AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType())); + } catch (Exception e) { + String msg = "Error revoking roles for " + hivePrincipal.getName() + " to role " + + roleName + hivePrincipal.getName(); + throw new HiveAuthzPluginException(msg, e); } } } } @Override - public List getAllRoles() throws HiveAuthorizationPluginException { + public List getAllRoles() throws HiveAuthzPluginException { try { return metastoreClientFactory.getHiveMetastoreClient().listRoleNames(); } catch (Exception e) { - throw new HiveAuthorizationPluginException("Error listing all roles", e); + throw new HiveAuthzPluginException("Error listing all roles", e); } } - @Override public List showPrivileges(HivePrincipal principal, HivePrivilegeObject privObj) - throws HiveAuthorizationPluginException { + throws HiveAuthzPluginException { try { List resPrivInfos = new ArrayList(); IMetaStoreClient mClient = metastoreClientFactory.getHiveMetastoreClient(); - //get metastore/thrift privilege object using metastore api - List msObjPrivs - = mClient.list_privileges(principal.getName(), - AuthorizationUtils.getThriftPrincipalType(principal.getType()), - getThriftHiveObjectRef(privObj)); + // get metastore/thrift privilege object using metastore api + List msObjPrivs = mClient.list_privileges(principal.getName(), + AuthorizationUtils.getThriftPrincipalType(principal.getType()), + SQLAuthorizationUtils.getThriftHiveObjectRef(privObj)); - //convert the metastore thrift objects to result objects - for(HiveObjectPrivilege msObjPriv : msObjPrivs){ - //result principal - HivePrincipal resPrincipal = - new HivePrincipal(msObjPriv.getPrincipalName(), - AuthorizationUtils.getHivePrincipalType(msObjPriv.getPrincipalType())); + // convert the metastore thrift objects to result objects + for (HiveObjectPrivilege msObjPriv : msObjPrivs) { + // result principal + HivePrincipal resPrincipal = new HivePrincipal(msObjPriv.getPrincipalName(), + AuthorizationUtils.getHivePrincipalType(msObjPriv.getPrincipalType())); - //result privilege + // result privilege PrivilegeGrantInfo msGrantInfo = msObjPriv.getGrantInfo(); HivePrivilege resPrivilege = new HivePrivilege(msGrantInfo.getPrivilege(), null); - //result object + // result object HiveObjectRef msObjRef = msObjPriv.getHiveObject(); HivePrivilegeObject resPrivObj = new HivePrivilegeObject( - getPluginObjType(msObjRef.getObjectType()), - msObjRef.getDbName(), - msObjRef.getObjectName() - ); - - //result grantor principal - HivePrincipal grantorPrincipal = - new HivePrincipal(msGrantInfo.getGrantor(), - AuthorizationUtils.getHivePrincipalType(msGrantInfo.getGrantorType())); + getPluginObjType(msObjRef.getObjectType()), msObjRef.getDbName(), + msObjRef.getObjectName()); + // result grantor principal + HivePrincipal grantorPrincipal = new HivePrincipal(msGrantInfo.getGrantor(), + AuthorizationUtils.getHivePrincipalType(msGrantInfo.getGrantorType())); HivePrivilegeInfo resPrivInfo = new HivePrivilegeInfo(resPrincipal, resPrivilege, resPrivObj, grantorPrincipal, msGrantInfo.isGrantOption()); @@ -296,17 +313,15 @@ public void revokeRole(List hivePrincipals, List roleName } return resPrivInfos; - } - catch (Exception e) { - throw new HiveAuthorizationPluginException("Error showing privileges", e); + } catch (Exception e) { + throw new HiveAuthzPluginException("Error showing privileges", e); } } - private HivePrivilegeObjectType getPluginObjType(HiveObjectType objectType) - throws HiveAuthorizationPluginException { - switch(objectType){ + throws HiveAuthzPluginException { + switch (objectType) { case DATABASE: return HivePrivilegeObjectType.DATABASE; case TABLE: @@ -314,7 +329,7 @@ private HivePrivilegeObjectType getPluginObjType(HiveObjectType objectType) case COLUMN: case GLOBAL: case PARTITION: - throw new HiveAuthorizationPluginException("Unsupported object type " + objectType); + throw new HiveAuthzPluginException("Unsupported object type " + objectType); default: throw new AssertionError("Unexpected object type " + objectType); } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAuthorizationValidator.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAuthorizationValidator.java index 3b2361c..8fc019e 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAuthorizationValidator.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAuthorizationValidator.java @@ -17,18 +17,66 @@ */ package org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd; +import java.util.Collection; import java.util.List; -import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizationPluginException; +import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.metastore.IMetaStoreClient; +import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizationValidator; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginDeniedException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveMetastoreClientFactory; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal.HivePrincipalType; import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject; public class SQLStdHiveAuthorizationValidator implements HiveAuthorizationValidator { + private final HiveMetastoreClientFactory metastoreClientFactory; + private final HiveConf conf; + private final HiveAuthenticationProvider authenticator; + + public SQLStdHiveAuthorizationValidator(HiveMetastoreClientFactory metastoreClientFactory, + HiveConf conf, HiveAuthenticationProvider authenticator) { + this.metastoreClientFactory = metastoreClientFactory; + this.conf = conf; + this.authenticator = authenticator; + } + @Override public void checkPrivileges(HiveOperationType hiveOpType, List inputHObjs, - List outputHObjs) throws HiveAuthorizationPluginException { + List outputHObjs) throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { + String userName = authenticator.getUserName(); + IMetaStoreClient metastoreClient = metastoreClientFactory.getHiveMetastoreClient(); + + // get privileges required on input and check + SQLPrivTypeGrant[] inputPrivs = Operation2Privilege.getInputPrivs(hiveOpType); + checkPrivileges(inputPrivs, inputHObjs, metastoreClient, userName); + + // get privileges required on input and check + SQLPrivTypeGrant[] outputPrivs = Operation2Privilege.getOutputPrivs(hiveOpType); + checkPrivileges(outputPrivs, outputHObjs, metastoreClient, userName); + + } + + private void checkPrivileges(SQLPrivTypeGrant[] reqPrivs, + List hObjs, IMetaStoreClient metastoreClient, String userName) + throws HiveAuthzPluginException, HiveAuthzPluginDeniedException { + RequiredPrivileges requiredInpPrivs = new RequiredPrivileges(); + requiredInpPrivs.addAll(reqPrivs); + + // check if this user has these privileges on the objects + for (HivePrivilegeObject hObj : hObjs) { + // get the privileges that this user has on the object + RequiredPrivileges availPrivs = SQLAuthorizationUtils.getPrivilegesFromMetaStore( + metastoreClient, userName, hObj); + Collection missingPriv = requiredInpPrivs + .findMissingPrivs(availPrivs); + SQLAuthorizationUtils.assertNoMissingPrivilege(missingPriv, new HivePrincipal(userName, + HivePrincipalType.USER), hObj); + } } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAuthorizerFactory.java b/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAuthorizerFactory.java index 7688bbf..51e9ece 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAuthorizerFactory.java +++ b/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.HiveAuthenticationProvider; 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,10 +29,10 @@ public class SQLStdHiveAuthorizerFactory implements HiveAuthorizerFactory{ @Override public HiveAuthorizer createHiveAuthorizer(HiveMetastoreClientFactory metastoreClientFactory, - HiveConf conf, String hiveCurrentUser) { + HiveConf conf, HiveAuthenticationProvider authenticator) { return new HiveAuthorizerImpl( - new SQLStdHiveAccessController(metastoreClientFactory, conf, hiveCurrentUser), - new SQLStdHiveAuthorizationValidator() + new SQLStdHiveAccessController(metastoreClientFactory, conf, authenticator), + new SQLStdHiveAuthorizationValidator(metastoreClientFactory, conf, authenticator) ); } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java b/ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java index 64a8a60..536c8a1 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java @@ -54,6 +54,8 @@ import org.apache.hadoop.hive.ql.metadata.HiveUtils; import org.apache.hadoop.hive.ql.plan.HiveOperation; import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider; +import org.apache.hadoop.hive.ql.security.SessionStateAuthenticator; +import org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator; import org.apache.hadoop.hive.ql.security.authorization.HiveAuthorizationProvider; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizer; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizerFactory; @@ -340,29 +342,42 @@ public static SessionState start(SessionState startSs) { */ private void setupAuth() { - if(authenticator != null){ - //auth has been initialized + if (authenticator != null) { + // auth has been initialized return; } try { - authenticator = HiveUtils.getAuthenticator( - getConf(),HiveConf.ConfVars.HIVE_AUTHENTICATOR_MANAGER); - authorizer = HiveUtils.getAuthorizeProviderManager( - getConf(), HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER, - authenticator, true); - - if(authorizer == null){ - //if it was null, the new authorization plugin must be specified in config - HiveAuthorizerFactory authorizerFactory = - HiveUtils.getAuthorizerFactory(getConf(), HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER); - String authUser = userName == null ? authenticator.getUserName() : userName; - authorizerV2 = authorizerFactory.createHiveAuthorizer(new HiveMetastoreClientFactoryImpl(), - getConf(), authUser); + authenticator = HiveUtils.getAuthenticator(getConf(), + HiveConf.ConfVars.HIVE_AUTHENTICATOR_MANAGER); + + if (userName != null) { + // if username is set through the session, use an authenticator that + // just returns the sessionstate user + authenticator = new SessionStateUserAuthenticator(this); + } + + if(authenticator instanceof SessionStateAuthenticator){ + ((SessionStateAuthenticator)authenticator).setSessionState(this); } - else{ - createTableGrants = CreateTableAutomaticGrant.create(getConf()); + + authorizer = HiveUtils.getAuthorizeProviderManager(getConf(), + HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER, authenticator, true); + + if (authorizer == null) { + // if it was null, the new authorization plugin must be specified in + // config + HiveAuthorizerFactory authorizerFactory = HiveUtils.getAuthorizerFactory(getConf(), + HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER); + + authorizerV2 = authorizerFactory.createHiveAuthorizer(new HiveMetastoreClientFactoryImpl(), + getConf(), authenticator); + // grant all privileges for table to its owner + getConf().setVar(ConfVars.HIVE_AUTHORIZATION_TABLE_OWNER_GRANTS, "insert,select,update,delete"); } + + createTableGrants = CreateTableAutomaticGrant.create(getConf()); + } catch (HiveException e) { throw new RuntimeException(e); } @@ -821,6 +836,7 @@ public void setAuthenticator(HiveAuthenticationProvider authenticator) { } public CreateTableAutomaticGrant getCreateTableGrants() { + setupAuth(); return createTableGrants; } @@ -947,4 +963,9 @@ public TezSessionState getTezSession() { public void setTezSession(TezSessionState session) { this.tezSessionState = session; } + + public String getUserName() { + return userName; + } + } diff --git a/ql/src/test/org/apache/hadoop/hive/ql/parse/authorization/TestSessionUserName.java b/ql/src/test/org/apache/hadoop/hive/ql/parse/authorization/TestSessionUserName.java index 86d5f46..4c5b2bf 100644 --- a/ql/src/test/org/apache/hadoop/hive/ql/parse/authorization/TestSessionUserName.java +++ b/ql/src/test/org/apache/hadoop/hive/ql/parse/authorization/TestSessionUserName.java @@ -22,6 +22,7 @@ import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.api.MetaException; import org.apache.hadoop.hive.ql.metadata.Hive; +import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider; 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; @@ -106,8 +107,8 @@ private HiveConf getAuthV2HiveConf() { @Override public HiveAuthorizer createHiveAuthorizer(HiveMetastoreClientFactory metastoreClientFactory, - HiveConf conf, String hiveCurrentUser) { - username = hiveCurrentUser; + HiveConf conf, HiveAuthenticationProvider authenticator) { + username = authenticator.getUserName(); return new HiveAuthorizerImpl(null, null); } } diff --git a/ql/src/test/org/apache/hadoop/hive/ql/parse/authorization/plugin/sqlstd/TestOperation2Privilege.java b/ql/src/test/org/apache/hadoop/hive/ql/parse/authorization/plugin/sqlstd/TestOperation2Privilege.java new file mode 100644 index 0000000..31c4443 --- /dev/null +++ b/ql/src/test/org/apache/hadoop/hive/ql/parse/authorization/plugin/sqlstd/TestOperation2Privilege.java @@ -0,0 +1,51 @@ +/** + * 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.hadoop.hive.ql.parse.authorization.plugin.sqlstd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.util.Set; + +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType; +import org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.Operation2Privilege; +import org.junit.Test; + +/** + * Test HiveOperationType + */ +public class TestOperation2Privilege { + + /** + * test that all enums in {@link HiveOperationType} match one map entry in + * Operation2Privilege + */ + @Test + public void checkHiveOperationTypeMatch() { + Set operationMapKeys = Operation2Privilege.getOperationTypes(); + for (HiveOperationType operationType : HiveOperationType.values()) { + if (!operationMapKeys.contains(operationType)) { + fail("Unable to find corresponding entry in Operation2Privilege map for HiveOperationType " + + operationType); + } + } + assertEquals("Check if Operation2Privilege, HiveOperationType have same number of instances", + operationMapKeys.size(), HiveOperationType.values().length); + } + +} diff --git a/ql/src/test/queries/clientnegative/authorization_grant_table_allpriv.q b/ql/src/test/queries/clientnegative/authorization_grant_table_allpriv.q new file mode 100644 index 0000000..17d2b46 --- /dev/null +++ b/ql/src/test/queries/clientnegative/authorization_grant_table_allpriv.q @@ -0,0 +1,14 @@ +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=user1; +-- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_allf(i int); + +-- grant insert to user2 WITH grant option +GRANT INSERT ON table_priv_allf TO USER user2 with grant option; + +set user.name=user2; +-- try grant all to user3, without having all privileges +GRANT ALL ON table_priv_allf TO USER user3; diff --git a/ql/src/test/queries/clientnegative/authorization_grant_table_fail1.q b/ql/src/test/queries/clientnegative/authorization_grant_table_fail1.q new file mode 100644 index 0000000..140f5b0 --- /dev/null +++ b/ql/src/test/queries/clientnegative/authorization_grant_table_fail1.q @@ -0,0 +1,11 @@ +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=user1; +-- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_gfail1(i int); + +set user.name=user2; +-- try grant insert to user3 as user2 +GRANT INSERT ON table_priv_gfail1 TO USER user3; diff --git a/ql/src/test/queries/clientnegative/authorization_grant_table_fail_nogrant.q b/ql/src/test/queries/clientnegative/authorization_grant_table_fail_nogrant.q new file mode 100644 index 0000000..aff9b9f --- /dev/null +++ b/ql/src/test/queries/clientnegative/authorization_grant_table_fail_nogrant.q @@ -0,0 +1,14 @@ +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=user1; +-- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_gfail1(i int); + +-- grant insert to user2 WITHOUT grant option +GRANT INSERT ON table_priv_gfail1 TO USER user2; + +set user.name=user2; +-- try grant insert to user3 +GRANT INSERT ON table_priv_gfail1 TO USER user3; diff --git a/ql/src/test/queries/clientnegative/authorization_revoke_table_fail1.q b/ql/src/test/queries/clientnegative/authorization_revoke_table_fail1.q new file mode 100644 index 0000000..f2e3eab --- /dev/null +++ b/ql/src/test/queries/clientnegative/authorization_revoke_table_fail1.q @@ -0,0 +1,14 @@ +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=user1; +-- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_rfail1(i int); + +-- grant insert to user2 +GRANT INSERT ON table_priv_rfail1 TO USER user2; + +set user.name=user3; +-- try dropping the privilege as user3 +REVOKE INSERT ON TABLE table_priv_rfail1 FROM USER user2; diff --git a/ql/src/test/queries/clientnegative/authorization_revoke_table_fail2.q b/ql/src/test/queries/clientnegative/authorization_revoke_table_fail2.q new file mode 100644 index 0000000..edb5b65 --- /dev/null +++ b/ql/src/test/queries/clientnegative/authorization_revoke_table_fail2.q @@ -0,0 +1,18 @@ +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=user1; +-- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_rfai2(i int); + +-- grant insert to user2 +GRANT INSERT ON table_priv_rfai2 TO USER user2; +GRANT SELECT ON table_priv_rfai2 TO USER user3 WITH GRANT OPTION; + +set user.name=user3; +-- grant select as user3 to user 2 +GRANT SELECT ON table_priv_rfai2 TO USER user2; + +-- try dropping the privilege as user3 +REVOKE INSERT ON TABLE table_priv_rfai2 FROM USER user2; diff --git a/ql/src/test/queries/clientpositive/authorization_1_sql_std.q b/ql/src/test/queries/clientpositive/authorization_1_sql_std.q index 65cfeb3..44d73fc 100644 --- a/ql/src/test/queries/clientpositive/authorization_1_sql_std.q +++ b/ql/src/test/queries/clientpositive/authorization_1_sql_std.q @@ -6,18 +6,18 @@ set hive.security.authorization.enabled=true; --table grant to user -grant select on table src_autho_test to user hive_test_user; +grant select on table src_autho_test to user user_sauth; -show grant user hive_test_user on table src_autho_test; +show grant user user_sauth on table src_autho_test; -revoke select on table src_autho_test from user hive_test_user; -show grant user hive_test_user on table src_autho_test; +revoke select on table src_autho_test from user user_sauth; +show grant user user_sauth on table src_autho_test; --role create role src_role; -grant role src_role to user hive_test_user; -show role grant user hive_test_user; +grant role src_role to user user_sauth; +show role grant user user_sauth; --table grant to role diff --git a/ql/src/test/queries/clientpositive/authorization_create_table_owner_privs.q b/ql/src/test/queries/clientpositive/authorization_create_table_owner_privs.q new file mode 100644 index 0000000..4dde2b0 --- /dev/null +++ b/ql/src/test/queries/clientpositive/authorization_create_table_owner_privs.q @@ -0,0 +1,10 @@ +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=user1; + +create table create_table_creator_priv_test(i int); + +-- all privileges should have been set for user + +show grant user user1 on table create_table_creator_priv_test; diff --git a/ql/src/test/queries/clientpositive/authorization_grant_table_priv.q b/ql/src/test/queries/clientpositive/authorization_grant_table_priv.q new file mode 100644 index 0000000..c18f5b4 --- /dev/null +++ b/ql/src/test/queries/clientpositive/authorization_grant_table_priv.q @@ -0,0 +1,43 @@ +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=user1; +-- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv1(i int); + +-- all privileges should have been set for user + +-- grant insert privilege to another user +GRANT INSERT ON table_priv1 TO USER user2; +SHOW GRANT USER user2 ON TABLE table_priv1; + +-- grant select privilege to another user with grant +GRANT SELECT ON table_priv1 TO USER user2 with grant option; +SHOW GRANT USER user2 ON TABLE table_priv1; + +set user.name=user2; +-- change to other user - user2 +-- grant permissions to another user as user2 +GRANT SELECT ON table_priv1 TO USER user3 with grant option; +SHOW GRANT USER user3 ON TABLE table_priv1; + +set user.name=user3; +-- change to other user - user3 +-- grant permissions to another user as user3 +GRANT SELECT ON table_priv1 TO USER user4 with grant option; +SHOW GRANT USER user4 ON TABLE table_priv1; + +set user.name=user1; +-- switched back to table owner + +-- grant all with grant to user22 +GRANT ALL ON table_priv1 TO USER user22 with grant option; +SHOW GRANT USER user22 ON TABLE table_priv1; + +set user.name=user22; + +-- grant all without grant to user33 +GRANT ALL ON table_priv1 TO USER user33 with grant option; +SHOW GRANT USER user33 ON TABLE table_priv1; + diff --git a/ql/src/test/queries/clientpositive/authorization_revoke_table_priv.q b/ql/src/test/queries/clientpositive/authorization_revoke_table_priv.q new file mode 100644 index 0000000..18eec8d --- /dev/null +++ b/ql/src/test/queries/clientpositive/authorization_revoke_table_priv.q @@ -0,0 +1,50 @@ +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=user1; +-- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_rev(i int); + +-- grant insert privilege to user2 +GRANT INSERT ON table_priv_rev TO USER user2; +SHOW GRANT USER user2 ON TABLE table_priv_rev; + +-- revoke insert privilege from user2 +REVOKE INSERT ON TABLE table_priv_rev FROM USER user2; +SHOW GRANT USER user2 ON TABLE table_priv_rev; + +-- grant all privileges one at a time -- +-- grant insert privilege to user2 +GRANT INSERT ON table_priv_rev TO USER user2; +SHOW GRANT USER user2 ON TABLE table_priv_rev; + +-- grant select privilege to user2, with grant option +GRANT SELECT ON table_priv_rev TO USER user2 WITH GRANT OPTION; +SHOW GRANT USER user2 ON TABLE table_priv_rev; + +-- grant update privilege to user2 +GRANT UPDATE ON table_priv_rev TO USER user2; +SHOW GRANT USER user2 ON TABLE table_priv_rev; + +-- grant delete privilege to user2 +GRANT DELETE ON table_priv_rev TO USER user2; +SHOW GRANT USER user2 ON TABLE table_priv_rev; + +-- start revoking -- +-- revoke update privilege from user2 +REVOKE UPDATE ON TABLE table_priv_rev FROM USER user2; +SHOW GRANT USER user2 ON TABLE table_priv_rev; + +-- revoke DELETE privilege from user2 +REVOKE DELETE ON TABLE table_priv_rev FROM USER user2; +SHOW GRANT USER user2 ON TABLE table_priv_rev; + +-- revoke insert privilege from user2 +REVOKE INSERT ON TABLE table_priv_rev FROM USER user2; +SHOW GRANT USER user2 ON TABLE table_priv_rev; + +-- revoke select privilege from user2 +REVOKE SELECT ON TABLE table_priv_rev FROM USER user2; +SHOW GRANT USER user2 ON TABLE table_priv_rev; + diff --git a/ql/src/test/results/clientnegative/authorization_grant_table_allpriv.q.out b/ql/src/test/results/clientnegative/authorization_grant_table_allpriv.q.out new file mode 100644 index 0000000..11d42fc --- /dev/null +++ b/ql/src/test/results/clientnegative/authorization_grant_table_allpriv.q.out @@ -0,0 +1,22 @@ +PREHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_allf(i int) +PREHOOK: type: CREATETABLE +POSTHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_allf(i int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: default@table_priv_allf +PREHOOK: query: -- grant insert to user2 WITH grant option +GRANT INSERT ON table_priv_allf TO USER user2 with grant option +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_allf +POSTHOOK: query: -- grant insert to user2 WITH grant option +GRANT INSERT ON table_priv_allf TO USER user2 with grant option +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv_allf +PREHOOK: query: -- try grant all to user3, without having all privileges +GRANT ALL ON table_priv_allf TO USER user3 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_allf +FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Permission denied. Principal [name=user2, type=USER] does not have following privileges on Hive Object [type=TABLE, dbname=default, table/viewname=table_priv_allf] :DELETE with grant, UPDATE with grant, SELECT with grant, diff --git a/ql/src/test/results/clientnegative/authorization_grant_table_fail1.q.out b/ql/src/test/results/clientnegative/authorization_grant_table_fail1.q.out new file mode 100644 index 0000000..3163ae1 --- /dev/null +++ b/ql/src/test/results/clientnegative/authorization_grant_table_fail1.q.out @@ -0,0 +1,14 @@ +PREHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_gfail1(i int) +PREHOOK: type: CREATETABLE +POSTHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_gfail1(i int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: default@table_priv_gfail1 +PREHOOK: query: -- try grant insert to user3 as user2 +GRANT INSERT ON table_priv_gfail1 TO USER user3 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_gfail1 +FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Permission denied. Principal [name=user2, type=USER] does not have following privileges on Hive Object [type=TABLE, dbname=default, table/viewname=table_priv_gfail1] :INSERT with grant, diff --git a/ql/src/test/results/clientnegative/authorization_grant_table_fail_nogrant.q.out b/ql/src/test/results/clientnegative/authorization_grant_table_fail_nogrant.q.out new file mode 100644 index 0000000..c283210 --- /dev/null +++ b/ql/src/test/results/clientnegative/authorization_grant_table_fail_nogrant.q.out @@ -0,0 +1,22 @@ +PREHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_gfail1(i int) +PREHOOK: type: CREATETABLE +POSTHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_gfail1(i int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: default@table_priv_gfail1 +PREHOOK: query: -- grant insert to user2 WITHOUT grant option +GRANT INSERT ON table_priv_gfail1 TO USER user2 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_gfail1 +POSTHOOK: query: -- grant insert to user2 WITHOUT grant option +GRANT INSERT ON table_priv_gfail1 TO USER user2 +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv_gfail1 +PREHOOK: query: -- try grant insert to user3 +GRANT INSERT ON table_priv_gfail1 TO USER user3 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_gfail1 +FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Permission denied. Principal [name=user2, type=USER] does not have following privileges on Hive Object [type=TABLE, dbname=default, table/viewname=table_priv_gfail1] :INSERT with grant, diff --git a/ql/src/test/results/clientnegative/authorization_invalid_priv_v2.q.out b/ql/src/test/results/clientnegative/authorization_invalid_priv_v2.q.out index 6adc333..a3b6284 100644 --- a/ql/src/test/results/clientnegative/authorization_invalid_priv_v2.q.out +++ b/ql/src/test/results/clientnegative/authorization_invalid_priv_v2.q.out @@ -6,4 +6,4 @@ POSTHOOK: Output: default@authorization_invalid_v2 PREHOOK: query: grant index on table authorization_invalid_v2 to user hive_test_user PREHOOK: type: GRANT_PRIVILEGE PREHOOK: Output: default@authorization_invalid_v2 -FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Privilege: Index is not supported in sql standard authorization mode +FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Invalid privilege INDEX diff --git a/ql/src/test/results/clientnegative/authorization_revoke_table_fail1.q.out b/ql/src/test/results/clientnegative/authorization_revoke_table_fail1.q.out new file mode 100644 index 0000000..696f29b --- /dev/null +++ b/ql/src/test/results/clientnegative/authorization_revoke_table_fail1.q.out @@ -0,0 +1,23 @@ +PREHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_rfail1(i int) +PREHOOK: type: CREATETABLE +POSTHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_rfail1(i int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: default@table_priv_rfail1 +PREHOOK: query: -- grant insert to user2 +GRANT INSERT ON table_priv_rfail1 TO USER user2 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_rfail1 +POSTHOOK: query: -- grant insert to user2 +GRANT INSERT ON table_priv_rfail1 TO USER user2 +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv_rfail1 +PREHOOK: query: -- try dropping the privilege as user3 +REVOKE INSERT ON TABLE table_priv_rfail1 FROM USER user2 +PREHOOK: type: REVOKE_PRIVILEGE +PREHOOK: Output: default@table_priv_rfail1 +FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Cannot find privilege Privilege [name=INSERT, columns=null] for Principal [name=user2, type=USER] on Hive Object [type=TABLE, dbname=default, table/viewname=table_priv_rfail1] granted by user3 + diff --git a/ql/src/test/results/clientnegative/authorization_revoke_table_fail2.q.out b/ql/src/test/results/clientnegative/authorization_revoke_table_fail2.q.out new file mode 100644 index 0000000..5fbfd17 --- /dev/null +++ b/ql/src/test/results/clientnegative/authorization_revoke_table_fail2.q.out @@ -0,0 +1,37 @@ +PREHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_rfai2(i int) +PREHOOK: type: CREATETABLE +POSTHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_rfai2(i int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: default@table_priv_rfai2 +PREHOOK: query: -- grant insert to user2 +GRANT INSERT ON table_priv_rfai2 TO USER user2 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_rfai2 +POSTHOOK: query: -- grant insert to user2 +GRANT INSERT ON table_priv_rfai2 TO USER user2 +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv_rfai2 +PREHOOK: query: GRANT SELECT ON table_priv_rfai2 TO USER user3 WITH GRANT OPTION +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_rfai2 +POSTHOOK: query: GRANT SELECT ON table_priv_rfai2 TO USER user3 WITH GRANT OPTION +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv_rfai2 +PREHOOK: query: -- grant select as user3 to user 2 +GRANT SELECT ON table_priv_rfai2 TO USER user2 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_rfai2 +POSTHOOK: query: -- grant select as user3 to user 2 +GRANT SELECT ON table_priv_rfai2 TO USER user2 +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv_rfai2 +PREHOOK: query: -- try dropping the privilege as user3 +REVOKE INSERT ON TABLE table_priv_rfai2 FROM USER user2 +PREHOOK: type: REVOKE_PRIVILEGE +PREHOOK: Output: default@table_priv_rfai2 +FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Cannot find privilege Privilege [name=INSERT, columns=null] for Principal [name=user2, type=USER] on Hive Object [type=TABLE, dbname=default, table/viewname=table_priv_rfai2] granted by user3 + diff --git a/ql/src/test/results/clientnegative/authorization_role_cycles1.q.out b/ql/src/test/results/clientnegative/authorization_role_cycles1.q.out index 9d2c3be..da9014d 100644 --- a/ql/src/test/results/clientnegative/authorization_role_cycles1.q.out +++ b/ql/src/test/results/clientnegative/authorization_role_cycles1.q.out @@ -15,4 +15,4 @@ POSTHOOK: type: GRANT_ROLE PREHOOK: query: -- this will create a cycle grant role role2 to role role1 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.HiveAuthorizationPluginException: Cannot grant role role1 to role2 as role2 already belongs to the role role1. (no cycles allowed) +FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException: Cannot grant role role1 to role2 as role2 already belongs to the role role1. (no cycles allowed) diff --git a/ql/src/test/results/clientnegative/authorization_role_cycles2.q.out b/ql/src/test/results/clientnegative/authorization_role_cycles2.q.out index be9a491..f54b88e 100644 --- a/ql/src/test/results/clientnegative/authorization_role_cycles2.q.out +++ b/ql/src/test/results/clientnegative/authorization_role_cycles2.q.out @@ -41,4 +41,4 @@ POSTHOOK: type: GRANT_ROLE PREHOOK: query: -- this will create a cycle in middle of the hierarchy grant role role2 to role role4 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.HiveAuthorizationPluginException: Cannot grant role role4 to role2 as role2 already belongs to the role role4. (no cycles allowed) +FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException: Cannot grant role role4 to role2 as role2 already belongs to the role role4. (no cycles allowed) diff --git a/ql/src/test/results/clientpositive/authorization_1_sql_std.q.out b/ql/src/test/results/clientpositive/authorization_1_sql_std.q.out index 0874b92..8184708 100644 --- a/ql/src/test/results/clientpositive/authorization_1_sql_std.q.out +++ b/ql/src/test/results/clientpositive/authorization_1_sql_std.q.out @@ -5,28 +5,28 @@ POSTHOOK: type: CREATETABLE POSTHOOK: Output: default@src_autho_test PREHOOK: query: --table grant to user -grant select on table src_autho_test to user hive_test_user +grant select on table src_autho_test to user user_sauth PREHOOK: type: GRANT_PRIVILEGE PREHOOK: Output: default@src_autho_test POSTHOOK: query: --table grant to user -grant select on table src_autho_test to user hive_test_user +grant select on table src_autho_test to user user_sauth POSTHOOK: type: GRANT_PRIVILEGE POSTHOOK: Output: default@src_autho_test -PREHOOK: query: show grant user hive_test_user on table src_autho_test +PREHOOK: query: show grant user user_sauth on table src_autho_test PREHOOK: type: SHOW_GRANT -POSTHOOK: query: show grant user hive_test_user on table src_autho_test +POSTHOOK: query: show grant user user_sauth on table src_autho_test POSTHOOK: type: SHOW_GRANT -default src_autho_test hive_test_user USER Select false -1 hive_test_user -PREHOOK: query: revoke select on table src_autho_test from user hive_test_user +default src_autho_test user_sauth USER SELECT false -1 hive_test_user +PREHOOK: query: revoke select on table src_autho_test from user user_sauth PREHOOK: type: REVOKE_PRIVILEGE PREHOOK: Output: default@src_autho_test -POSTHOOK: query: revoke select on table src_autho_test from user hive_test_user +POSTHOOK: query: revoke select on table src_autho_test from user user_sauth POSTHOOK: type: REVOKE_PRIVILEGE POSTHOOK: Output: default@src_autho_test -PREHOOK: query: show grant user hive_test_user on table src_autho_test +PREHOOK: query: show grant user user_sauth on table src_autho_test PREHOOK: type: SHOW_GRANT -POSTHOOK: query: show grant user hive_test_user on table src_autho_test +POSTHOOK: query: show grant user user_sauth on table src_autho_test POSTHOOK: type: SHOW_GRANT PREHOOK: query: --role create role src_role @@ -34,15 +34,15 @@ PREHOOK: type: CREATEROLE POSTHOOK: query: --role create role src_role POSTHOOK: type: CREATEROLE -PREHOOK: query: grant role src_role to user hive_test_user +PREHOOK: query: grant role src_role to user user_sauth PREHOOK: type: GRANT_ROLE -POSTHOOK: query: grant role src_role to user hive_test_user +POSTHOOK: query: grant role src_role to user user_sauth POSTHOOK: type: GRANT_ROLE -PREHOOK: query: show role grant user hive_test_user +PREHOOK: query: show role grant user user_sauth PREHOOK: type: SHOW_ROLE_GRANT -POSTHOOK: query: show role grant user hive_test_user +POSTHOOK: query: show role grant user user_sauth POSTHOOK: type: SHOW_ROLE_GRANT -src_role -1 hive_test_user USER false -1 hive_test_user +src_role -1 user_sauth USER false -1 hive_test_user PUBLIC -1 false -1 PREHOOK: query: --table grant to role @@ -58,7 +58,7 @@ PREHOOK: query: show grant role src_role on table src_autho_test PREHOOK: type: SHOW_GRANT POSTHOOK: query: show grant role src_role on table src_autho_test POSTHOOK: type: SHOW_GRANT -default src_autho_test src_role ROLE Select false -1 hive_test_user +default src_autho_test src_role ROLE SELECT false -1 hive_test_user PREHOOK: query: revoke select on table src_autho_test from role src_role PREHOOK: type: REVOKE_PRIVILEGE PREHOOK: Output: default@src_autho_test diff --git a/ql/src/test/results/clientpositive/authorization_create_table_owner_privs.q.out b/ql/src/test/results/clientpositive/authorization_create_table_owner_privs.q.out new file mode 100644 index 0000000..b1bce1c --- /dev/null +++ b/ql/src/test/results/clientpositive/authorization_create_table_owner_privs.q.out @@ -0,0 +1,17 @@ +PREHOOK: query: create table create_table_creator_priv_test(i int) +PREHOOK: type: CREATETABLE +POSTHOOK: query: create table create_table_creator_priv_test(i int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: default@create_table_creator_priv_test +PREHOOK: query: -- all privileges should have been set for user + +show grant user user1 on table create_table_creator_priv_test +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: -- all privileges should have been set for user + +show grant user user1 on table create_table_creator_priv_test +POSTHOOK: type: SHOW_GRANT +default create_table_creator_priv_test user1 USER DELETE true -1 user1 +default create_table_creator_priv_test user1 USER INSERT true -1 user1 +default create_table_creator_priv_test user1 USER SELECT true -1 user1 +default create_table_creator_priv_test user1 USER UPDATE true -1 user1 diff --git a/ql/src/test/results/clientpositive/authorization_grant_table_priv.q.out b/ql/src/test/results/clientpositive/authorization_grant_table_priv.q.out new file mode 100644 index 0000000..1e5c031 --- /dev/null +++ b/ql/src/test/results/clientpositive/authorization_grant_table_priv.q.out @@ -0,0 +1,106 @@ +PREHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv1(i int) +PREHOOK: type: CREATETABLE +POSTHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv1(i int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: default@table_priv1 +PREHOOK: query: -- all privileges should have been set for user + +-- grant insert privilege to another user +GRANT INSERT ON table_priv1 TO USER user2 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv1 +POSTHOOK: query: -- all privileges should have been set for user + +-- grant insert privilege to another user +GRANT INSERT ON table_priv1 TO USER user2 +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv1 +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv1 +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv1 +POSTHOOK: type: SHOW_GRANT +default table_priv1 user2 USER INSERT false -1 user1 +PREHOOK: query: -- grant select privilege to another user with grant +GRANT SELECT ON table_priv1 TO USER user2 with grant option +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv1 +POSTHOOK: query: -- grant select privilege to another user with grant +GRANT SELECT ON table_priv1 TO USER user2 with grant option +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv1 +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv1 +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv1 +POSTHOOK: type: SHOW_GRANT +default table_priv1 user2 USER INSERT false -1 user1 +default table_priv1 user2 USER SELECT true -1 user1 +PREHOOK: query: -- change to other user - user2 +-- grant permissions to another user as user2 +GRANT SELECT ON table_priv1 TO USER user3 with grant option +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv1 +POSTHOOK: query: -- change to other user - user2 +-- grant permissions to another user as user2 +GRANT SELECT ON table_priv1 TO USER user3 with grant option +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv1 +PREHOOK: query: SHOW GRANT USER user3 ON TABLE table_priv1 +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user3 ON TABLE table_priv1 +POSTHOOK: type: SHOW_GRANT +default table_priv1 user3 USER SELECT true -1 user2 +PREHOOK: query: -- change to other user - user3 +-- grant permissions to another user as user3 +GRANT SELECT ON table_priv1 TO USER user4 with grant option +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv1 +POSTHOOK: query: -- change to other user - user3 +-- grant permissions to another user as user3 +GRANT SELECT ON table_priv1 TO USER user4 with grant option +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv1 +PREHOOK: query: SHOW GRANT USER user4 ON TABLE table_priv1 +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user4 ON TABLE table_priv1 +POSTHOOK: type: SHOW_GRANT +default table_priv1 user4 USER SELECT true -1 user3 +#### A masked pattern was here #### + +-- grant all with grant to user22 +GRANT ALL ON table_priv1 TO USER user22 with grant option +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv1 +#### A masked pattern was here #### + +-- grant all with grant to user22 +GRANT ALL ON table_priv1 TO USER user22 with grant option +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv1 +PREHOOK: query: SHOW GRANT USER user22 ON TABLE table_priv1 +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user22 ON TABLE table_priv1 +POSTHOOK: type: SHOW_GRANT +default table_priv1 user22 USER DELETE true -1 user1 +default table_priv1 user22 USER INSERT true -1 user1 +default table_priv1 user22 USER SELECT true -1 user1 +default table_priv1 user22 USER UPDATE true -1 user1 +PREHOOK: query: -- grant all without grant to user33 +GRANT ALL ON table_priv1 TO USER user33 with grant option +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv1 +POSTHOOK: query: -- grant all without grant to user33 +GRANT ALL ON table_priv1 TO USER user33 with grant option +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv1 +PREHOOK: query: SHOW GRANT USER user33 ON TABLE table_priv1 +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user33 ON TABLE table_priv1 +POSTHOOK: type: SHOW_GRANT +default table_priv1 user33 USER DELETE true -1 user22 +default table_priv1 user33 USER INSERT true -1 user22 +default table_priv1 user33 USER SELECT true -1 user22 +default table_priv1 user33 USER UPDATE true -1 user22 diff --git a/ql/src/test/results/clientpositive/authorization_revoke_table_priv.q.out b/ql/src/test/results/clientpositive/authorization_revoke_table_priv.q.out new file mode 100644 index 0000000..a4ffc46 --- /dev/null +++ b/ql/src/test/results/clientpositive/authorization_revoke_table_priv.q.out @@ -0,0 +1,150 @@ +PREHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_rev(i int) +PREHOOK: type: CREATETABLE +POSTHOOK: query: -- current user has been set (comment line before the set cmd is resulting in parse error!!) + +CREATE TABLE table_priv_rev(i int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: default@table_priv_rev +PREHOOK: query: -- grant insert privilege to user2 +GRANT INSERT ON table_priv_rev TO USER user2 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_rev +POSTHOOK: query: -- grant insert privilege to user2 +GRANT INSERT ON table_priv_rev TO USER user2 +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv_rev +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +POSTHOOK: type: SHOW_GRANT +default table_priv_rev user2 USER INSERT false -1 user1 +PREHOOK: query: -- revoke insert privilege from user2 +REVOKE INSERT ON TABLE table_priv_rev FROM USER user2 +PREHOOK: type: REVOKE_PRIVILEGE +PREHOOK: Output: default@table_priv_rev +POSTHOOK: query: -- revoke insert privilege from user2 +REVOKE INSERT ON TABLE table_priv_rev FROM USER user2 +POSTHOOK: type: REVOKE_PRIVILEGE +POSTHOOK: Output: default@table_priv_rev +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +POSTHOOK: type: SHOW_GRANT +PREHOOK: query: -- grant all privileges one at a time -- +-- grant insert privilege to user2 +GRANT INSERT ON table_priv_rev TO USER user2 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_rev +POSTHOOK: query: -- grant all privileges one at a time -- +-- grant insert privilege to user2 +GRANT INSERT ON table_priv_rev TO USER user2 +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv_rev +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +POSTHOOK: type: SHOW_GRANT +default table_priv_rev user2 USER INSERT false -1 user1 +PREHOOK: query: -- grant select privilege to user2, with grant option +GRANT SELECT ON table_priv_rev TO USER user2 WITH GRANT OPTION +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_rev +POSTHOOK: query: -- grant select privilege to user2, with grant option +GRANT SELECT ON table_priv_rev TO USER user2 WITH GRANT OPTION +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv_rev +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +POSTHOOK: type: SHOW_GRANT +default table_priv_rev user2 USER INSERT false -1 user1 +default table_priv_rev user2 USER SELECT true -1 user1 +PREHOOK: query: -- grant update privilege to user2 +GRANT UPDATE ON table_priv_rev TO USER user2 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_rev +POSTHOOK: query: -- grant update privilege to user2 +GRANT UPDATE ON table_priv_rev TO USER user2 +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv_rev +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +POSTHOOK: type: SHOW_GRANT +default table_priv_rev user2 USER INSERT false -1 user1 +default table_priv_rev user2 USER UPDATE false -1 user1 +default table_priv_rev user2 USER SELECT true -1 user1 +PREHOOK: query: -- grant delete privilege to user2 +GRANT DELETE ON table_priv_rev TO USER user2 +PREHOOK: type: GRANT_PRIVILEGE +PREHOOK: Output: default@table_priv_rev +POSTHOOK: query: -- grant delete privilege to user2 +GRANT DELETE ON table_priv_rev TO USER user2 +POSTHOOK: type: GRANT_PRIVILEGE +POSTHOOK: Output: default@table_priv_rev +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +POSTHOOK: type: SHOW_GRANT +default table_priv_rev user2 USER DELETE false -1 user1 +default table_priv_rev user2 USER INSERT false -1 user1 +default table_priv_rev user2 USER UPDATE false -1 user1 +default table_priv_rev user2 USER SELECT true -1 user1 +PREHOOK: query: -- start revoking -- +-- revoke update privilege from user2 +REVOKE UPDATE ON TABLE table_priv_rev FROM USER user2 +PREHOOK: type: REVOKE_PRIVILEGE +PREHOOK: Output: default@table_priv_rev +POSTHOOK: query: -- start revoking -- +-- revoke update privilege from user2 +REVOKE UPDATE ON TABLE table_priv_rev FROM USER user2 +POSTHOOK: type: REVOKE_PRIVILEGE +POSTHOOK: Output: default@table_priv_rev +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +POSTHOOK: type: SHOW_GRANT +default table_priv_rev user2 USER DELETE false -1 user1 +default table_priv_rev user2 USER INSERT false -1 user1 +default table_priv_rev user2 USER SELECT true -1 user1 +PREHOOK: query: -- revoke DELETE privilege from user2 +REVOKE DELETE ON TABLE table_priv_rev FROM USER user2 +PREHOOK: type: REVOKE_PRIVILEGE +PREHOOK: Output: default@table_priv_rev +POSTHOOK: query: -- revoke DELETE privilege from user2 +REVOKE DELETE ON TABLE table_priv_rev FROM USER user2 +POSTHOOK: type: REVOKE_PRIVILEGE +POSTHOOK: Output: default@table_priv_rev +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +POSTHOOK: type: SHOW_GRANT +default table_priv_rev user2 USER INSERT false -1 user1 +default table_priv_rev user2 USER SELECT true -1 user1 +PREHOOK: query: -- revoke insert privilege from user2 +REVOKE INSERT ON TABLE table_priv_rev FROM USER user2 +PREHOOK: type: REVOKE_PRIVILEGE +PREHOOK: Output: default@table_priv_rev +POSTHOOK: query: -- revoke insert privilege from user2 +REVOKE INSERT ON TABLE table_priv_rev FROM USER user2 +POSTHOOK: type: REVOKE_PRIVILEGE +POSTHOOK: Output: default@table_priv_rev +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +POSTHOOK: type: SHOW_GRANT +default table_priv_rev user2 USER SELECT true -1 user1 +PREHOOK: query: -- revoke select privilege from user2 +REVOKE SELECT ON TABLE table_priv_rev FROM USER user2 +PREHOOK: type: REVOKE_PRIVILEGE +PREHOOK: Output: default@table_priv_rev +POSTHOOK: query: -- revoke select privilege from user2 +REVOKE SELECT ON TABLE table_priv_rev FROM USER user2 +POSTHOOK: type: REVOKE_PRIVILEGE +POSTHOOK: Output: default@table_priv_rev +PREHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +PREHOOK: type: SHOW_GRANT +POSTHOOK: query: SHOW GRANT USER user2 ON TABLE table_priv_rev +POSTHOOK: type: SHOW_GRANT