This is an automated email from the ASF dual-hosted git repository.

rajeshbabu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/phoenix-omid.git


The following commit(s) were added to refs/heads/master by this push:
     new 86dcf1e  OMID-194 OmidTableManager cannot create commit and timestamp 
tables in kerberos cluster(Rajeshbabu)
86dcf1e is described below

commit 86dcf1e1d0d177af217838be7d951b58d783034d
Author: Rajeshbabu Chintaguntla <rajeshb...@apache.org>
AuthorDate: Tue Feb 9 10:38:45 2021 +0530

    OMID-194 OmidTableManager cannot create commit and timestamp tables in 
kerberos cluster(Rajeshbabu)
---
 .../org/apache/omid/tools/hbase/HBaseLogin.java    | 90 +++++++++++++++++++---
 .../apache/omid/tools/hbase/OmidTableManager.java  |  7 +-
 2 files changed, 86 insertions(+), 11 deletions(-)

diff --git 
a/hbase-common/src/main/java/org/apache/omid/tools/hbase/HBaseLogin.java 
b/hbase-common/src/main/java/org/apache/omid/tools/hbase/HBaseLogin.java
index 92b4904..0241fc0 100644
--- a/hbase-common/src/main/java/org/apache/omid/tools/hbase/HBaseLogin.java
+++ b/hbase-common/src/main/java/org/apache/omid/tools/hbase/HBaseLogin.java
@@ -17,7 +17,11 @@
  */
 package org.apache.omid.tools.hbase;
 
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.security.User;
 import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authentication.util.KerberosUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -29,22 +33,38 @@ public final class HBaseLogin {
     private static final Logger LOG = 
LoggerFactory.getLogger(HBaseLogin.class);
 
     private static volatile UserGroupInformation ugi;
+    private static final Object KERBEROS_LOGIN_LOCK = new Object();
 
     @Nullable
     public static UserGroupInformation loginIfNeeded(SecureHBaseConfig config) 
throws IOException {
+        return loginIfNeeded(config, null);
+    }
 
-        if (UserGroupInformation.isSecurityEnabled()) {
-            LOG.info("Security enabled when connecting to HBase");
-            if (ugi == null) { // Use lazy initialization with double-checked 
locking
-                synchronized (HBaseLogin.class) {
-                    if (ugi == null) {
-                        LOG.info("Login with Kerberos. User={}, keytab={}", 
config.getPrincipal(), config.getKeytab());
-                        
UserGroupInformation.loginUserFromKeytab(config.getPrincipal(), 
config.getKeytab());
-                        ugi = UserGroupInformation.getCurrentUser();
+    @Nullable
+    public static UserGroupInformation loginIfNeeded(SecureHBaseConfig config, 
Configuration hbaseConf) throws IOException {
+        boolean credsProvided = null != config.getPrincipal() && null != 
config.getKeytab();
+        if (UserGroupInformation.isSecurityEnabled() && credsProvided) {
+            // Check if we need to authenticate with kerberos so that we cache 
the correct ConnectionInfo
+            UserGroupInformation currentUser = 
UserGroupInformation.getCurrentUser();
+            if (!currentUser.hasKerberosCredentials() || 
!isSameName(currentUser.getUserName(), config.getPrincipal())) {
+                synchronized (KERBEROS_LOGIN_LOCK) {
+                    // Double check the current user, might have changed since 
we checked last. Don't want
+                    // to re-login if it's the same user.
+                    currentUser = UserGroupInformation.getCurrentUser();
+                    if (!currentUser.hasKerberosCredentials() || 
!isSameName(currentUser.getUserName(), config.getPrincipal())) {
+                        final Configuration hbaseConfig = 
getConfiguration(hbaseConf, config.getPrincipal(), config.getKeytab());
+                        LOG.info("Trying to connect to a secure cluster as {} 
" +
+                                        "with keytab {}",
+                                
hbaseConfig.get(SecureHBaseConfig.HBASE_CLIENT_PRINCIPAL_KEY),
+                                
hbaseConfig.get(SecureHBaseConfig.HBASE_CLIENT_KEYTAB_KEY));
+                        UserGroupInformation.setConfiguration(hbaseConfig);
+                        User.login(hbaseConfig, 
SecureHBaseConfig.HBASE_CLIENT_KEYTAB_KEY, 
SecureHBaseConfig.HBASE_CLIENT_PRINCIPAL_KEY, null);
+                        LOG.info("Successful login to secure cluster");
                     }
                 }
             } else {
-                LOG.info("User {}, already trusted (Kerberos). Avoiding 2nd 
login as it causes problems", ugi.toString());
+                // The user already has Kerberos creds, so there isn't 
anything to change in the ConnectionInfo.
+                LOG.debug("Already logged in as {}", currentUser);
             }
         } else {
             LOG.warn("Security NOT enabled when connecting to HBase. Act at 
your own risk. NULL UGI returned");
@@ -52,4 +72,56 @@ public final class HBaseLogin {
         return ugi;
     }
 
+    static boolean isSameName(String currentName, String newName, String 
hostname, String defaultRealm) throws IOException {
+        final boolean newNameContainsRealm = newName.indexOf('@') != -1;
+        // Make sure to replace "_HOST" if it exists before comparing the 
principals.
+        if 
(newName.contains(org.apache.hadoop.security.SecurityUtil.HOSTNAME_PATTERN)) {
+            if (newNameContainsRealm) {
+                newName = 
org.apache.hadoop.security.SecurityUtil.getServerPrincipal(newName, hostname);
+            } else {
+                // If the principal ends with "/_HOST", replace "_HOST" with 
the hostname.
+                if (newName.endsWith("/_HOST")) {
+                    newName = newName.substring(0, newName.length() - 5) + 
hostname;
+                }
+            }
+        }
+        // The new name doesn't contain a realm and we could compute a default 
realm
+        if (!newNameContainsRealm && defaultRealm != null) {
+            return currentName.equals(newName + "@" + defaultRealm);
+        }
+        // We expect both names to contain a realm, so we can do a simple 
equality check
+        return currentName.equals(newName);
+    }
+
+    static boolean isSameName(String currentName, String newName) throws 
IOException {
+        return isSameName(currentName, newName, null, 
getDefaultKerberosRealm());
+    }
+
+    /**
+     * Computes the default kerberos realm if one is available. If one cannot 
be computed, null
+     * is returned.
+     *
+     * @return The default kerberos realm, or null.
+     */
+    static String getDefaultKerberosRealm() {
+        try {
+            return KerberosUtil.getDefaultRealm();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private static Configuration getConfiguration(Configuration conf, String 
principal, String keytab) {
+        if(conf == null) {
+            conf = HBaseConfiguration.create();
+        }
+        // Set the principal and keytab if provided from the URL (overriding 
those provided in Properties)
+        if (null != principal) {
+            conf.set(SecureHBaseConfig.HBASE_CLIENT_PRINCIPAL_KEY, principal);
+        }
+        if (null != keytab) {
+            conf.set(SecureHBaseConfig.HBASE_CLIENT_KEYTAB_KEY, keytab);
+        }
+        return conf;
+    }
 }
diff --git 
a/hbase-tools/src/main/java/org/apache/omid/tools/hbase/OmidTableManager.java 
b/hbase-tools/src/main/java/org/apache/omid/tools/hbase/OmidTableManager.java
index 8e25530..104f2e8 100644
--- 
a/hbase-tools/src/main/java/org/apache/omid/tools/hbase/OmidTableManager.java
+++ 
b/hbase-tools/src/main/java/org/apache/omid/tools/hbase/OmidTableManager.java
@@ -78,8 +78,11 @@ public class OmidTableManager {
     }
 
     public void executeActionsOnHBase(Configuration hbaseConf) throws 
IOException {
-
-        HBaseLogin.loginIfNeeded(mainConfig.loginFlags);
+        mainConfig.loginFlags.setPrincipal(
+                hbaseConf.get(SecureHBaseConfig.HBASE_CLIENT_PRINCIPAL_KEY));
+        mainConfig.loginFlags.setKeytab(
+                hbaseConf.get(SecureHBaseConfig.HBASE_CLIENT_KEYTAB_KEY));
+        HBaseLogin.loginIfNeeded(mainConfig.loginFlags, hbaseConf);
 
         try (Connection conn = ConnectionFactory.createConnection(hbaseConf);
              Admin hBaseAdmin = conn.getAdmin()) {

Reply via email to