/** * 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.drill.exec.store.hive; import com.google.common.collect.ImmutableList; import org.apache.drill.common.exceptions.DrillRuntimeException; import org.apache.drill.common.exceptions.UserException; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.conf.HiveConf.ConfVars; import org.apache.hadoop.hive.metastore.IMetaStoreClient; import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.ql.metadata.HiveUtils; import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAccessControlException; 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.HiveAuthzContext; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzSessionContext; import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzSessionContext.CLIENT_TYPE; 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.HivePrivilegeObject; import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivilegeObjectType; import org.apache.hadoop.hive.ql.session.SessionState; import java.util.Collections; import java.util.List; /** * Helper class for initializing and checking privileges according to authorization configuration set in Hive storage * plugin config. */ public class HiveAuthorizationHelper { private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(HiveAuthorizationHelper.class); final boolean authzEnabled; final HiveAuthorizer authorizerV2; public HiveAuthorizationHelper(final IMetaStoreClient mClient, final HiveConf hiveConf, final String user) { authzEnabled = hiveConf.getBoolVar(ConfVars.HIVE_AUTHORIZATION_ENABLED); if (!authzEnabled) { authorizerV2 = null; return; } try { final HiveConf hiveConfCopy = new HiveConf(hiveConf); hiveConfCopy.set("user.name", user); final HiveAuthenticationProvider authenticator = HiveUtils.getAuthenticator(hiveConfCopy, HiveConf.ConfVars.HIVE_AUTHENTICATOR_MANAGER); SessionState ss = new SessionState(hiveConfCopy, user); SessionState.start(ss); authenticator.setSessionState(ss); HiveAuthorizerFactory authorizerFactory = HiveUtils.getAuthorizerFactory(hiveConfCopy, HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER); HiveAuthzSessionContext.Builder authzContextBuilder = new HiveAuthzSessionContext.Builder(); authzContextBuilder.setClientType(CLIENT_TYPE.HIVESERVER2); // Drill is emulating HS2 here authorizerV2 = authorizerFactory.createHiveAuthorizer( new HiveMetastoreClientFactory() { @Override public IMetaStoreClient getHiveMetastoreClient() throws HiveAuthzPluginException { return mClient; } }, hiveConf, authenticator, authzContextBuilder.build()); authorizerV2.applyAuthorizationConfigPolicy(hiveConfCopy); } catch (final HiveException e) { throw new DrillRuntimeException("Failed to initialize Hive authorization components: " + e.getMessage(), e); } logger.trace("Hive authorization enabled"); } /** * Check authorization for "SHOW DATABASES" command. A {@link HiveAccessControlException} is thrown * for illegal access. */ public void authorizeShowDatabases() throws HiveAccessControlException { if (!authzEnabled) { return; } authorize(HiveOperationType.SHOWDATABASES, Collections.<HivePrivilegeObject> emptyList(), Collections.<HivePrivilegeObject> emptyList(), "SHOW DATABASES"); } /** * Check authorization for "SHOW TABLES" command in given Hive db. A {@link HiveAccessControlException} is thrown * for illegal access. * @param dbName */ public void authorizeShowTables(final String dbName) throws HiveAccessControlException { if (!authzEnabled) { return; } final HivePrivilegeObject toRead = new HivePrivilegeObject(HivePrivilegeObjectType.DATABASE, dbName, null); authorize(HiveOperationType.SHOWTABLES, ImmutableList.of(toRead), Collections.<HivePrivilegeObject> emptyList(), "SHOW TABLES"); } /** * Check authorization for "READ TABLE" for given db.table. A {@link HiveAccessControlException} is thrown * for illegal access. * @param dbName * @param tableName */ public void authorizeReadTable(final String dbName, final String tableName) throws HiveAccessControlException { if (!authzEnabled) { return; } HivePrivilegeObject toRead = new HivePrivilegeObject(HivePrivilegeObjectType.TABLE_OR_VIEW, dbName, tableName); authorize(HiveOperationType.QUERY, ImmutableList.of(toRead), Collections.<HivePrivilegeObject> emptyList(), "READ TABLE"); } /* Helper method to check privileges */ private void authorize(final HiveOperationType hiveOpType, final List<HivePrivilegeObject> toRead, final List<HivePrivilegeObject> toWrite, final String cmd) throws HiveAccessControlException { try { HiveAuthzContext.Builder authzContextBuilder = new HiveAuthzContext.Builder(); authzContextBuilder.setUserIpAddress("Not available"); authzContextBuilder.setCommandString(cmd); authorizerV2.checkPrivileges(hiveOpType, toRead, toWrite, authzContextBuilder.build()); } catch (final HiveAccessControlException e) { throw e; } catch (final Exception e) { throw new DrillRuntimeException("Failed to use the Hive authorization components: " + e.getMessage(), e); } } }