From 5f9ee7d0e0fdd9d71a7105f499e2b8eb39e1568e Mon Sep 17 00:00:00 2001 From: chenheng Date: Fri, 21 Aug 2015 14:10:28 +0800 Subject: [PATCH] HBASE-14265 we should forbid creating table using 'hbase' namespace except by superuser --- .../hadoop/hbase/SystemNamespaceAccessException.java | 13 +++++++++++++ .../src/main/java/org/apache/hadoop/hbase/TableName.java | 4 ++++ .../main/java/org/apache/hadoop/hbase/master/HMaster.java | 12 ++++++++++++ .../java/org/apache/hadoop/hbase/client/TestAdmin1.java | 15 +++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/SystemNamespaceAccessException.java diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/SystemNamespaceAccessException.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/SystemNamespaceAccessException.java new file mode 100644 index 0000000..179086a --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/SystemNamespaceAccessException.java @@ -0,0 +1,13 @@ +package org.apache.hadoop.hbase; + +/** + * Thrown if user create/delete table under System Namespace + */ +public class SystemNamespaceAccessException extends DoNotRetryIOException { + + public SystemNamespaceAccessException() {} + + public SystemNamespaceAccessException(String msg) { + super(msg); + } +} diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java index 63066b3..77a907d 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java @@ -270,6 +270,10 @@ public final class TableName implements Comparable { return systemTable; } + public boolean isSystemNamespace() { + return Bytes.equals(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME, namespace); + } + @Override public String toString() { return nameAsString; diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java index ca721e2..517a35e 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java @@ -73,6 +73,7 @@ import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableNotDisabledException; import org.apache.hadoop.hbase.TableNotFoundException; import org.apache.hadoop.hbase.UnknownRegionException; +import org.apache.hadoop.hbase.SystemNamespaceAccessException; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.client.RegionReplicaUtil; import org.apache.hadoop.hbase.client.Result; @@ -82,6 +83,7 @@ import org.apache.hadoop.hbase.exceptions.DeserializationException; import org.apache.hadoop.hbase.executor.ExecutorType; import org.apache.hadoop.hbase.ipc.RpcServer; import org.apache.hadoop.hbase.ipc.ServerNotRunningYetException; +import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.master.MasterRpcServices.BalanceSwitchMode; import org.apache.hadoop.hbase.master.balancer.BalancerChore; import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer; @@ -125,6 +127,7 @@ import org.apache.hadoop.hbase.regionserver.RSRpcServices; import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost; import org.apache.hadoop.hbase.regionserver.RegionSplitPolicy; import org.apache.hadoop.hbase.replication.regionserver.Replication; +import org.apache.hadoop.hbase.security.Superusers; import org.apache.hadoop.hbase.security.UserProvider; import org.apache.hadoop.hbase.util.Addressing; import org.apache.hadoop.hbase.util.Bytes; @@ -1453,6 +1456,15 @@ public class HMaster extends HRegionServer implements MasterServices, Server { String namespace = hTableDescriptor.getTableName().getNamespaceAsString(); ensureNamespaceExists(namespace); + User activeUser = RpcServer.getRequestUser(); + if (activeUser == null) { + activeUser = User.getCurrent(); + } + if (hTableDescriptor.getTableName().isSystemNamespace() + && !Superusers.isSuperUser(activeUser)) { + throw new SystemNamespaceAccessException("Can't create table under system namespace 'hbase'!"); + } + HRegionInfo[] newRegions = ModifyRegionUtils.createHRegionInfos(hTableDescriptor, splitKeys); checkInitialized(); sanityCheckTableDescriptor(hTableDescriptor); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java index 33c151d..c751122 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java @@ -40,6 +40,7 @@ import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.HRegionLocation; import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.NamespaceDescriptor; import org.apache.hadoop.hbase.InvalidFamilyOperationException; import org.apache.hadoop.hbase.MasterNotRunningException; import org.apache.hadoop.hbase.MetaTableAccessor; @@ -48,8 +49,10 @@ import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableNotDisabledException; import org.apache.hadoop.hbase.TableNotEnabledException; import org.apache.hadoop.hbase.TableNotFoundException; +import org.apache.hadoop.hbase.SystemNamespaceAccessException; import org.apache.hadoop.hbase.ZooKeeperConnectionException; import org.apache.hadoop.hbase.exceptions.MergeRegionException; +import org.apache.hadoop.hbase.ipc.RpcServer; import org.apache.hadoop.hbase.master.HMaster; import org.apache.hadoop.hbase.protobuf.ProtobufUtil; import org.apache.hadoop.hbase.protobuf.RequestConverter; @@ -927,6 +930,18 @@ public class TestAdmin1 { } } + @Test (timeout = 300000) + public void testCreateTableInSystemNamespace() throws IOException { + TableName tableName = TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME, + Bytes.toBytes("testCreateTableInSystemNamespace")); + try { + admin.createTable(new HTableDescriptor(tableName)); + fail("Test case should fail as create table under system namespace."); + } catch (SystemNamespaceAccessException e) { + LOG.info("Expected ", e); + } + } + @Test (timeout=120000) public void testTableExist() throws IOException { final TableName table = TableName.valueOf("testTableExist"); -- 1.9.3 (Apple Git-50)