You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by zg...@apache.org on 2019/01/30 03:29:41 UTC
[hbase] branch master updated: HBASE-21739 Move grant/revoke from
regionserver to master
This is an automated email from the ASF dual-hosted git repository.
zghao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/master by this push:
new f997252 HBASE-21739 Move grant/revoke from regionserver to master
f997252 is described below
commit f99725234464612d14eaa3b4d043d4291026c622
Author: meiyi <my...@gamil.com>
AuthorDate: Tue Jan 29 19:52:50 2019 +0800
HBASE-21739 Move grant/revoke from regionserver to master
Signed-off-by: Guanghao Zhang <zg...@apache.org>
---
.../java/org/apache/hadoop/hbase/client/Admin.java | 20 +++
.../org/apache/hadoop/hbase/client/AsyncAdmin.java | 16 +++
.../hadoop/hbase/client/AsyncHBaseAdmin.java | 12 ++
.../hbase/client/ConnectionImplementation.java | 13 ++
.../org/apache/hadoop/hbase/client/HBaseAdmin.java | 30 +++++
.../hadoop/hbase/client/RawAsyncHBaseAdmin.java | 25 ++++
.../hbase/client/ShortCircuitMasterConnection.java | 17 +++
.../hbase/security/access/AccessControlClient.java | 58 +++------
.../hbase/security/access/AccessControlUtil.java | 13 ++
.../security/access/ShadedAccessControlUtil.java | 130 +++++++++++---------
.../src/main/protobuf/Master.proto | 5 +
.../hadoop/hbase/coprocessor/MasterObserver.java | 39 ++++++
.../hadoop/hbase/master/MasterCoprocessorHost.java | 39 ++++++
.../hadoop/hbase/master/MasterRpcServices.java | 52 ++++++++
.../hbase/security/access/AccessControlLists.java | 4 +-
.../hbase/security/access/AccessController.java | 107 +++++++---------
.../hbase/security/access/SecureTestUtil.java | 49 ++------
.../security/access/TestAccessController.java | 88 ++++++++++---
.../security/access/TestNamespaceCommands.java | 136 ++++++++++++---------
.../hadoop/hbase/thrift2/client/ThriftAdmin.java | 11 ++
20 files changed, 599 insertions(+), 265 deletions(-)
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java
index 5a05859..f80a460 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java
@@ -53,6 +53,7 @@ import org.apache.hadoop.hbase.replication.ReplicationException;
import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
import org.apache.hadoop.hbase.replication.ReplicationPeerDescription;
import org.apache.hadoop.hbase.replication.SyncReplicationState;
+import org.apache.hadoop.hbase.security.access.UserPermission;
import org.apache.hadoop.hbase.snapshot.HBaseSnapshotException;
import org.apache.hadoop.hbase.snapshot.RestoreSnapshotException;
import org.apache.hadoop.hbase.snapshot.SnapshotCreationException;
@@ -2833,4 +2834,23 @@ public interface Admin extends Abortable, Closeable {
* no quota information on that table.
*/
SpaceQuotaSnapshotView getCurrentSpaceQuotaSnapshot(TableName tableName) throws IOException;
+
+ /**
+ * Grants user specific permissions
+ *
+ * @param userPermission user and permissions
+ * @param mergeExistingPermissions If set to false, later granted permissions will override
+ * previous granted permissions. otherwise, it'll merge with previous granted
+ * permissions.
+ * @throws IOException if a remote or network exception occurs
+ */
+ void grant(UserPermission userPermission, boolean mergeExistingPermissions) throws IOException;
+
+ /**
+ * Revokes user specific permissions
+ *
+ * @param userPermission user and permissions
+ * @throws IOException if a remote or network exception occurs
+ */
+ void revoke(UserPermission userPermission) throws IOException;
}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java
index 13e8195..3a5aef1 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java
@@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshotView;
import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
import org.apache.hadoop.hbase.replication.ReplicationPeerDescription;
import org.apache.hadoop.hbase.replication.SyncReplicationState;
+import org.apache.hadoop.hbase.security.access.UserPermission;
import org.apache.yetus.audience.InterfaceAudience;
/**
@@ -1324,4 +1325,19 @@ public interface AsyncAdmin {
*/
CompletableFuture<? extends SpaceQuotaSnapshotView> getCurrentSpaceQuotaSnapshot(
TableName tableName);
+
+ /**
+ * Grants user specific permissions
+ * @param userPermission user and permissions
+ * @param mergeExistingPermissions If set to false, later granted permissions will override
+ * previous granted permissions. otherwise, it'll merge with previous granted
+ * permissions.
+ */
+ CompletableFuture<Void> grant(UserPermission userPermission, boolean mergeExistingPermissions);
+
+ /**
+ * Revokes user specific permissions
+ * @param userPermission user and permissions
+ */
+ CompletableFuture<Void> revoke(UserPermission userPermission);
}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java
index edcf0dc..356a425 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java
@@ -42,6 +42,7 @@ import org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshot;
import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
import org.apache.hadoop.hbase.replication.ReplicationPeerDescription;
import org.apache.hadoop.hbase.replication.SyncReplicationState;
+import org.apache.hadoop.hbase.security.access.UserPermission;
import org.apache.yetus.audience.InterfaceAudience;
/**
@@ -796,4 +797,15 @@ class AsyncHBaseAdmin implements AsyncAdmin {
public CompletableFuture<SpaceQuotaSnapshot> getCurrentSpaceQuotaSnapshot(TableName tableName) {
return wrap(rawAdmin.getCurrentSpaceQuotaSnapshot(tableName));
}
+
+ @Override
+ public CompletableFuture<Void> grant(UserPermission userPermission,
+ boolean mergeExistingPermissions) {
+ return wrap(rawAdmin.grant(userPermission, mergeExistingPermissions));
+ }
+
+ @Override
+ public CompletableFuture<Void> revoke(UserPermission userPermission) {
+ return wrap(rawAdmin.revoke(userPermission));
+ }
}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java
index 70f0588..5df3c07 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java
@@ -92,6 +92,7 @@ import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ClientService.BlockingInterface;
@@ -1774,6 +1775,18 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
IsRpcThrottleEnabledRequest request) throws ServiceException {
return stub.isRpcThrottleEnabled(controller, request);
}
+
+ @Override
+ public AccessControlProtos.GrantResponse grant(RpcController controller,
+ AccessControlProtos.GrantRequest request) throws ServiceException {
+ return stub.grant(controller, request);
+ }
+
+ @Override
+ public AccessControlProtos.RevokeResponse revoke(RpcController controller,
+ AccessControlProtos.RevokeRequest request) throws ServiceException {
+ return stub.revoke(controller, request);
+ }
};
}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
index d38cc2a..769ddd7 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
@@ -91,6 +91,8 @@ import org.apache.hadoop.hbase.replication.ReplicationException;
import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
import org.apache.hadoop.hbase.replication.ReplicationPeerDescription;
import org.apache.hadoop.hbase.replication.SyncReplicationState;
+import org.apache.hadoop.hbase.security.access.ShadedAccessControlUtil;
+import org.apache.hadoop.hbase.security.access.UserPermission;
import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
import org.apache.hadoop.hbase.snapshot.HBaseSnapshotException;
import org.apache.hadoop.hbase.snapshot.RestoreSnapshotException;
@@ -113,6 +115,8 @@ import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GrantRequest;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.RevokeRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminService;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ClearCompactionQueuesRequest;
@@ -4464,4 +4468,30 @@ public class HBaseAdmin implements Admin {
}
});
}
+
+ @Override
+ public void grant(UserPermission userPermission, boolean mergeExistingPermissions)
+ throws IOException {
+ executeCallable(new MasterCallable<Void>(getConnection(), getRpcControllerFactory()) {
+ @Override
+ protected Void rpcCall() throws Exception {
+ GrantRequest req =
+ ShadedAccessControlUtil.buildGrantRequest(userPermission, mergeExistingPermissions);
+ this.master.grant(getRpcController(), req);
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public void revoke(UserPermission userPermission) throws IOException {
+ executeCallable(new MasterCallable<Void>(getConnection(), getRpcControllerFactory()) {
+ @Override
+ protected Void rpcCall() throws Exception {
+ RevokeRequest req = ShadedAccessControlUtil.buildRevokeRequest(userPermission);
+ this.master.revoke(getRpcController(), req);
+ return null;
+ }
+ });
+ }
}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java
index 914dcc4..73efe32 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java
@@ -82,6 +82,8 @@ import org.apache.hadoop.hbase.replication.ReplicationException;
import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
import org.apache.hadoop.hbase.replication.ReplicationPeerDescription;
import org.apache.hadoop.hbase.replication.SyncReplicationState;
+import org.apache.hadoop.hbase.security.access.ShadedAccessControlUtil;
+import org.apache.hadoop.hbase.security.access.UserPermission;
import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
import org.apache.hadoop.hbase.snapshot.RestoreSnapshotException;
import org.apache.hadoop.hbase.snapshot.SnapshotCreationException;
@@ -101,6 +103,10 @@ import org.apache.hbase.thirdparty.io.netty.util.TimerTask;
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GrantRequest;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GrantResponse;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.RevokeRequest;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.RevokeResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminService;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ClearCompactionQueuesRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ClearCompactionQueuesResponse;
@@ -3712,4 +3718,23 @@ class RawAsyncHBaseAdmin implements AsyncAdmin {
.filter(s -> s.getTableName().equals(protoTableName)).findFirst()
.map(s -> SpaceQuotaSnapshot.toSpaceQuotaSnapshot(s.getSnapshot())).orElse(null));
}
+
+ @Override
+ public CompletableFuture<Void> grant(UserPermission userPermission,
+ boolean mergeExistingPermissions) {
+ return this.<Void> newMasterCaller()
+ .action((controller, stub) -> this.<GrantRequest, GrantResponse, Void> call(controller,
+ stub, ShadedAccessControlUtil.buildGrantRequest(userPermission, mergeExistingPermissions),
+ (s, c, req, done) -> s.grant(c, req, done), resp -> null))
+ .call();
+ }
+
+ @Override
+ public CompletableFuture<Void> revoke(UserPermission userPermission) {
+ return this.<Void> newMasterCaller()
+ .action((controller, stub) -> this.<RevokeRequest, RevokeResponse, Void> call(controller,
+ stub, ShadedAccessControlUtil.buildRevokeRequest(userPermission),
+ (s, c, req, done) -> s.revoke(c, req, done), resp -> null))
+ .call();
+ }
}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java
index 197f98b..02935548 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java
@@ -20,6 +20,11 @@ package org.apache.hadoop.hbase.client;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hbase.thirdparty.com.google.protobuf.RpcController;
import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
+
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GrantRequest;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GrantResponse;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.RevokeRequest;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.RevokeResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.CoprocessorServiceRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.CoprocessorServiceResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AbortProcedureRequest;
@@ -663,4 +668,16 @@ public class ShortCircuitMasterConnection implements MasterKeepAliveConnection {
IsRpcThrottleEnabledRequest request) throws ServiceException {
return stub.isRpcThrottleEnabled(controller, request);
}
+
+ @Override
+ public GrantResponse grant(RpcController controller, GrantRequest request)
+ throws ServiceException {
+ return stub.grant(controller, request);
+ }
+
+ @Override
+ public RevokeResponse revoke(RpcController controller, RevokeRequest request)
+ throws ServiceException {
+ return stub.revoke(controller, request);
+ }
}
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 981db76..1031cfe 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
@@ -94,10 +94,9 @@ public class AccessControlClient {
final String userName, final byte[] family, final byte[] qual, boolean mergeExistingPermissions,
final Permission.Action... actions) throws Throwable {
// TODO: Priority is not used.
- try (Table table = connection.getTable(ACL_TABLE_NAME)) {
- AccessControlUtil.grant(null, getAccessControlServiceStub(table), userName, tableName,
- family, qual, mergeExistingPermissions, actions);
- }
+ UserPermission userPermission =
+ new UserPermission(userName, new TablePermission(tableName, family, qual, actions));
+ connection.getAdmin().grant(userPermission, mergeExistingPermissions);
}
/**
@@ -129,11 +128,9 @@ public class AccessControlClient {
*/
private static void grant(Connection connection, final String namespace, final String userName,
boolean mergeExistingPermissions, final Permission.Action... actions) throws Throwable {
- // TODO: Pass an rpcController.
- try (Table table = connection.getTable(ACL_TABLE_NAME)) {
- AccessControlUtil.grant(null, getAccessControlServiceStub(table), userName, namespace,
- mergeExistingPermissions, actions);
- }
+ UserPermission userPermission =
+ new UserPermission(userName, new NamespacePermission(namespace, actions));
+ connection.getAdmin().grant(userPermission, mergeExistingPermissions);
}
/**
@@ -152,7 +149,7 @@ public class AccessControlClient {
}
/**
- * Grants permission on the specified namespace for the specified user.
+ * Grant global permissions for the specified user.
* @param connection
* @param userName
* @param mergeExistingPermissions If set to false, later granted permissions will override
@@ -163,11 +160,8 @@ public class AccessControlClient {
*/
private static void grant(Connection connection, final String userName,
boolean mergeExistingPermissions, final Permission.Action... actions) throws Throwable {
- // TODO: Pass an rpcController
- try (Table table = connection.getTable(ACL_TABLE_NAME)) {
- AccessControlUtil.grant(null, getAccessControlServiceStub(table), userName,
- mergeExistingPermissions, actions);
- }
+ UserPermission userPermission = new UserPermission(userName, new GlobalPermission(actions));
+ connection.getAdmin().grant(userPermission, mergeExistingPermissions);
}
/**
@@ -204,19 +198,13 @@ public class AccessControlClient {
public static void revoke(Connection connection, final TableName tableName,
final String username, final byte[] family, final byte[] qualifier,
final Permission.Action... actions) throws Throwable {
- /** TODO: Pass an rpcController
- HBaseRpcController controller
- = ((ClusterConnection) connection).getRpcControllerFactory().newController();
- controller.setPriority(tableName);
- */
- try (Table table = connection.getTable(ACL_TABLE_NAME)) {
- AccessControlUtil.revoke(null, getAccessControlServiceStub(table), username, tableName,
- family, qualifier, actions);
- }
+ UserPermission userPermission =
+ new UserPermission(username, new TablePermission(tableName, family, qualifier, actions));
+ connection.getAdmin().revoke(userPermission);
}
/**
- * Revokes the permission on the table for the specified user.
+ * Revokes the permission on the namespace for the specified user.
* @param connection The Connection instance to use
* @param namespace
* @param userName
@@ -225,14 +213,9 @@ public class AccessControlClient {
*/
public static void revoke(Connection connection, final String namespace,
final String userName, final Permission.Action... actions) throws Throwable {
- /** TODO: Pass an rpcController
- HBaseRpcController controller
- = ((ClusterConnection) connection).getRpcControllerFactory().newController();
- */
- try (Table table = connection.getTable(ACL_TABLE_NAME)) {
- AccessControlUtil.revoke(null, getAccessControlServiceStub(table), userName, namespace,
- actions);
- }
+ UserPermission userPermission =
+ new UserPermission(userName, new NamespacePermission(namespace, actions));
+ connection.getAdmin().revoke(userPermission);
}
/**
@@ -241,13 +224,8 @@ public class AccessControlClient {
*/
public static void revoke(Connection connection, final String userName,
final Permission.Action... actions) throws Throwable {
- /** TODO: Pass an rpc controller.
- HBaseRpcController controller
- = ((ClusterConnection) connection).getRpcControllerFactory().newController();
- */
- try (Table table = connection.getTable(ACL_TABLE_NAME)) {
- AccessControlUtil.revoke(null, getAccessControlServiceStub(table), userName, actions);
- }
+ UserPermission userPermission = new UserPermission(userName, new GlobalPermission(actions));
+ connection.getAdmin().revoke(userPermission);
}
/**
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlUtil.java
index b37440c..4bae943 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlUtil.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlUtil.java
@@ -25,6 +25,7 @@ import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Admin;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
@@ -490,7 +491,9 @@ public class AccessControlUtil {
* @param userShortName the short name of the user to grant permissions
* @param actions the permissions to be granted
* @throws ServiceException
+ * @deprecated Use {@link Admin#grant(UserPermission, boolean)} instead.
*/
+ @Deprecated
public static void grant(RpcController controller,
AccessControlService.BlockingInterface protocol, String userShortName, boolean mergeExistingPermissions,
Permission.Action... actions) throws ServiceException {
@@ -517,7 +520,9 @@ public class AccessControlUtil {
* @param q optional qualifier
* @param actions the permissions to be granted
* @throws ServiceException
+ * @deprecated Use {@link Admin#grant(UserPermission, boolean)} instead.
*/
+ @Deprecated
public static void grant(RpcController controller,
AccessControlService.BlockingInterface protocol, String userShortName, TableName tableName,
byte[] f, byte[] q, boolean mergeExistingPermissions, Permission.Action... actions)
@@ -543,7 +548,9 @@ public class AccessControlUtil {
* @param namespace the short name of the user to grant permissions
* @param actions the permissions to be granted
* @throws ServiceException
+ * @deprecated Use {@link Admin#grant(UserPermission, boolean)} instead.
*/
+ @Deprecated
public static void grant(RpcController controller,
AccessControlService.BlockingInterface protocol, String userShortName, String namespace,
boolean mergeExistingPermissions, Permission.Action... actions) throws ServiceException {
@@ -567,7 +574,9 @@ public class AccessControlUtil {
* @param userShortName the short name of the user to revoke permissions
* @param actions the permissions to be revoked
* @throws ServiceException on failure
+ * @deprecated Use {@link Admin#grant(UserPermission, boolean)} instead.
*/
+ @Deprecated
public static void revoke(RpcController controller,
AccessControlService.BlockingInterface protocol, String userShortName,
Permission.Action... actions) throws ServiceException {
@@ -595,7 +604,9 @@ public class AccessControlUtil {
* @param q optional qualifier
* @param actions the permissions to be revoked
* @throws ServiceException on failure
+ * @deprecated Use {@link Admin#grant(UserPermission, boolean)} instead.
*/
+ @Deprecated
public static void revoke(RpcController controller,
AccessControlService.BlockingInterface protocol, String userShortName, TableName tableName,
byte[] f, byte[] q, Permission.Action... actions) throws ServiceException {
@@ -620,7 +631,9 @@ public class AccessControlUtil {
* @param namespace optional table name
* @param actions the permissions to be revoked
* @throws ServiceException on failure
+ * @deprecated Use {@link Admin#grant(UserPermission, boolean)} instead.
*/
+ @Deprecated
public static void revoke(RpcController controller,
AccessControlService.BlockingInterface protocol, String userShortName, String namespace,
Permission.Action... actions) throws ServiceException {
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/ShadedAccessControlUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/ShadedAccessControlUtil.java
index 7e36656..67fdba3 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/ShadedAccessControlUtil.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/ShadedAccessControlUtil.java
@@ -18,20 +18,21 @@
package org.apache.hadoop.hbase.security.access;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.security.access.Permission.Action;
+import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hbase.thirdparty.com.google.common.collect.ArrayListMultimap;
import org.apache.hbase.thirdparty.com.google.common.collect.ListMultimap;
-import org.apache.hadoop.hbase.TableName;
-import org.apache.yetus.audience.InterfaceAudience;
-import org.apache.hadoop.hbase.security.access.Permission.Action;
+import org.apache.hbase.thirdparty.com.google.protobuf.ByteString;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GrantRequest;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.RevokeRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;
-import org.apache.hbase.thirdparty.com.google.protobuf.ByteString;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
/**
* Convert protobuf objects in AccessControl.proto under hbase-protocol-shaded to user-oriented
@@ -49,20 +50,18 @@ public class ShadedAccessControlUtil {
/**
* Convert a client user permission to a user permission shaded proto.
*/
- public static
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action
- toPermissionAction(Permission.Action action) {
+ public static AccessControlProtos.Permission.Action toPermissionAction(Permission.Action action) {
switch (action) {
- case READ:
- return org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action.READ;
- case WRITE:
- return org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action.WRITE;
- case EXEC:
- return org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action.EXEC;
- case CREATE:
- return org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action.CREATE;
- case ADMIN:
- return org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action.ADMIN;
+ case READ:
+ return AccessControlProtos.Permission.Action.READ;
+ case WRITE:
+ return AccessControlProtos.Permission.Action.WRITE;
+ case EXEC:
+ return AccessControlProtos.Permission.Action.EXEC;
+ case CREATE:
+ return AccessControlProtos.Permission.Action.CREATE;
+ case ADMIN:
+ return AccessControlProtos.Permission.Action.ADMIN;
}
throw new IllegalArgumentException("Unknown action value " + action.name());
}
@@ -70,8 +69,7 @@ public class ShadedAccessControlUtil {
/**
* Convert a Permission.Action shaded proto to a client Permission.Action object.
*/
- public static Permission.Action toPermissionAction(
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action action) {
+ public static Permission.Action toPermissionAction(AccessControlProtos.Permission.Action action) {
switch (action) {
case READ:
return Permission.Action.READ;
@@ -94,9 +92,9 @@ public class ShadedAccessControlUtil {
* @return the converted list of Actions
*/
public static List<Permission.Action> toPermissionActions(
- List<org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action> protoActions) {
+ List<AccessControlProtos.Permission.Action> protoActions) {
List<Permission.Action> actions = new ArrayList<>(protoActions.size());
- for (org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action a : protoActions) {
+ for (AccessControlProtos.Permission.Action a : protoActions) {
actions.add(toPermissionAction(a));
}
return actions;
@@ -163,20 +161,15 @@ public class ShadedAccessControlUtil {
* @param perm the client Permission
* @return the protobuf Permission
*/
- public static org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission
- toPermission(Permission perm) {
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Builder ret =
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission
- .newBuilder();
+ public static AccessControlProtos.Permission toPermission(Permission perm) {
+ AccessControlProtos.Permission.Builder ret = AccessControlProtos.Permission.newBuilder();
if (perm instanceof NamespacePermission) {
NamespacePermission nsPerm = (NamespacePermission) perm;
- ret.setType(
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Type.Namespace);
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.NamespacePermission.Builder builder =
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.NamespacePermission
- .newBuilder();
+ ret.setType(AccessControlProtos.Permission.Type.Namespace);
+ AccessControlProtos.NamespacePermission.Builder builder =
+ AccessControlProtos.NamespacePermission.newBuilder();
builder.setNamespaceName(org.apache.hbase.thirdparty.com.google.protobuf.ByteString
- .copyFromUtf8(nsPerm.getNamespace()));
+ .copyFromUtf8(nsPerm.getNamespace()));
Permission.Action[] actions = perm.getActions();
if (actions != null) {
for (Permission.Action a : actions) {
@@ -186,11 +179,9 @@ public class ShadedAccessControlUtil {
ret.setNamespacePermission(builder);
} else if (perm instanceof TablePermission) {
TablePermission tablePerm = (TablePermission) perm;
- ret.setType(
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Type.Table);
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.TablePermission.Builder builder =
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.TablePermission
- .newBuilder();
+ ret.setType(AccessControlProtos.Permission.Type.Table);
+ AccessControlProtos.TablePermission.Builder builder =
+ AccessControlProtos.TablePermission.newBuilder();
builder.setTableName(toProtoTableName(tablePerm.getTableName()));
if (tablePerm.hasFamily()) {
builder.setFamily(ByteString.copyFrom(tablePerm.getFamily()));
@@ -207,11 +198,9 @@ public class ShadedAccessControlUtil {
ret.setTablePermission(builder);
} else {
// perm.getAccessScope() == Permission.Scope.GLOBAL
- ret.setType(
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Type.Global);
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GlobalPermission.Builder builder =
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GlobalPermission
- .newBuilder();
+ ret.setType(AccessControlProtos.Permission.Type.Global);
+ AccessControlProtos.GlobalPermission.Builder builder =
+ AccessControlProtos.GlobalPermission.newBuilder();
Permission.Action[] actions = perm.getActions();
if (actions != null) {
for (Permission.Action a : actions) {
@@ -230,9 +219,9 @@ public class ShadedAccessControlUtil {
* @return the converted UserPermission
*/
public static ListMultimap<String, Permission> toUserTablePermissions(
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions proto) {
+ AccessControlProtos.UsersAndPermissions proto) {
ListMultimap<String, Permission> perms = ArrayListMultimap.create();
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions.UserPermissions userPerm;
+ AccessControlProtos.UsersAndPermissions.UserPermissions userPerm;
for (int i = 0; i < proto.getUserPermissionsCount(); i++) {
userPerm = proto.getUserPermissions(i);
for (int j = 0; j < userPerm.getPermissionsCount(); j++) {
@@ -249,16 +238,13 @@ public class ShadedAccessControlUtil {
* @param perm the list of user and table permissions
* @return the protobuf UserTablePermissions
*/
- public static
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions
+ public static AccessControlProtos.UsersAndPermissions
toUserTablePermissions(ListMultimap<String, UserPermission> perm) {
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions.Builder builder =
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions
- .newBuilder();
+ AccessControlProtos.UsersAndPermissions.Builder builder =
+ AccessControlProtos.UsersAndPermissions.newBuilder();
for (Map.Entry<String, Collection<UserPermission>> entry : perm.asMap().entrySet()) {
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions.UserPermissions.Builder userPermBuilder =
- org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions.UserPermissions
- .newBuilder();
+ AccessControlProtos.UsersAndPermissions.UserPermissions.Builder userPermBuilder =
+ AccessControlProtos.UsersAndPermissions.UserPermissions.newBuilder();
userPermBuilder.setUser(ByteString.copyFromUtf8(entry.getKey()));
for (UserPermission userPerm : entry.getValue()) {
userPermBuilder.addPermissions(toPermission(userPerm.getPermission()));
@@ -267,4 +253,34 @@ public class ShadedAccessControlUtil {
}
return builder.build();
}
+
+ /**
+ * Converts a user permission proto to a client user permission object.
+ * @param proto the protobuf UserPermission
+ * @return the converted UserPermission
+ */
+ public static UserPermission toUserPermission(AccessControlProtos.UserPermission proto) {
+ return new UserPermission(proto.getUser().toStringUtf8(), toPermission(proto.getPermission()));
+ }
+
+ /**
+ * Convert a client user permission to a user permission proto
+ * @param perm the client UserPermission
+ * @return the protobuf UserPermission
+ */
+ public static AccessControlProtos.UserPermission toUserPermission(UserPermission perm) {
+ return AccessControlProtos.UserPermission.newBuilder()
+ .setUser(ByteString.copyFromUtf8(perm.getUser()))
+ .setPermission(toPermission(perm.getPermission())).build();
+ }
+
+ public static GrantRequest buildGrantRequest(UserPermission userPermission,
+ boolean mergeExistingPermissions) {
+ return GrantRequest.newBuilder().setUserPermission(toUserPermission(userPermission))
+ .setMergeExistingPermissions(mergeExistingPermissions).build();
+ }
+
+ public static RevokeRequest buildRevokeRequest(UserPermission userPermission) {
+ return RevokeRequest.newBuilder().setUserPermission(toUserPermission(userPermission)).build();
+ }
}
diff --git a/hbase-protocol-shaded/src/main/protobuf/Master.proto b/hbase-protocol-shaded/src/main/protobuf/Master.proto
index b1ed94f..ec0b543 100644
--- a/hbase-protocol-shaded/src/main/protobuf/Master.proto
+++ b/hbase-protocol-shaded/src/main/protobuf/Master.proto
@@ -36,6 +36,7 @@ import "Procedure.proto";
import "Quota.proto";
import "Replication.proto";
import "Snapshot.proto";
+import "AccessControl.proto";
/* Column-level protobufs */
@@ -1014,6 +1015,10 @@ service MasterService {
/** Get if is rpc throttled enabled */
rpc IsRpcThrottleEnabled (IsRpcThrottleEnabledRequest)
returns (IsRpcThrottleEnabledResponse);
+
+ rpc Grant(GrantRequest) returns (GrantResponse);
+
+ rpc Revoke(RevokeRequest) returns (RevokeResponse);
}
// HBCK Service definitions.
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
index 63ed125..68e69b9 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
@@ -37,6 +37,7 @@ import org.apache.hadoop.hbase.net.Address;
import org.apache.hadoop.hbase.quotas.GlobalQuotaSettings;
import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
import org.apache.hadoop.hbase.replication.SyncReplicationState;
+import org.apache.hadoop.hbase.security.access.UserPermission;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.yetus.audience.InterfaceStability;
@@ -1573,4 +1574,42 @@ public interface MasterObserver {
default void postIsRpcThrottleEnabled(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final boolean rpcThrottleEnabled) throws IOException {
}
+
+ /**
+ * Called before granting user permissions.
+ * @param ctx the coprocessor instance's environment
+ * @param userPermission the user and permissions
+ * @param mergeExistingPermissions True if merge with previous granted permissions
+ */
+ default void preGrant(ObserverContext<MasterCoprocessorEnvironment> ctx,
+ UserPermission userPermission, boolean mergeExistingPermissions) throws IOException {
+ }
+
+ /**
+ * Called after granting user permissions.
+ * @param ctx the coprocessor instance's environment
+ * @param userPermission the user and permissions
+ * @param mergeExistingPermissions True if merge with previous granted permissions
+ */
+ default void postGrant(ObserverContext<MasterCoprocessorEnvironment> ctx,
+ UserPermission userPermission, boolean mergeExistingPermissions) throws IOException {
+ }
+
+ /**
+ * Called before revoking user permissions.
+ * @param ctx the coprocessor instance's environment
+ * @param userPermission the user and permissions
+ */
+ default void preRevoke(ObserverContext<MasterCoprocessorEnvironment> ctx,
+ UserPermission userPermission) throws IOException {
+ }
+
+ /**
+ * Called after revoking user permissions.
+ * @param ctx the coprocessor instance's environment
+ * @param userPermission the user and permissions
+ */
+ default void postRevoke(ObserverContext<MasterCoprocessorEnvironment> ctx,
+ UserPermission userPermission) throws IOException {
+ }
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
index b4a4421..d999dae 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
@@ -58,6 +58,7 @@ import org.apache.hadoop.hbase.quotas.GlobalQuotaSettings;
import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
import org.apache.hadoop.hbase.replication.SyncReplicationState;
import org.apache.hadoop.hbase.security.User;
+import org.apache.hadoop.hbase.security.access.UserPermission;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1834,4 +1835,42 @@ public class MasterCoprocessorHost
}
});
}
+
+ public void preGrant(UserPermission userPermission, boolean mergeExistingPermissions)
+ throws IOException {
+ execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
+ @Override
+ public void call(MasterObserver observer) throws IOException {
+ observer.preGrant(this, userPermission, mergeExistingPermissions);
+ }
+ });
+ }
+
+ public void postGrant(UserPermission userPermission, boolean mergeExistingPermissions)
+ throws IOException {
+ execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
+ @Override
+ public void call(MasterObserver observer) throws IOException {
+ observer.postGrant(this, userPermission, mergeExistingPermissions);
+ }
+ });
+ }
+
+ public void preRevoke(UserPermission userPermission) throws IOException {
+ execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
+ @Override
+ public void call(MasterObserver observer) throws IOException {
+ observer.preRevoke(this, userPermission);
+ }
+ });
+ }
+
+ public void postRevoke(UserPermission userPermission) throws IOException {
+ execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
+ @Override
+ public void call(MasterObserver observer) throws IOException {
+ observer.postRevoke(this, userPermission);
+ }
+ });
+ }
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
index 89fcff9..1ff3f0e 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
@@ -49,6 +49,7 @@ import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
import org.apache.hadoop.hbase.client.MasterSwitchType;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.RegionInfoBuilder;
+import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.TableState;
import org.apache.hadoop.hbase.client.VersionInfoUtil;
@@ -92,8 +93,11 @@ import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
import org.apache.hadoop.hbase.replication.ReplicationPeerDescription;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.security.access.AccessChecker;
+import org.apache.hadoop.hbase.security.access.AccessControlLists;
import org.apache.hadoop.hbase.security.access.AccessController;
import org.apache.hadoop.hbase.security.access.Permission;
+import org.apache.hadoop.hbase.security.access.ShadedAccessControlUtil;
+import org.apache.hadoop.hbase.security.access.UserPermission;
import org.apache.hadoop.hbase.security.visibility.VisibilityController;
import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
@@ -114,6 +118,10 @@ import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations;
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.shaded.protobuf.ResponseConverter;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GrantRequest;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GrantResponse;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.RevokeRequest;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.RevokeResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.CompactRegionRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.CompactRegionResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionInfoRequest;
@@ -2502,6 +2510,50 @@ public class MasterRpcServices extends RSRpcServices
}
}
+ @Override
+ public GrantResponse grant(RpcController controller, GrantRequest request)
+ throws ServiceException {
+ try {
+ final UserPermission perm =
+ ShadedAccessControlUtil.toUserPermission(request.getUserPermission());
+ boolean mergeExistingPermissions = request.getMergeExistingPermissions();
+ if (master.cpHost != null) {
+ master.cpHost.preGrant(perm, mergeExistingPermissions);
+ }
+ try (Table table = master.getConnection().getTable(AccessControlLists.ACL_TABLE_NAME)) {
+ AccessControlLists.addUserPermission(getConfiguration(), perm, table,
+ mergeExistingPermissions);
+ }
+ if (master.cpHost != null) {
+ master.cpHost.postGrant(perm, mergeExistingPermissions);
+ }
+ return GrantResponse.getDefaultInstance();
+ } catch (IOException ioe) {
+ throw new ServiceException(ioe);
+ }
+ }
+
+ @Override
+ public RevokeResponse revoke(RpcController controller, RevokeRequest request)
+ throws ServiceException {
+ try {
+ final UserPermission userPermission =
+ ShadedAccessControlUtil.toUserPermission(request.getUserPermission());
+ if (master.cpHost != null) {
+ master.cpHost.preRevoke(userPermission);
+ }
+ try (Table table = master.getConnection().getTable(AccessControlLists.ACL_TABLE_NAME)) {
+ AccessControlLists.removeUserPermission(master.getConfiguration(), userPermission, table);
+ }
+ if (master.cpHost != null) {
+ master.cpHost.postRevoke(userPermission);
+ }
+ return RevokeResponse.getDefaultInstance();
+ } catch (IOException ioe) {
+ throw new ServiceException(ioe);
+ }
+ }
+
private boolean containMetaWals(ServerName serverName) throws IOException {
Path logDir = new Path(master.getWALRootDir(),
AbstractFSWALProvider.getWALDirectoryName(serverName.toString()));
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlLists.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlLists.java
index 34480d3..7560a93 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlLists.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlLists.java
@@ -130,7 +130,7 @@ public class AccessControlLists {
* @param t acl table instance. It is closed upon method return.
* @throws IOException in the case of an error accessing the metadata table
*/
- static void addUserPermission(Configuration conf, UserPermission userPerm, Table t,
+ public static void addUserPermission(Configuration conf, UserPermission userPerm, Table t,
boolean mergeExistingPermissions) throws IOException {
Permission permission = userPerm.getPermission();
Permission.Action[] actions = permission.getActions();
@@ -222,7 +222,7 @@ public class AccessControlLists {
* @param t acl table
* @throws IOException if there is an error accessing the metadata table
*/
- static void removeUserPermission(Configuration conf, UserPermission userPerm, Table t)
+ public static void removeUserPermission(Configuration conf, UserPermission userPerm, Table t)
throws IOException {
if (null == userPerm.getPermission().getActions() ||
userPerm.getPermission().getActions().length == 0) {
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java
index f99531c..d6a2463 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java
@@ -2052,6 +2052,10 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor,
/* ---- Protobuf AccessControlService implementation ---- */
+ /**
+ * @deprecated Use {@link Admin#grant(UserPermission, boolean)} instead.
+ */
+ @Deprecated
@Override
public void grant(RpcController controller,
AccessControlProtos.GrantRequest request,
@@ -2069,36 +2073,10 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor,
LOG.debug("Received request from {} to grant access permission {}",
caller.getName(), perm.toString());
}
+ preGrantOrRevoke(caller, "grant", perm);
- switch(request.getUserPermission().getPermission().getType()) {
- case Global :
- accessChecker.requireGlobalPermission(caller, "grant", Action.ADMIN, "");
- break;
- case Table :
- TablePermission tablePerm = (TablePermission) perm.getPermission();
- accessChecker.requirePermission(caller, "grant", tablePerm.getTableName(),
- tablePerm.getFamily(), tablePerm.getQualifier(), null, Action.ADMIN);
- break;
- case Namespace :
- NamespacePermission namespacePer = (NamespacePermission) perm.getPermission();
- accessChecker.requireNamespacePermission(caller, "grant", namespacePer.getNamespace(),
- null, Action.ADMIN);
- break;
- }
-
- User.runAsLoginUser(new PrivilegedExceptionAction<Void>() {
- @Override
- public Void run() throws Exception {
- // regionEnv is set at #start. Hopefully not null at this point.
- try (Table table = regionEnv.getConnection().
- getTable(AccessControlLists.ACL_TABLE_NAME)) {
- AccessControlLists.addUserPermission(regionEnv.getConfiguration(), perm, table,
- request.getMergeExistingPermissions());
- }
- return null;
- }
- });
-
+ // regionEnv is set at #start. Hopefully not null at this point.
+ regionEnv.getConnection().getAdmin().grant(perm, request.getMergeExistingPermissions());
if (AUDITLOG.isTraceEnabled()) {
// audit log should store permission changes in addition to auth results
AUDITLOG.trace("Granted permission " + perm.toString());
@@ -2115,9 +2093,12 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor,
done.run(response);
}
+ /**
+ * @deprecated Use {@link Admin#revoke(UserPermission)} instead.
+ */
+ @Deprecated
@Override
- public void revoke(RpcController controller,
- AccessControlProtos.RevokeRequest request,
+ public void revoke(RpcController controller, AccessControlProtos.RevokeRequest request,
RpcCallback<AccessControlProtos.RevokeResponse> done) {
final UserPermission perm = AccessControlUtil.toUserPermission(request.getUserPermission());
AccessControlProtos.RevokeResponse response = null;
@@ -2132,35 +2113,9 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor,
LOG.debug("Received request from {} to revoke access permission {}",
caller.getShortName(), perm.toString());
}
-
- switch(request.getUserPermission().getPermission().getType()) {
- case Global :
- accessChecker.requireGlobalPermission(caller, "revoke", Action.ADMIN, "");
- break;
- case Table :
- TablePermission tablePerm = (TablePermission) perm.getPermission();
- accessChecker.requirePermission(caller, "revoke", tablePerm.getTableName(),
- tablePerm.getFamily(), tablePerm.getQualifier(), null, Action.ADMIN);
- break;
- case Namespace :
- NamespacePermission namespacePer = (NamespacePermission) perm.getPermission();
- accessChecker.requireNamespacePermission(caller, "revoke",
- namespacePer.getNamespace(), null, Action.ADMIN);
- break;
- }
-
- User.runAsLoginUser(new PrivilegedExceptionAction<Void>() {
- @Override
- public Void run() throws Exception {
- // regionEnv is set at #start. Hopefully not null here.
- try (Table table = regionEnv.getConnection().
- getTable(AccessControlLists.ACL_TABLE_NAME)) {
- AccessControlLists.removeUserPermission(regionEnv.getConfiguration(), perm, table);
- }
- return null;
- }
- });
-
+ preGrantOrRevoke(caller, "revoke", perm);
+ // regionEnv is set at #start. Hopefully not null here.
+ regionEnv.getConnection().getAdmin().revoke(perm);
if (AUDITLOG.isTraceEnabled()) {
// audit log should record all permission changes
AUDITLOG.trace("Revoked permission " + perm.toString());
@@ -2680,4 +2635,36 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor,
}
done.run(response);
}
+
+ @Override
+ public void preGrant(ObserverContext<MasterCoprocessorEnvironment> ctx,
+ UserPermission userPermission, boolean mergeExistingPermissions) throws IOException {
+ preGrantOrRevoke(getActiveUser(ctx), "grant", userPermission);
+ }
+
+ @Override
+ public void preRevoke(ObserverContext<MasterCoprocessorEnvironment> ctx,
+ UserPermission userPermission) throws IOException {
+ preGrantOrRevoke(getActiveUser(ctx), "revoke", userPermission);
+ }
+
+ private void preGrantOrRevoke(User caller, String request, UserPermission userPermission)
+ throws IOException {
+ switch (userPermission.getPermission().scope) {
+ case GLOBAL:
+ accessChecker.requireGlobalPermission(caller, request, Action.ADMIN, "");
+ break;
+ case NAMESPACE:
+ NamespacePermission namespacePerm = (NamespacePermission) userPermission.getPermission();
+ accessChecker.requireNamespacePermission(caller, request, namespacePerm.getNamespace(),
+ null, Action.ADMIN);
+ break;
+ case TABLE:
+ TablePermission tablePerm = (TablePermission) userPermission.getPermission();
+ accessChecker.requirePermission(caller, request, tablePerm.getTableName(),
+ tablePerm.getFamily(), tablePerm.getQualifier(), null, Action.ADMIN);
+ break;
+ default:
+ }
+ }
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/SecureTestUtil.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/SecureTestUtil.java
index 3655352..e392b3b 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/SecureTestUtil.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/SecureTestUtil.java
@@ -34,7 +34,6 @@ import com.google.protobuf.ServiceException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Coprocessor;
import org.apache.hadoop.hbase.HBaseTestingUtility;
-import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.MiniHBaseCluster;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.TableName;
@@ -375,12 +374,8 @@ public class SecureTestUtil {
@Override
public Void call() throws Exception {
try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
- try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
- BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.grant(null, protocol, user, false, actions);
- }
+ connection.getAdmin().grant(new UserPermission(user, new GlobalPermission(actions)),
+ false);
}
return null;
}
@@ -398,12 +393,7 @@ public class SecureTestUtil {
@Override
public Void call() throws Exception {
try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
- try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
- BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.revoke(null, protocol, user, actions);
- }
+ connection.getAdmin().revoke(new UserPermission(user, new GlobalPermission(actions)));
}
return null;
}
@@ -421,12 +411,8 @@ public class SecureTestUtil {
@Override
public Void call() throws Exception {
try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
- try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
- BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.grant(null, protocol, user, namespace, false, actions);
- }
+ connection.getAdmin()
+ .grant(new UserPermission(user, new NamespacePermission(namespace, actions)), false);
}
return null;
}
@@ -486,12 +472,8 @@ public class SecureTestUtil {
@Override
public Void call() throws Exception {
try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
- try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
- BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.revoke(null, protocol, user, namespace, actions);
- }
+ connection.getAdmin()
+ .revoke(new UserPermission(user, new NamespacePermission(namespace, actions)));
}
return null;
}
@@ -510,12 +492,9 @@ public class SecureTestUtil {
@Override
public Void call() throws Exception {
try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
- try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
- BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.grant(null, protocol, user, table, family, qualifier, false, actions);
- }
+ connection.getAdmin().grant(
+ new UserPermission(user, new TablePermission(table, family, qualifier, actions)),
+ false);
}
return null;
}
@@ -576,12 +555,8 @@ public class SecureTestUtil {
@Override
public Void call() throws Exception {
try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
- try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
- BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.revoke(null, protocol, user, table, family, qualifier, actions);
- }
+ connection.getAdmin().revoke(
+ new UserPermission(user, new TablePermission(table, family, qualifier, actions)));
}
return 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 9b8c8a6..5199550 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
@@ -1170,13 +1170,10 @@ public class TestAccessController extends SecureTestUtil {
AccessTestAction grantAction = new AccessTestAction() {
@Override
public Object run() throws Exception {
- try(Connection conn = ConnectionFactory.createConnection(conf);
- Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
- BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName());
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.grant(null, protocol, USER_RO.getShortName(), TEST_TABLE, TEST_FAMILY,
- null, false, Action.READ);
+ try (Connection conn = ConnectionFactory.createConnection(conf)) {
+ conn.getAdmin().grant(new UserPermission(USER_RO.getShortName(),
+ new TablePermission(TEST_TABLE, TEST_FAMILY, Action.READ)),
+ false);
}
return null;
}
@@ -1185,13 +1182,9 @@ public class TestAccessController extends SecureTestUtil {
AccessTestAction revokeAction = new AccessTestAction() {
@Override
public Object run() throws Exception {
- try(Connection conn = ConnectionFactory.createConnection(conf);
- Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
- BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName());
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.revoke(null, protocol, USER_RO.getShortName(), TEST_TABLE, TEST_FAMILY, null,
- Action.READ);
+ try(Connection conn = ConnectionFactory.createConnection(conf)) {
+ conn.getAdmin().revoke(new UserPermission(USER_RO.getShortName(),
+ new TablePermission(TEST_TABLE, TEST_FAMILY, Action.READ)));
}
return null;
}
@@ -1225,6 +1218,57 @@ public class TestAccessController extends SecureTestUtil {
}
};
+ AccessTestAction preGrantAction = new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preGrant(ObserverContextImpl.createAndPrepare(CP_ENV),
+ new UserPermission(USER_RO.getShortName(),
+ new TablePermission(TEST_TABLE, TEST_FAMILY, Action.READ)),
+ false);
+ return null;
+ }
+ };
+
+ AccessTestAction preRevokeAction = new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preRevoke(ObserverContextImpl.createAndPrepare(CP_ENV),
+ new UserPermission(USER_RO.getShortName(),
+ new TablePermission(TEST_TABLE, TEST_FAMILY, Action.READ)));
+ return null;
+ }
+ };
+
+ AccessTestAction grantCPAction = new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ try (Connection conn = ConnectionFactory.createConnection(conf);
+ Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
+ BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName());
+ AccessControlService.BlockingInterface protocol =
+ AccessControlService.newBlockingStub(service);
+ AccessControlUtil.grant(null, protocol, USER_RO.getShortName(), TEST_TABLE, TEST_FAMILY,
+ null, false, Action.READ);
+ }
+ return null;
+ }
+ };
+
+ AccessTestAction revokeCPAction = new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ try (Connection conn = ConnectionFactory.createConnection(conf);
+ Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
+ BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName());
+ AccessControlService.BlockingInterface protocol =
+ AccessControlService.newBlockingStub(service);
+ AccessControlUtil.revoke(null, protocol, USER_RO.getShortName(), TEST_TABLE, TEST_FAMILY,
+ null, Action.READ);
+ }
+ return null;
+ }
+ };
+
verifyAllowed(grantAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN);
verifyDenied(grantAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ,
USER_GROUP_WRITE, USER_GROUP_CREATE);
@@ -1240,6 +1284,22 @@ public class TestAccessController extends SecureTestUtil {
verifyAllowed(getGlobalPermissionsAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN);
verifyDenied(getGlobalPermissionsAction, USER_CREATE, USER_OWNER, USER_RW, USER_RO,
USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
+
+ verifyAllowed(preGrantAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN);
+ verifyDenied(preGrantAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ,
+ USER_GROUP_WRITE, USER_GROUP_CREATE);
+
+ verifyAllowed(preRevokeAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN);
+ verifyDenied(preRevokeAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ,
+ USER_GROUP_WRITE, USER_GROUP_CREATE);
+
+ verifyAllowed(grantCPAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN);
+ verifyDenied(grantCPAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ,
+ USER_GROUP_WRITE, USER_GROUP_CREATE);
+
+ verifyAllowed(revokeCPAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN);
+ verifyDenied(revokeCPAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ,
+ USER_GROUP_WRITE, USER_GROUP_CREATE);
} finally {
// Cleanup, Grant the revoked permission back to the user
grantOnTable(TEST_UTIL, USER_RO.getShortName(), TEST_TABLE, TEST_FAMILY, null,
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestNamespaceCommands.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestNamespaceCommands.java
index d37794d..fa8543e 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestNamespaceCommands.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestNamespaceCommands.java
@@ -356,40 +356,27 @@ public class TestNamespaceCommands extends SecureTestUtil {
}
@Test
- public void testGrantRevoke() throws Exception{
+ public void testGrantRevoke() throws Exception {
final String testUser = "testUser";
-
// Test if client API actions are authorized
-
AccessTestAction grantAction = new AccessTestAction() {
@Override
public Object run() throws Exception {
- Connection connection = ConnectionFactory.createConnection(conf);
- Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME);
- try {
- BlockingRpcChannel service =
- acl.coprocessorService(HConstants.EMPTY_START_ROW);
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.grant(null, protocol, testUser, TEST_NAMESPACE, false, Action.WRITE);
- } finally {
- acl.close();
- connection.close();
+ try (Connection connection = ConnectionFactory.createConnection(conf)) {
+ connection.getAdmin().grant(
+ new UserPermission(testUser, new NamespacePermission(TEST_NAMESPACE, Action.WRITE)),
+ false);
}
return null;
}
};
-
AccessTestAction grantNamespaceAction = new AccessTestAction() {
@Override
public Object run() throws Exception {
- try(Connection conn = ConnectionFactory.createConnection(conf);
- Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
- BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.grant(null, protocol, USER_GROUP_NS_ADMIN.getShortName(),
- TEST_NAMESPACE, false, Action.READ);
+ try (Connection conn = ConnectionFactory.createConnection(conf)) {
+ conn.getAdmin().grant(
+ new UserPermission(USER_GROUP_NS_ADMIN.getShortName(), TEST_NAMESPACE, Action.READ),
+ false);
}
return null;
}
@@ -398,37 +385,19 @@ public class TestNamespaceCommands extends SecureTestUtil {
AccessTestAction revokeAction = new AccessTestAction() {
@Override
public Object run() throws Exception {
- Connection connection = ConnectionFactory.createConnection(conf);
- Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME);
- try {
- BlockingRpcChannel service =
- acl.coprocessorService(HConstants.EMPTY_START_ROW);
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.revoke(null, protocol, testUser, TEST_NAMESPACE, Action.WRITE);
- } finally {
- acl.close();
- connection.close();
+ try (Connection connection = ConnectionFactory.createConnection(conf)) {
+ connection.getAdmin().revoke(
+ new UserPermission(testUser, new NamespacePermission(TEST_NAMESPACE, Action.WRITE)));
}
return null;
}
};
-
AccessTestAction revokeNamespaceAction = new AccessTestAction() {
@Override
public Object run() throws Exception {
- Connection connection = ConnectionFactory.createConnection(conf);
- Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME);
- try {
- BlockingRpcChannel service =
- acl.coprocessorService(HConstants.EMPTY_START_ROW);
- AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
- AccessControlUtil.revoke(null, protocol, USER_GROUP_NS_ADMIN.getShortName(),
- TEST_NAMESPACE, Action.READ);
- } finally {
- acl.close();
- connection.close();
+ try (Connection connection = ConnectionFactory.createConnection(conf)) {
+ connection.getAdmin().revoke(new UserPermission(USER_GROUP_NS_ADMIN.getShortName(),
+ new NamespacePermission(TEST_NAMESPACE, Action.READ)));
}
return null;
}
@@ -437,16 +406,57 @@ public class TestNamespaceCommands extends SecureTestUtil {
AccessTestAction getPermissionsAction = new AccessTestAction() {
@Override
public Object run() throws Exception {
- Connection connection = ConnectionFactory.createConnection(conf);
- Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME);
- try {
+ try (Connection connection = ConnectionFactory.createConnection(conf);
+ Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
AccessControlService.BlockingInterface protocol =
- AccessControlService.newBlockingStub(service);
+ AccessControlService.newBlockingStub(service);
AccessControlUtil.getUserPermissions(null, protocol, Bytes.toBytes(TEST_NAMESPACE));
- } finally {
- acl.close();
- connection.close();
+ }
+ return null;
+ }
+ };
+
+ AccessTestAction preGrantAction = new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preGrant(ObserverContextImpl.createAndPrepare(CP_ENV),
+ new UserPermission(testUser, new NamespacePermission(TEST_NAMESPACE, Action.WRITE)),
+ false);
+ return null;
+ }
+ };
+ AccessTestAction preRevokeAction = new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preRevoke(ObserverContextImpl.createAndPrepare(CP_ENV),
+ new UserPermission(testUser, new NamespacePermission(TEST_NAMESPACE, Action.WRITE)));
+ return null;
+ }
+ };
+
+ AccessTestAction grantCPAction = new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ try (Connection connection = ConnectionFactory.createConnection(conf);
+ Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
+ BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
+ AccessControlService.BlockingInterface protocol =
+ AccessControlService.newBlockingStub(service);
+ AccessControlUtil.grant(null, protocol, testUser, TEST_NAMESPACE, false, Action.WRITE);
+ }
+ return null;
+ }
+ };
+ AccessTestAction revokeCPAction = new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ try (Connection connection = ConnectionFactory.createConnection(conf);
+ Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
+ BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
+ AccessControlService.BlockingInterface protocol =
+ AccessControlService.newBlockingStub(service);
+ AccessControlUtil.revoke(null, protocol, testUser, TEST_NAMESPACE, Action.WRITE);
}
return null;
}
@@ -456,7 +466,6 @@ public class TestNamespaceCommands extends SecureTestUtil {
verifyDenied(grantAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
-
verifyAllowed(grantNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
verifyDenied(grantNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
@@ -467,7 +476,6 @@ public class TestNamespaceCommands extends SecureTestUtil {
verifyDenied(revokeAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
-
verifyAllowed(revokeNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
verifyDenied(revokeNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
@@ -479,6 +487,24 @@ public class TestNamespaceCommands extends SecureTestUtil {
verifyDenied(getPermissionsAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
+
+ verifyAllowed(preGrantAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
+ verifyDenied(preGrantAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
+ USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
+ USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
+ verifyAllowed(preRevokeAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
+ verifyDenied(preRevokeAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
+ USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
+ USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
+
+ verifyAllowed(grantCPAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
+ verifyDenied(grantCPAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
+ USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
+ USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
+ verifyAllowed(revokeCPAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
+ verifyDenied(revokeCPAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
+ USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
+ USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
}
@Test
diff --git a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java
index 56626b6..5d550c6 100644
--- a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java
+++ b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java
@@ -60,6 +60,7 @@ import org.apache.hadoop.hbase.replication.ReplicationException;
import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
import org.apache.hadoop.hbase.replication.ReplicationPeerDescription;
import org.apache.hadoop.hbase.replication.SyncReplicationState;
+import org.apache.hadoop.hbase.security.access.UserPermission;
import org.apache.hadoop.hbase.thrift2.ThriftUtilities;
import org.apache.hadoop.hbase.thrift2.generated.TColumnFamilyDescriptor;
import org.apache.hadoop.hbase.thrift2.generated.THBaseService;
@@ -1425,4 +1426,14 @@ public class ThriftAdmin implements Admin {
public SpaceQuotaSnapshot getCurrentSpaceQuotaSnapshot(TableName tableName) throws IOException {
throw new NotImplementedException("getCurrentSpaceQuotaSnapshot not supported in ThriftAdmin");
}
+
+ @Override
+ public void grant(UserPermission userPermission, boolean mergeExistingPermissions) {
+ throw new NotImplementedException("grant not supported in ThriftAdmin");
+ }
+
+ @Override
+ public void revoke(UserPermission userPermission) {
+ throw new NotImplementedException("revoke not supported in ThriftAdmin");
+ }
}