You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ra...@apache.org on 2021/02/10 09:41:35 UTC
[phoenix-omid] branch master updated: OMID-194 OmidTableManager
cannot create commit and timestamp tables in kerberos cluster(Rajeshbabu)
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 <ra...@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()) {