From 8b1050fc25bcdba371d52e4e894e6e45f1c813a6 Mon Sep 17 00:00:00 2001 From: Kiran Velumuri Date: Thu, 11 Dec 2025 10:10:03 +0530 Subject: [PATCH] HIVE-29306: GSSException encountered during HMS Ranger authorization --- .../TestRemoteHiveMetaStoreKerberos.java | 75 +++++++++++++++++++ .../security/TUGIAssumingTransport.java | 3 +- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/itests/hive-minikdc/src/test/java/org/apache/hive/minikdc/TestRemoteHiveMetaStoreKerberos.java b/itests/hive-minikdc/src/test/java/org/apache/hive/minikdc/TestRemoteHiveMetaStoreKerberos.java index cf25ac08a4c7..de40cc31c6f1 100644 --- a/itests/hive-minikdc/src/test/java/org/apache/hive/minikdc/TestRemoteHiveMetaStoreKerberos.java +++ b/itests/hive-minikdc/src/test/java/org/apache/hive/minikdc/TestRemoteHiveMetaStoreKerberos.java @@ -20,18 +20,27 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hive.metastore.HiveMetaStoreClient; +import org.apache.hadoop.hive.metastore.IMetaStoreClient; import org.apache.hadoop.hive.metastore.TestRemoteHiveMetaStore; import org.apache.hadoop.hive.metastore.api.EnvironmentContext; import org.apache.hadoop.hive.metastore.api.Partition; import org.apache.hadoop.hive.metastore.conf.MetastoreConf; import org.apache.hadoop.hive.metastore.conf.MetastoreConf.ConfVars; +import org.apache.hadoop.hive.ql.metadata.StringAppender; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.logging.log4j.Level; import org.apache.thrift.transport.TTransportException; import org.junit.Before; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.security.PrivilegedExceptionAction; import java.util.List; import java.util.ArrayList; +import org.junit.Assert; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; @@ -107,6 +116,72 @@ public void testThriftMaxMessageSize() throws Throwable { cleanUp(dbName, tblName, typeName); } + @Test + public void testKerberosProxyUser() throws Exception { + String realUserName = "realuser"; + String realUserPrincipal = miniKDC.getFullyQualifiedUserPrincipal(realUserName); + + // Add the real user principal and generate keytab + miniKDC.addUserPrincipal(realUserName); + + // Login real user with valid keytab - this gives us real TGT credentials + UserGroupInformation realUserUgi = miniKDC.loginUser(realUserName); + + // Create a proxy user on behalf of the real user + String proxyUserName = "proxyuser@" + miniKDC.getKdcConf().getProperty("realm", "EXAMPLE.COM"); + UserGroupInformation proxyUserUgi = UserGroupInformation.createProxyUser( + proxyUserName, realUserUgi); + + proxyUserUgi.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + Logger logger = null; + StringAppender appender = null; + try { + UserGroupInformation currentUser = UserGroupInformation.getCurrentUser(); + + System.out.println("Real user: " + currentUser.getRealUser().getUserName() + + " (auth:" + currentUser.getRealUser().getAuthenticationMethod() + ")"); + System.out.println("Proxy user: " + currentUser.getShortUserName() + + " (auth:" + currentUser.getAuthenticationMethod() + ")"); + + // Set up log capture to catch "Failed to find any Kerberos tgt" error in logs + logger = LoggerFactory.getLogger("org.apache.hadoop.hive.metastore.security"); + appender = StringAppender.createStringAppender(null); + appender.addToLogger(logger.getName(), Level.INFO); + appender.start(); + + // Attempt to create metastore client connection as Kerberos proxy user + // This should work properly (after TUGIAssumingTransport fix) + IMetaStoreClient client = new HiveMetaStoreClient(conf); + + // Clean up + if (client != null) { + client.close(); + } + + // The test has successfully demonstrated: + // 1. Real user has valid Kerberos authentication with real TGT from MiniKdc + // 2. Proxy user is properly created with PROXY authentication method + // 3. TUGIAssumingTransport fix is working - no "Failed to find any Kerberos tgt" error + System.out.println("Successfully verified Kerberos proxy user setup with real KDC"); + + } catch (Exception clientException) { + // Check the captured logs for the specific "Failed to find any Kerberos tgt" error + if (appender.getOutput().contains("Failed to find any Kerberos tgt")) { + // This is expected behavior before TUGIAssumingTransport fix + Assert.fail("EXPECTED BEFORE FIX: HMS client creation failed with 'Failed to find any Kerberos tgt' error in logs"); + } else { + Assert.fail("Unexpected error (not 'Failed to find any Kerberos tgt'): " + clientException.getMessage()); + } + } finally { + appender.removeFromLogger(logger.getName()); + } + return null; + } + }); + } + @Override protected HiveMetaStoreClient createClient() throws Exception { MetastoreConf.setVar(conf, ConfVars.THRIFT_URIS, "thrift://localhost:" + port); diff --git a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/security/TUGIAssumingTransport.java b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/security/TUGIAssumingTransport.java index 38a946e2d2f8..474e38fbcd82 100644 --- a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/security/TUGIAssumingTransport.java +++ b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/security/TUGIAssumingTransport.java @@ -45,7 +45,8 @@ public TUGIAssumingTransport(TTransport wrapped, UserGroupInformation ugi) { @Override public void open() throws TTransportException { try { - ugi.doAs(new PrivilegedExceptionAction() { + UserGroupInformation loggedInUGI = ugi.getRealUser() != null ? ugi.getRealUser() : ugi; + loggedInUGI.doAs(new PrivilegedExceptionAction() { public Void run() { try { wrapped.open();