diff --git a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java index 78d9cc9..edec7c8 100644 --- a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java +++ b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java @@ -722,8 +722,8 @@ HIVE_SERVER2_KERBEROS_PRINCIPAL("hive.server2.authentication.kerberos.principal", ""), HIVE_SERVER2_PLAIN_LDAP_URL("hive.server2.authentication.ldap.url", null), HIVE_SERVER2_PLAIN_LDAP_BASEDN("hive.server2.authentication.ldap.baseDN", null), - HIVE_SERVER2_KERBEROS_IMPERSONATION("hive.server2.enable.impersonation", false), HIVE_SERVER2_CUSTOM_AUTHENTICATION_CLASS("hive.server2.custom.authentication.class", null), + HIVE_SERVER2_ENABLE_DOAS("hive.server2.enable.doAs", true), HIVE_CONF_RESTRICTED_LIST("hive.conf.restricted.list", null), diff --git a/conf/hive-default.xml.template b/conf/hive-default.xml.template index e266ce7..41e20af 100644 --- a/conf/hive-default.xml.template +++ b/conf/hive-default.xml.template @@ -1877,7 +1877,6 @@ - hive.server2.authentication.ldap.baseDN @@ -1886,5 +1885,15 @@ + + hive.server2.enable.doAs + true + + Setting this property to true will have hive server2 execute + hive operations as the user making the calls to it. + + + + diff --git a/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java b/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java index 18d4aae..15b1675 100644 --- a/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java +++ b/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java @@ -103,7 +103,7 @@ public SQLPlainProcessorFactory(ThriftCLIService service) { super(null); this.service = service; this.conf = service.getHiveConf(); - this.doAsEnabled = conf.getBoolean("hive.server2.enable.doAs", false); + this.doAsEnabled = conf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_ENABLE_DOAS); } @Override diff --git a/service/src/java/org/apache/hive/service/cli/CLIService.java b/service/src/java/org/apache/hive/service/cli/CLIService.java index b53599b..035e689 100644 --- a/service/src/java/org/apache/hive/service/cli/CLIService.java +++ b/service/src/java/org/apache/hive/service/cli/CLIService.java @@ -309,7 +309,7 @@ public RowSet fetchResults(OperationHandle opHandle) public synchronized String getDelegationTokenFromMetaStore(String owner) throws HiveSQLException, UnsupportedOperationException, LoginException, IOException { if (!hiveConf.getBoolVar(HiveConf.ConfVars.METASTORE_USE_THRIFT_SASL) || - !hiveConf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_KERBEROS_IMPERSONATION)) { + !hiveConf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_ENABLE_DOAS)) { throw new UnsupportedOperationException( "delegation token is can only be obtained for a secure remote metastore"); } diff --git a/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java b/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java index 43d79aa..0788ead 100644 --- a/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java +++ b/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java @@ -18,16 +18,20 @@ package org.apache.hive.service.cli.thrift; +import java.io.IOException; import java.net.InetSocketAddress; import java.util.HashMap; import java.util.Map; +import javax.security.auth.login.LoginException; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.conf.HiveConf.ConfVars; import org.apache.hive.service.AbstractService; import org.apache.hive.service.auth.HiveAuthFactory; +import org.apache.hive.service.cli.CLIService; import org.apache.hive.service.cli.FetchOrientation; import org.apache.hive.service.cli.GetInfoType; import org.apache.hive.service.cli.GetInfoValue; @@ -35,7 +39,6 @@ import org.apache.hive.service.cli.OperationHandle; import org.apache.hive.service.cli.OperationState; import org.apache.hive.service.cli.RowSet; -import org.apache.hive.service.cli.CLIService; import org.apache.hive.service.cli.SessionHandle; import org.apache.hive.service.cli.TableSchema; import org.apache.thrift.TException; @@ -110,28 +113,7 @@ public synchronized void stop() { public TOpenSessionResp OpenSession(TOpenSessionReq req) throws TException { TOpenSessionResp resp = new TOpenSessionResp(); try { - String userName; - if (hiveAuthFactory != null - && hiveAuthFactory.getRemoteUser() != null) { - userName = hiveAuthFactory.getRemoteUser(); - } else { - userName = req.getUsername(); - } - SessionHandle sessionHandle = null; - if (cliService.getHiveConf(). - getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_KERBEROS_IMPERSONATION)) { - String delegationTokenStr = null; - try { - delegationTokenStr = cliService.getDelegationTokenFromMetaStore(userName); - } catch (UnsupportedOperationException e) { - // The delegation token is not applicable in the given deployment mode - } - sessionHandle = cliService.openSessionWithImpersonation(userName, req.getPassword(), - req.getConfiguration(), delegationTokenStr); - } else { - sessionHandle = cliService.openSession(userName, req.getPassword(), - req.getConfiguration()); - } + SessionHandle sessionHandle = getSessionHandle(req); resp.setSessionHandle(sessionHandle.toTSessionHandle()); // TODO: set real configuration map resp.setConfiguration(new HashMap()); @@ -143,6 +125,44 @@ public TOpenSessionResp OpenSession(TOpenSessionReq req) throws TException { return resp; } + private String getUserName(TOpenSessionReq req) { + if (hiveAuthFactory != null + && hiveAuthFactory.getRemoteUser() != null) { + return hiveAuthFactory.getRemoteUser(); + } else { + return req.getUsername(); + } + } + + SessionHandle getSessionHandle(TOpenSessionReq req) + throws HiveSQLException, LoginException, IOException { + + String userName = getUserName(req); + + SessionHandle sessionHandle = null; + if ( + cliService.getHiveConf().getVar(ConfVars.HIVE_SERVER2_AUTHENTICATION) + .equals(HiveAuthFactory.AuthTypes.KERBEROS.toString()) + && + cliService.getHiveConf(). + getBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS) + ) + { + String delegationTokenStr = null; + try { + delegationTokenStr = cliService.getDelegationTokenFromMetaStore(userName); + } catch (UnsupportedOperationException e) { + // The delegation token is not applicable in the given deployment mode + } + sessionHandle = cliService.openSessionWithImpersonation(userName, req.getPassword(), + req.getConfiguration(), delegationTokenStr); + } else { + sessionHandle = cliService.openSession(userName, req.getPassword(), + req.getConfiguration()); + } + return sessionHandle; + } + @Override public TCloseSessionResp CloseSession(TCloseSessionReq req) throws TException { TCloseSessionResp resp = new TCloseSessionResp(); diff --git a/service/src/test/org/apache/hive/service/auth/TestPlainSaslHelper.java b/service/src/test/org/apache/hive/service/auth/TestPlainSaslHelper.java new file mode 100644 index 0000000..8395647 --- /dev/null +++ b/service/src/test/org/apache/hive/service/auth/TestPlainSaslHelper.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.hive.service.auth; + +import junit.framework.TestCase; + +import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.conf.HiveConf.ConfVars; +import org.apache.hive.service.cli.CLIService; +import org.apache.hive.service.cli.thrift.ThriftCLIService; +import org.apache.thrift.TProcessorFactory; + +public class TestPlainSaslHelper extends TestCase { + + /** + * Test setting {@link HiveConf.ConfVars}} config parameter + * HIVE_SERVER2_ENABLE_DOAS for unsecure mode + */ + public void testDoAsSetting(){ + + HiveConf hconf = new HiveConf(); + assertTrue("default value of hive server2 doAs should be true", + hconf.getBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS)); + + + CLIService cliService = new CLIService(); + cliService.init(hconf); + ThriftCLIService tcliService = new ThriftCLIService(cliService); + tcliService.init(hconf); + TProcessorFactory procFactory = PlainSaslHelper.getPlainProcessorFactory(tcliService); + assertEquals("doAs enabled processor for unsecure mode", + procFactory.getProcessor(null).getClass(), TUGIContainingProcessor.class); + } +} diff --git a/service/src/test/org/apache/hive/service/cli/thrift/TestThriftCLIService.java b/service/src/test/org/apache/hive/service/cli/thrift/TestThriftCLIService.java new file mode 100644 index 0000000..963803a --- /dev/null +++ b/service/src/test/org/apache/hive/service/cli/thrift/TestThriftCLIService.java @@ -0,0 +1,76 @@ +/** + * 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.hive.service.cli.thrift; + +import java.io.IOException; +import java.util.Collection; + +import javax.security.auth.login.LoginException; + +import junit.framework.TestCase; + +import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.conf.HiveConf.ConfVars; +import org.apache.hive.service.Service; +import org.apache.hive.service.auth.HiveAuthFactory; +import org.apache.hive.service.cli.CLIService; +import org.apache.hive.service.cli.HiveSQLException; +import org.apache.hive.service.cli.SessionHandle; +import org.apache.hive.service.cli.session.HiveSession; +import org.apache.hive.service.cli.session.SessionManager; + +public class TestThriftCLIService extends TestCase{ + + /** + * Test setting {@link HiveConf.ConfVars}} config parameter + * HIVE_SERVER2_ENABLE_DOAS for kerberos secure mode + * @throws IOException + * @throws LoginException + * @throws HiveSQLException + */ + public void testDoAs() throws HiveSQLException, LoginException, IOException{ + HiveConf hconf = new HiveConf(); + assertTrue("default value of hive server2 doAs should be true", + hconf.getBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS)); + + hconf.setVar(ConfVars.HIVE_SERVER2_AUTHENTICATION, + HiveAuthFactory.AuthTypes.KERBEROS.toString()); + + CLIService cliService = new CLIService(); + cliService.init(hconf); + ThriftCLIService tcliService = new ThriftCLIService(cliService); + TOpenSessionReq req = new TOpenSessionReq(); + req.setUsername("testuser1"); + SessionHandle sHandle = tcliService.getSessionHandle(req ); + SessionManager sManager = getSessionManager(cliService.getServices()); + HiveSession session = sManager.getSession(sHandle); + + //Proxy class for doing doAs on all calls is used when doAs is enabled + // and kerberos security is on + assertTrue("check if session class is a proxy", session instanceof java.lang.reflect.Proxy); + } + + private SessionManager getSessionManager(Collection services) { + for(Service s : services){ + if(s instanceof SessionManager){ + return (SessionManager)s; + } + } + return null; + } +}