diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlClient.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlClient.java index 6a743da409f..cefe48ca332 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlClient.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlClient.java @@ -26,6 +26,7 @@ import java.util.regex.Pattern; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseIOException; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.MasterNotRunningException; @@ -49,6 +50,8 @@ import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.GrantRespo import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.RevokeRequest; import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.RevokeResponse; import org.apache.hadoop.hbase.util.ByteStringer; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.security.authorize.AccessControlList; import com.google.protobuf.ByteString; @@ -216,22 +219,25 @@ public class AccessControlClient { Table ht = null; Admin ha = null; try { - TableName aclTableName = - TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "acl"); + TableName aclTableName = TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, + "acl"); ha = new HBaseAdmin(conf); ht = new HTable(conf, aclTableName); CoprocessorRpcChannel service = ht.coprocessorService(HConstants.EMPTY_START_ROW); - BlockingInterface protocol = - AccessControlProtos.AccessControlService.newBlockingStub(service); + BlockingInterface protocol = AccessControlProtos.AccessControlService + .newBlockingStub(service); HTableDescriptor[] htds = null; - - if (tableRegex != null) { + + if (tableRegex == null) { + permList = ProtobufUtil.getUserPermissions(protocol); + } else if (tableRegex.charAt(0) == '@') { + String namespace = tableRegex.substring(1); + permList = ProtobufUtil.getUserPermissions(protocol, Bytes.toBytes(namespace)); + } else { htds = ha.listTables(Pattern.compile(tableRegex)); - for (HTableDescriptor hd: htds) { + for (HTableDescriptor hd : htds) { permList.addAll(ProtobufUtil.getUserPermissions(protocol, hd.getTableName())); } - } else { - permList = ProtobufUtil.getUserPermissions(protocol); } } finally { if (ht != null) { diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java index 3ed58ccffe9..d2edeb9b5ba 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java @@ -43,6 +43,8 @@ import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.MiniHBaseCluster; +import org.apache.hadoop.hbase.NamespaceDescriptor; +import org.apache.hadoop.hbase.NamespaceDescriptor.Builder; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableNotFoundException; @@ -77,6 +79,7 @@ import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.NoopRes import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.PingRequest; import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.PingResponse; import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.PingService; +import org.apache.hadoop.hbase.exceptions.HBaseException; import org.apache.hadoop.hbase.io.hfile.CacheConfig; import org.apache.hadoop.hbase.io.hfile.HFile; import org.apache.hadoop.hbase.io.hfile.HFileContext; @@ -2304,4 +2307,21 @@ public class TestAccessController extends SecureTestUtil { verifyAllowed(setNamespaceQuotaAction, SUPERUSER, USER_ADMIN); verifyDenied(setNamespaceQuotaAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); } + + @Test + public void testGetNamespacePermission() throws Exception { + String namespace = "testNamespace"; + NamespaceDescriptor desc = NamespaceDescriptor.create(namespace).build(); + TEST_UTIL.getMiniHBaseCluster().getMaster().createNamespace(desc); + grantOnNamespace(TEST_UTIL, USER_NONE.getShortName(), namespace, Permission.Action.READ); + try { + List namespacePermissions = AccessControlClient.getUserPermissions(conf, + AccessControlLists.toNamespaceEntry(namespace)); + assertTrue(namespacePermissions != null); + assertTrue(namespacePermissions.size() == 1); + } catch (Throwable thw) { + throw new HBaseException(thw); + } + TEST_UTIL.getMiniHBaseCluster().getMaster().deleteNamespace(namespace); + } } diff --git a/hbase-shell/src/main/ruby/hbase/security.rb b/hbase-shell/src/main/ruby/hbase/security.rb index 1c4d9ae0c47..1361c19707f 100644 --- a/hbase-shell/src/main/ruby/hbase/security.rb +++ b/hbase-shell/src/main/ruby/hbase/security.rb @@ -156,6 +156,11 @@ module Hbase count = 0 all_perms.each do |value| user_name = String.from_java_bytes(value.getUser) + if (isNamespace?(table_regex)) + namespace = table_regex[1...table_regex.length] + else + namespace = (value.getTableName != nil) ? value.getTableName.getNamespaceAsString() : '' + end table = (value.getTableName != nil) ? value.getTableName.getNameAsString() : '' family = (value.getFamily != nil) ? org.apache.hadoop.hbase.util.Bytes::toStringBinary(value.getFamily) : @@ -167,7 +172,7 @@ module Hbase action = org.apache.hadoop.hbase.security.access.Permission.new value.getActions if block_given? - yield(user_name, "#{table},#{family},#{qualifier}: #{action.to_s}") + yield(user_name, "#{namespace},#{table},#{family},#{qualifier}: #{action.to_s}") else res[user_name] ||= {} res[user_name][family + ":" +qualifier] = action