diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java index 92545d8..2c5b463 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java @@ -55,7 +55,6 @@ import org.apache.hadoop.hive.ql.plan.OperatorDesc; import org.apache.hadoop.hive.ql.plan.api.StageType; import org.apache.hadoop.hive.ql.security.authorization.AuthorizationFactory; -import org.apache.hadoop.hive.ql.security.authorization.HiveAuthorizationProvider; import org.apache.hadoop.hive.ql.session.SessionState; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.util.StringUtils; @@ -334,23 +333,27 @@ private JSONObject collectAuthRelatedEntities(PrintStream out, ExplainWork work) if (analyzer.skipAuthorization()) { return object; } - HiveAuthorizationProvider delegate = SessionState.get().getAuthorizer(); final List exceptions = new ArrayList(); - HiveAuthorizationProvider authorizer = AuthorizationFactory.create(delegate, - new AuthorizationFactory.AuthorizationExceptionHandler() { - public void exception(AuthorizationException exception) { - exceptions.add(exception.getMessage()); - } - }); - SessionState.get().setAuthorizer(authorizer); - try { - Driver.doAuthorization(analyzer); - } finally { - SessionState.get().setAuthorizer(delegate); - } + Object delegate = SessionState.get().getActiveAuthorizer(); + if (delegate != null) { + Class itface = SessionState.get().getAuthorizerInterface(); + Object authorizer = AuthorizationFactory.create(delegate, itface, + new AuthorizationFactory.AuthorizationExceptionHandler() { + public void exception(Exception exception) { + exceptions.add(exception.getMessage()); + } + }); + + SessionState.get().setActiveAuthorizer(authorizer); + try { + Driver.doAuthorization(analyzer); + } finally { + SessionState.get().setActiveAuthorizer(delegate); + } + } if (!exceptions.isEmpty()) { Object jsonFails = toJson("AUTHORIZATION_FAILURES", exceptions, out, work); if (work.isFormatted()) { diff --git ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationFactory.java ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationFactory.java index 47c57db..7e1696b 100644 --- ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationFactory.java +++ ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationFactory.java @@ -19,6 +19,8 @@ package org.apache.hadoop.hive.ql.security.authorization; import org.apache.hadoop.hive.ql.metadata.AuthorizationException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAccessControlException; +import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; @@ -27,13 +29,8 @@ public class AuthorizationFactory { - public static HiveAuthorizationProvider create(HiveAuthorizationProvider delegated) { - return create(delegated, new DefaultAuthorizationExceptionHandler()); - } - - public static HiveAuthorizationProvider create(final HiveAuthorizationProvider delegated, - final AuthorizationExceptionHandler handler) { - + public static T create( + final Object delegated, final Class itface, final AuthorizationExceptionHandler handler) { InvocationHandler invocation = new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { invokeAuth(method, args); @@ -44,27 +41,38 @@ private void invokeAuth(Method method, Object[] args) throws Throwable { try { method.invoke(delegated, args); } catch (InvocationTargetException e) { - if (e.getTargetException() instanceof AuthorizationException) { - handler.exception((AuthorizationException) e.getTargetException()); + if (e.getTargetException() instanceof AuthorizationException || + e.getTargetException() instanceof HiveAuthzPluginException|| + e.getTargetException() instanceof HiveAccessControlException) { + handler.exception((Exception) e.getTargetException()); } } } }; - return (HiveAuthorizationProvider)Proxy.newProxyInstance( - AuthorizationFactory.class.getClassLoader(), - new Class[] {HiveAuthorizationProvider.class}, - invocation); + return (T) Proxy.newProxyInstance( + AuthorizationFactory.class.getClassLoader(), new Class[]{itface}, invocation); } public static interface AuthorizationExceptionHandler { - void exception(AuthorizationException exception) throws AuthorizationException; + void exception(Exception exception) + throws AuthorizationException, HiveAuthzPluginException, HiveAccessControlException; } public static class DefaultAuthorizationExceptionHandler implements AuthorizationExceptionHandler { - public void exception(AuthorizationException exception) { - throw exception; + public void exception(Exception exception) throws + AuthorizationException, HiveAuthzPluginException, HiveAccessControlException { + if (exception instanceof AuthorizationException) { + throw (AuthorizationException) exception; + } + if (exception instanceof HiveAuthzPluginException) { + throw (HiveAuthzPluginException) exception; + } + if (exception instanceof HiveAccessControlException) { + throw (HiveAccessControlException) exception; + } + throw new RuntimeException(exception); } } } diff --git ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java index 2de476e..0f0c294 100644 --- ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java +++ ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java @@ -397,13 +397,32 @@ private void setupAuth() { } if(LOG.isDebugEnabled()){ - Object authorizationClass = getAuthorizationMode() == AuthorizationMode.V1 ? - getAuthorizer() : getAuthorizerV2(); - LOG.debug("Session is using authorization class " + authorizationClass.getClass()); + Object authorizationClass = getActiveAuthorizer(); + LOG.debug("Session is using authorization class " + authorizationClass.getClass()); } return; } + public Object getActiveAuthorizer() { + return getAuthorizationMode() == AuthorizationMode.V1 ? + getAuthorizer() : getAuthorizerV2(); + } + + public Class getAuthorizerInterface() { + return getAuthorizationMode() == AuthorizationMode.V1 ? + HiveAuthorizationProvider.class : HiveAuthorizer.class; + } + + public void setActiveAuthorizer(Object authorizer) { + if (authorizer instanceof HiveAuthorizationProvider) { + this.authorizer = (HiveAuthorizationProvider)authorizer; + } else if (authorizer instanceof HiveAuthorizer) { + this.authorizerV2 = (HiveAuthorizer) authorizer; + } else if (authorizer != null) { + throw new IllegalArgumentException("Invalid authorizer " + authorizer); + } + } + /** * @param conf * @return per-session temp file diff --git ql/src/test/queries/clientpositive/authorization_view_sqlstd.q ql/src/test/queries/clientpositive/authorization_view_sqlstd.q index 3418e47..b04f6d6 100644 --- ql/src/test/queries/clientpositive/authorization_view_sqlstd.q +++ ql/src/test/queries/clientpositive/authorization_view_sqlstd.q @@ -30,6 +30,8 @@ show grant user user3 on table vt1; set user.name=user2; + +explain authorization select * from vt1; select * from vt1; set user.name=user1; diff --git ql/src/test/results/clientpositive/authorization_view_sqlstd.q.out ql/src/test/results/clientpositive/authorization_view_sqlstd.q.out index cf3925b..a4b59b3 100644 --- ql/src/test/results/clientpositive/authorization_view_sqlstd.q.out +++ ql/src/test/results/clientpositive/authorization_view_sqlstd.q.out @@ -79,6 +79,19 @@ PREHOOK: type: SHOW_GRANT POSTHOOK: query: show grant user user3 on table vt1 POSTHOOK: type: SHOW_GRANT default vt1 user3 USER INSERT false -1 user1 +PREHOOK: query: explain authorization select * from vt1 +PREHOOK: type: QUERY +POSTHOOK: query: explain authorization select * from vt1 +POSTHOOK: type: QUERY +INPUTS: + default@vt1 + default@t1 +OUTPUTS: +#### A masked pattern was here #### +CURRENT_USER: + user2 +OPERATION: + QUERY PREHOOK: query: select * from vt1 PREHOOK: type: QUERY PREHOOK: Input: default@t1