Index: standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java (revision 0213afb8a31af1f48d009edd41cec9e6c8942354) +++ standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java (date 1567775977000) @@ -585,7 +585,7 @@ // Wrap thrift connection with SASL for secure connection. try { HadoopThriftAuthBridge.Client authBridge = - HadoopThriftAuthBridge.getBridge().createClient(); + HadoopThriftAuthBridge.getBridge().createClientWithConf("KERBEROS"); // check if we should use delegation tokens to authenticate // the call below gets hold of the tokens if they are set up by hadoop @@ -604,10 +604,11 @@ MetaStoreUtils.getMetaStoreSaslProperties(conf, useSSL)); } else { LOG.debug("HMSC::open(): Could not find delegation token. Creating KERBEROS-based thrift connection."); - String principalConfig = - MetastoreConf.getVar(conf, ConfVars.KERBEROS_PRINCIPAL); + String principalConfig = MetastoreConf.getVar(conf, ConfVars.KERBEROS_PRINCIPAL); + String keytab = MetastoreConf.getVar(conf, ConfVars.KERBEROS_KEYTAB_FILE); + transport = authBridge.createClientTransport( - principalConfig, store.getHost(), "KERBEROS", null, + principalConfig, keytab, store.getHost(), "KERBEROS", null, transport, MetaStoreUtils.getMetaStoreSaslProperties(conf, useSSL)); } } catch (IOException ioe) { Index: standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/security/HadoopThriftAuthBridge.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/security/HadoopThriftAuthBridge.java (revision 0213afb8a31af1f48d009edd41cec9e6c8942354) +++ standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/security/HadoopThriftAuthBridge.java (date 1567775977000) @@ -202,9 +202,17 @@ * @param saslProps the sasl properties to create the client with */ - public TTransport createClientTransport( - String principalConfig, String host, + String principalConfig, String host, + String methodStr, String tokenStrForm, final TTransport underlyingTransport, + final Map saslProps) throws IOException { + + return createClientTransport(principalConfig, null, host, methodStr, tokenStrForm, + underlyingTransport, saslProps); + } + + public TTransport createClientTransport( + String principalConfig, String keytab, String host, String methodStr, String tokenStrForm, final TTransport underlyingTransport, final Map saslProps) throws IOException { final AuthMethod method = AuthMethod.valueOf(AuthMethod.class, methodStr); @@ -231,19 +239,19 @@ + serverPrincipal); } try { - return UserGroupInformation.getCurrentUser().doAs( - new PrivilegedExceptionAction() { - @Override - public TUGIAssumingTransport run() throws IOException { - TTransport saslTransport = new TSaslClientTransport( - method.getMechanismName(), - null, - names[0], names[1], - saslProps, null, - underlyingTransport); - return new TUGIAssumingTransport(saslTransport, UserGroupInformation.getCurrentUser()); - } - }); + UserGroupInformation ugi = !UserGroupInformation.getCurrentUser().hasKerberosCredentials() ? + loginWithKerberos(serverPrincipal, keytab) : UserGroupInformation.getCurrentUser(); + + return ugi.doAs( + (PrivilegedExceptionAction) () -> { + TTransport saslTransport1 = new TSaslClientTransport( + method.getMechanismName(), + null, + names[0], names[1], + saslProps, null, + underlyingTransport); + return new TUGIAssumingTransport(saslTransport1, ugi); + }); } catch (InterruptedException | SaslException se) { throw new IOException("Could not instantiate SASL transport", se); } @@ -252,6 +260,26 @@ throw new IOException("Unsupported authentication method: " + method); } } + + /** + * Login using Kerberos and return UGI + * + * @param principal - kerberos principal + * @param keytabFile - keytab file + * @throws IOException - if keytab file cannot be found + */ + private UserGroupInformation loginWithKerberos(String principal, String keytabFile) throws IOException { + if (!UserGroupInformation.isSecurityEnabled()) { + return null; + } + if (principal == null || principal.isEmpty() || keytabFile == null || keytabFile.isEmpty()) { + throw new RuntimeException("Kerberos principal and/or keytab are null or empty"); + } + final String serverPrincipal = SecurityUtil.getServerPrincipal(principal, "0.0.0.0"); + LOG.info("Logging in as " + serverPrincipal + " via " + keytabFile); + return UserGroupInformation.loginUserFromKeytabAndReturnUGI(serverPrincipal, keytabFile); + } + private static class SaslClientCallbackHandler implements CallbackHandler { private final String userName; private final char[] userPassword;