You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ap...@apache.org on 2016/02/04 01:29:49 UTC
[5/6] hbase git commit: HBASE-15200 ZooKeeper znode ACL checks should
only compare the shortname
HBASE-15200 ZooKeeper znode ACL checks should only compare the shortname
Conflicts:
hbase-client/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/15db2244
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/15db2244
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/15db2244
Branch: refs/heads/branch-1.1
Commit: 15db2244e15647b94155293127828c4d0bad1c6d
Parents: 0ca1cac
Author: Andrew Purtell <ap...@apache.org>
Authored: Mon Feb 1 09:48:16 2016 -0800
Committer: Andrew Purtell <ap...@apache.org>
Committed: Wed Feb 3 15:11:19 2016 -0800
----------------------------------------------------------------------
.../hbase/zookeeper/ZooKeeperWatcher.java | 80 ++++++++++++++++++--
1 file changed, 74 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/15db2244/hbase-client/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java
index 4dffcd3..08a089c 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java
@@ -26,12 +26,16 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
+import org.apache.hadoop.hbase.security.Superusers;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Abortable;
+import org.apache.hadoop.hbase.AuthUtil;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
@@ -131,6 +135,9 @@ public class ZooKeeperWatcher implements Watcher, Abortable, Closeable {
private final Exception constructorCaller;
+ /* A pattern that matches a Kerberos name, borrowed from Hadoop's KerberosName */
+ private static final Pattern NAME_PATTERN = Pattern.compile("([^/@]*)(/([^/@]*))?@([^/@]*)");
+
/**
* Instantiate a ZooKeeper connection and watcher.
* @param identifier string that is passed to RecoverableZookeeper to be used as
@@ -223,6 +230,7 @@ public class ZooKeeperWatcher implements Watcher, Abortable, Closeable {
*/
public void checkAndSetZNodeAcls() {
if (!ZKUtil.isSecureZooKeeper(getConfiguration())) {
+ LOG.info("not a secure deployment, proceeding");
return;
}
@@ -267,13 +275,23 @@ public class ZooKeeperWatcher implements Watcher, Abortable, Closeable {
* @throws IOException
*/
private boolean isBaseZnodeAclSetup(List<ACL> acls) throws IOException {
- String superUser = conf.get("hbase.superuser");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checking znode ACLs");
+ }
+ String[] superUsers = conf.getStrings(Superusers.SUPERUSER_CONF_KEY);
+ // Check whether ACL set for all superusers
+ if (superUsers != null && !checkACLForSuperUsers(superUsers, acls)) {
+ return false;
+ }
// this assumes that current authenticated user is the same as zookeeper client user
// configured via JAAS
String hbaseUser = UserGroupInformation.getCurrentUser().getShortUserName();
if (acls.isEmpty()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("ACL is empty");
+ }
return false;
}
@@ -284,23 +302,73 @@ public class ZooKeeperWatcher implements Watcher, Abortable, Closeable {
// and one for the hbase user
if (Ids.ANYONE_ID_UNSAFE.equals(id)) {
if (perms != Perms.READ) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String.format("permissions for '%s' are not correct: have %0x, want %0x",
+ id, perms, Perms.READ));
+ }
return false;
}
- } else if (superUser != null && new Id("sasl", superUser).equals(id)) {
- if (perms != Perms.ALL) {
- return false;
+ } else if ("sasl".equals(id.getScheme())) {
+ String name = id.getId();
+ // If ZooKeeper recorded the Kerberos full name in the ACL, use only the shortname
+ Matcher match = NAME_PATTERN.matcher(name);
+ if (match.matches()) {
+ name = match.group(1);
}
- } else if (new Id("sasl", hbaseUser).equals(id)) {
- if (perms != Perms.ALL) {
+ if (name.equals(hbaseUser)) {
+ if (perms != Perms.ALL) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String.format("permissions for '%s' are not correct: have %0x, want %0x",
+ id, perms, Perms.ALL));
+ }
+ return false;
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Unexpected shortname in SASL ACL: " + id);
+ }
return false;
}
} else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("unexpected ACL id '" + id + "'");
+ }
return false;
}
}
return true;
}
+ /*
+ * Validate whether ACL set for all superusers.
+ */
+ private boolean checkACLForSuperUsers(String[] superUsers, List<ACL> acls) {
+ for (String user : superUsers) {
+ boolean hasAccess = false;
+ // TODO: Validate super group members also when ZK supports setting node ACL for groups.
+ if (!user.startsWith(AuthUtil.GROUP_PREFIX)) {
+ for (ACL acl : acls) {
+ if (user.equals(acl.getId().getId())) {
+ if (acl.getPerms() == Perms.ALL) {
+ hasAccess = true;
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String.format(
+ "superuser '%s' does not have correct permissions: have %0x, want %0x",
+ acl.getId().getId(), acl.getPerms(), Perms.ALL));
+ }
+ }
+ break;
+ }
+ }
+ if (!hasAccess) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
@Override
public String toString() {
return this.identifier + ", quorum=" + quorum + ", baseZNode=" + baseZNode;