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 e19c23c372e..e8675a2fc9b 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 @@ -18,18 +18,24 @@ package org.apache.hadoop.hbase.security.access; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Map; +import java.util.regex.Pattern; import com.google.protobuf.HBaseZeroCopyByteString; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.NamespaceDescriptor; import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.coprocessor.Batch; import org.apache.hadoop.hbase.ipc.BlockingRpcCallback; +import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; import org.apache.hadoop.hbase.ipc.ServerRpcController; import org.apache.hadoop.hbase.protobuf.ProtobufUtil; import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos; @@ -38,6 +44,7 @@ import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.GrantReque import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.GrantResponse; import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.RevokeRequest; import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.RevokeResponse; +import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService.BlockingInterface; import com.google.protobuf.ByteString; @@ -176,4 +183,46 @@ public class AccessControlClient { } } } + + /** + * List all the userPermissions matching the given pattern. + * @param conf + * @param tableRegex The regular expression string to match against + * @return - returns an array of UserPermissions + * @throws Throwable + */ + public static List getUserPermissions(Configuration conf, String tableRegex) + throws Throwable { + List permList = new ArrayList(); + HTable ht = null; + HBaseAdmin ha = null; + try { + TableName aclTableName = + TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "acl"); + ha = new HBaseAdmin(conf); + ht = new HTable(conf, aclTableName.getName()); + CoprocessorRpcChannel service = ht.coprocessorService(HConstants.EMPTY_START_ROW); + BlockingInterface protocol = + AccessControlProtos.AccessControlService.newBlockingStub(service); + HTableDescriptor[] htds = null; + + if (tableRegex != null) { + htds = ha.listTables(Pattern.compile(tableRegex)); + for (HTableDescriptor hd: htds) { + permList.addAll(ProtobufUtil.getUserPermissions(protocol, hd.getTableName())); + } + } else { + permList = ProtobufUtil.getUserPermissions(protocol); + } + } finally { + if (ht != null) { + ht.close(); + } + if (ha != null) { + ha.close(); + } + } + return permList; + } + } 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 a0ccf2e3d5c..cf503108636 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 @@ -95,6 +95,7 @@ import org.apache.hadoop.hbase.security.access.Permission.Action; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.JVMClusterUtil; import org.apache.hadoop.hbase.util.TestTableName; +import org.apache.hadoop.hbase.security.access.AccessControlClient; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.junit.After; @@ -243,6 +244,11 @@ public class TestAccessController extends SecureTestUtil { Permission.Action.READ); assertEquals(4, AccessControlLists.getTablePermissions(conf, TEST_TABLE.getTableName()).size()); + try { + assertEquals(4, AccessControlClient.getUserPermissions(conf, TEST_TABLE.toString()).size()); + } catch (Throwable e) { + LOG.error("error during call of AccessControlClient.getUserPermissions. " + e.getStackTrace()); + } } @After diff --git a/hbase-shell/src/main/ruby/hbase/security.rb b/hbase-shell/src/main/ruby/hbase/security.rb index 5d155c8e3a5..1c4d9ae0c47 100644 --- a/hbase-shell/src/main/ruby/hbase/security.rb +++ b/hbase-shell/src/main/ruby/hbase/security.rb @@ -151,60 +151,10 @@ module Hbase #---------------------------------------------------------------------------------------------- def user_permission(table_regex=nil) security_available? - - begin - meta_table = org.apache.hadoop.hbase.client.HTable.new(@config, - org.apache.hadoop.hbase.security.access.AccessControlLists::ACL_TABLE_NAME) - service = meta_table.coprocessorService( - org.apache.hadoop.hbase.HConstants::EMPTY_START_ROW) - - protocol = org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos:: - AccessControlService.newBlockingStub(service) - - if (table_regex == '') - table_regex = nil - end - - # handle simple glob '*' but if '.' is passed before '*' then assume regex - if /\*/.match(table_regex) && !/\.\*/.match(table_regex) - table_regex = table_regex.gsub(/\*/, '.*') - end - - all_perms = [] - tables = [] - - if table_regex != nil - - htds = @admin.listTables(table_regex) - htds.each { |t| - tables << t.getTableName().toString() - } - - tables.each { |t| - if (isNamespace?(t)) - # Namespace should exist first. - namespace_name = t[1...t.length] - raise(ArgumentError, "Can't find a namespace: #{namespace_name}") unless namespace_exists?(namespace_name) - perms = org.apache.hadoop.hbase.protobuf.ProtobufUtil.getUserPermissions( - protocol, org.apache.hadoop.hbase.TableName.valueOf(t)) - else - raise(ArgumentError, "Can't find table: #{t}") unless exists?(t) - perms = org.apache.hadoop.hbase.protobuf.ProtobufUtil.getUserPermissions( - protocol, org.apache.hadoop.hbase.TableName.valueOf(t)) - end - all_perms << perms - } - else - perms = org.apache.hadoop.hbase.protobuf.ProtobufUtil.getUserPermissions(protocol) - all_perms << perms - end - ensure - meta_table.close() - end + all_perms = org.apache.hadoop.hbase.security.access.AccessControlClient.getUserPermissions(@config,table_regex) res = {} count = 0 - all_perms.each do |this_perms| - this_perms.each do |value| + all_perms.each do |value| user_name = String.from_java_bytes(value.getUser) table = (value.getTableName != nil) ? value.getTableName.getNameAsString() : '' family = (value.getFamily != nil) ? @@ -223,7 +173,6 @@ module Hbase res[user_name][family + ":" +qualifier] = action end count += 1 - end end return ((block_given?) ? count : res) diff --git a/hbase-shell/src/main/ruby/shell/commands/user_permission.rb b/hbase-shell/src/main/ruby/shell/commands/user_permission.rb index 1c416e50f42..7c292613f6c 100644 --- a/hbase-shell/src/main/ruby/shell/commands/user_permission.rb +++ b/hbase-shell/src/main/ruby/shell/commands/user_permission.rb @@ -28,18 +28,18 @@ For example: hbase> user_permission hbase> user_permission 'table1' hbase> user_permission 'namespace1:table1' - hbase> user_permission '*' + hbase> user_permission '.*' hbase> user_permission '^[A-C].*' EOF end - def command(table=nil) + def command(table_regex=".*") #format_simple_command do - #admin.user_permission(table) + #admin.user_permission(table_regex) now = Time.now formatter.header(["User", "Table,Family,Qualifier:Permission"]) - count = security_admin.user_permission(table) do |user, permission| + count = security_admin.user_permission(table_regex) do |user, permission| formatter.row([ user, permission]) end