HBASE-16217 Pass through the calling user in ObserverContext

This commit is contained in:
Gary Helmling 2016-06-29 16:57:11 -07:00
parent 9d740f7b8b
commit 65834a1ced
25 changed files with 483 additions and 726 deletions

View File

@ -159,6 +159,7 @@ import org.apache.hadoop.hbase.quotas.ThrottleType;
import org.apache.hadoop.hbase.replication.ReplicationLoadSink;
import org.apache.hadoop.hbase.replication.ReplicationLoadSource;
import org.apache.hadoop.hbase.rsgroup.RSGroupInfo;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.security.access.Permission;
import org.apache.hadoop.hbase.security.access.TablePermission;
import org.apache.hadoop.hbase.security.access.UserPermission;
@ -1874,12 +1875,12 @@ public final class ProtobufUtil {
public static void mergeRegions(final RpcController controller,
final AdminService.BlockingInterface admin,
final HRegionInfo region_a, final HRegionInfo region_b,
final boolean forcible, final UserGroupInformation user) throws IOException {
final boolean forcible, final User user) throws IOException {
final MergeRegionsRequest request = RequestConverter.buildMergeRegionsRequest(
region_a.getRegionName(), region_b.getRegionName(),forcible);
if (user != null) {
try {
user.doAs(new PrivilegedExceptionAction<Void>() {
user.runAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
admin.mergeRegions(controller, request);

View File

@ -23,6 +23,10 @@ import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.classification.InterfaceStability;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
import org.apache.hadoop.hbase.ipc.RpcServer;
import org.apache.hadoop.hbase.security.User;
import javax.annotation.Nullable;
/**
* Carries the execution state for a given invocation of an Observer coprocessor
@ -40,8 +44,10 @@ public class ObserverContext<E extends CoprocessorEnvironment> {
private E env;
private boolean bypass;
private boolean complete;
private User caller;
public ObserverContext() {
public ObserverContext(User caller) {
this.caller = caller;
}
public E getEnvironment() {
@ -91,6 +97,17 @@ public class ObserverContext<E extends CoprocessorEnvironment> {
return current;
}
/**
* Returns the active user for the coprocessor call.
* If an explicit {@code User} instance was provided to the constructor, that will be returned,
* otherwise if we are in the context of an RPC call, the remote user is used. May return null
* if the execution is outside of an RPC context.
*/
@Nullable
public User getCaller() {
return caller;
}
/**
* Instantiates a new ObserverContext instance if the passed reference is
* <code>null</code> and sets the environment in the new or existing instance.
@ -103,10 +120,34 @@ public class ObserverContext<E extends CoprocessorEnvironment> {
* @param <T> The environment type for the context
* @return An instance of <code>ObserverContext</code> with the environment set
*/
@Deprecated
// TODO: Remove this method, ObserverContext should not depend on RpcServer
public static <T extends CoprocessorEnvironment> ObserverContext<T> createAndPrepare(
T env, ObserverContext<T> context) {
if (context == null) {
context = new ObserverContext<T>();
context = new ObserverContext<T>(RpcServer.getRequestUser());
}
context.prepare(env);
return context;
}
/**
* Instantiates a new ObserverContext instance if the passed reference is
* <code>null</code> and sets the environment in the new or existing instance.
* This allows deferring the instantiation of a ObserverContext until it is
* actually needed.
*
* @param env The coprocessor environment to set
* @param context An existing ObserverContext instance to use, or <code>null</code>
* to create a new instance
* @param user The requesting caller for the execution context
* @param <T> The environment type for the context
* @return An instance of <code>ObserverContext</code> with the environment set
*/
public static <T extends CoprocessorEnvironment> ObserverContext<T> createAndPrepare(
T env, ObserverContext<T> context, User user) {
if (context == null) {
context = new ObserverContext<T>(user);
}
context.prepare(env);
return context;

View File

@ -44,10 +44,12 @@ import org.apache.hadoop.hbase.coprocessor.CoprocessorService;
import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.MasterObserver;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.ipc.RpcServer;
import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
import org.apache.hadoop.hbase.security.User;
/**
* Provides the coprocessor framework and environment for master oriented
@ -240,9 +242,10 @@ public class MasterCoprocessorHost
});
}
public void preCreateTableAction(final HTableDescriptor htd, final HRegionInfo[] regions)
public void preCreateTableAction(final HTableDescriptor htd, final HRegionInfo[] regions,
final User user)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -253,8 +256,8 @@ public class MasterCoprocessorHost
}
public void postCompletedCreateTableAction(
final HTableDescriptor htd, final HRegionInfo[] regions) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
final HTableDescriptor htd, final HRegionInfo[] regions, final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -284,8 +287,8 @@ public class MasterCoprocessorHost
});
}
public void preDeleteTableAction(final TableName tableName) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
public void preDeleteTableAction(final TableName tableName, final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -295,8 +298,9 @@ public class MasterCoprocessorHost
});
}
public void postCompletedDeleteTableAction(final TableName tableName) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
public void postCompletedDeleteTableAction(final TableName tableName, final User user)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -326,8 +330,8 @@ public class MasterCoprocessorHost
});
}
public void preTruncateTableAction(final TableName tableName) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
public void preTruncateTableAction(final TableName tableName, final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -337,8 +341,9 @@ public class MasterCoprocessorHost
});
}
public void postCompletedTruncateTableAction(final TableName tableName) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
public void postCompletedTruncateTableAction(final TableName tableName, final User user)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -370,9 +375,10 @@ public class MasterCoprocessorHost
});
}
public void preModifyTableAction(final TableName tableName, final HTableDescriptor htd)
public void preModifyTableAction(final TableName tableName, final HTableDescriptor htd,
final User user)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -382,9 +388,10 @@ public class MasterCoprocessorHost
});
}
public void postCompletedModifyTableAction(final TableName tableName, final HTableDescriptor htd)
public void postCompletedModifyTableAction(final TableName tableName, final HTableDescriptor htd,
final User user)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -420,9 +427,10 @@ public class MasterCoprocessorHost
public boolean preAddColumnFamilyAction(
final TableName tableName,
final HColumnDescriptor columnFamily)
final HColumnDescriptor columnFamily,
final User user)
throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -434,9 +442,10 @@ public class MasterCoprocessorHost
public void postCompletedAddColumnFamilyAction(
final TableName tableName,
final HColumnDescriptor columnFamily)
final HColumnDescriptor columnFamily,
final User user)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -472,8 +481,9 @@ public class MasterCoprocessorHost
public boolean preModifyColumnFamilyAction(
final TableName tableName,
final HColumnDescriptor columnFamily) throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
final HColumnDescriptor columnFamily,
final User user) throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -485,8 +495,9 @@ public class MasterCoprocessorHost
public void postCompletedModifyColumnFamilyAction(
final TableName tableName,
final HColumnDescriptor columnFamily) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
final HColumnDescriptor columnFamily,
final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -522,9 +533,10 @@ public class MasterCoprocessorHost
public boolean preDeleteColumnFamilyAction(
final TableName tableName,
final byte[] columnFamily)
final byte[] columnFamily,
final User user)
throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -535,8 +547,8 @@ public class MasterCoprocessorHost
}
public void postCompletedDeleteColumnFamilyAction(
final TableName tableName, final byte[] columnFamily) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
final TableName tableName, final byte[] columnFamily, final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -566,8 +578,8 @@ public class MasterCoprocessorHost
});
}
public void preEnableTableAction(final TableName tableName) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
public void preEnableTableAction(final TableName tableName, final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -577,8 +589,9 @@ public class MasterCoprocessorHost
});
}
public void postCompletedEnableTableAction(final TableName tableName) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
public void postCompletedEnableTableAction(final TableName tableName, final User user)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -608,8 +621,8 @@ public class MasterCoprocessorHost
});
}
public void preDisableTableAction(final TableName tableName) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
public void preDisableTableAction(final TableName tableName, final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -619,8 +632,9 @@ public class MasterCoprocessorHost
});
}
public void postCompletedDisableTableAction(final TableName tableName) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
public void postCompletedDisableTableAction(final TableName tableName, final User user)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
@ -1168,6 +1182,11 @@ public class MasterCoprocessorHost
private static abstract class CoprocessorOperation
extends ObserverContext<MasterCoprocessorEnvironment> {
public CoprocessorOperation() {
this(RpcServer.getRequestUser());
}
public CoprocessorOperation(User user) {
super(user);
}
public abstract void call(MasterObserver oserver,

View File

@ -67,13 +67,13 @@ import org.apache.hadoop.hbase.protobuf.generated.ClusterStatusProtos.StoreSeque
import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.SplitLogTask.RecoveryMode;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.regionserver.RegionOpeningState;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.hbase.util.RetryCounter;
import org.apache.hadoop.hbase.util.RetryCounterFactory;
import org.apache.hadoop.hbase.zookeeper.ZKUtil;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.zookeeper.KeeperException;
import com.google.common.annotations.VisibleForTesting;
@ -884,7 +884,7 @@ public class ServerManager {
* @throws IOException
*/
public void sendRegionsMerge(ServerName server, HRegionInfo region_a,
HRegionInfo region_b, boolean forcible, final UserGroupInformation user) throws IOException {
HRegionInfo region_b, boolean forcible, final User user) throws IOException {
if (server == null)
throw new NullPointerException("Passed server is null");
if (region_a == null || region_b == null)

View File

@ -21,7 +21,6 @@ package org.apache.hadoop.hbase.master.procedure;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.PrivilegedExceptionAction;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@ -39,7 +38,7 @@ import org.apache.hadoop.hbase.procedure2.StateMachineProcedure;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.AddColumnFamilyState;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.hbase.security.User;
/**
* The procedure to add a column family to an existing table.
@ -55,7 +54,7 @@ public class AddColumnFamilyProcedure
private TableName tableName;
private HTableDescriptor unmodifiedHTableDescriptor;
private HColumnDescriptor cfDescriptor;
private UserGroupInformation user;
private User user;
private List<HRegionInfo> regionInfoList;
private Boolean traceEnabled;
@ -72,8 +71,8 @@ public class AddColumnFamilyProcedure
final HColumnDescriptor cfDescriptor) throws IOException {
this.tableName = tableName;
this.cfDescriptor = cfDescriptor;
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
this.unmodifiedHTableDescriptor = null;
this.regionInfoList = null;
this.traceEnabled = null;
@ -378,22 +377,16 @@ public class AddColumnFamilyProcedure
throws IOException, InterruptedException {
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
switch (state) {
case ADD_COLUMN_FAMILY_PRE_OPERATION:
cpHost.preAddColumnFamilyAction(tableName, cfDescriptor);
cpHost.preAddColumnFamilyAction(tableName, cfDescriptor, user);
break;
case ADD_COLUMN_FAMILY_POST_OPERATION:
cpHost.postCompletedAddColumnFamilyAction(tableName, cfDescriptor);
cpHost.postCompletedAddColumnFamilyAction(tableName, cfDescriptor, user);
break;
default:
throw new UnsupportedOperationException(this + " unhandled state=" + state);
}
return null;
}
});
}
}

View File

@ -53,6 +53,7 @@ import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.CloneSnapshotState;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.FSTableDescriptors;
import org.apache.hadoop.hbase.util.FSUtils;
import org.apache.hadoop.hbase.util.Pair;
@ -62,7 +63,6 @@ import org.apache.hadoop.hbase.snapshot.RestoreSnapshotException;
import org.apache.hadoop.hbase.snapshot.RestoreSnapshotHelper;
import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
import org.apache.hadoop.hbase.snapshot.SnapshotManifest;
import org.apache.hadoop.security.UserGroupInformation;
import com.google.common.base.Preconditions;
@ -74,7 +74,7 @@ public class CloneSnapshotProcedure
private final AtomicBoolean aborted = new AtomicBoolean(false);
private UserGroupInformation user;
private User user;
private HTableDescriptor hTableDescriptor;
private SnapshotDescription snapshot;
private List<HRegionInfo> newRegions = null;
@ -106,8 +106,8 @@ public class CloneSnapshotProcedure
throws IOException {
this.hTableDescriptor = hTableDescriptor;
this.snapshot = snapshot;
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
getMonitorStatus();
}
@ -372,13 +372,7 @@ public class CloneSnapshotProcedure
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
cpHost.preCreateTableAction(hTableDescriptor, null);
return null;
}
});
cpHost.preCreateTableAction(hTableDescriptor, null, user);
}
}
@ -394,13 +388,7 @@ public class CloneSnapshotProcedure
if (cpHost != null) {
final HRegionInfo[] regions = (newRegions == null) ? null :
newRegions.toArray(new HRegionInfo[newRegions.size()]);
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
cpHost.postCompletedCreateTableAction(hTableDescriptor, regions);
return null;
}
});
cpHost.postCompletedCreateTableAction(hTableDescriptor, regions, user);
}
}

View File

@ -47,11 +47,11 @@ import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.CreateTableState;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.FSTableDescriptors;
import org.apache.hadoop.hbase.util.FSUtils;
import org.apache.hadoop.hbase.util.ModifyRegionUtils;
import org.apache.hadoop.hbase.util.ServerRegionReplicaUtil;
import org.apache.hadoop.security.UserGroupInformation;
import com.google.common.collect.Lists;
@ -68,7 +68,7 @@ public class CreateTableProcedure
private HTableDescriptor hTableDescriptor;
private List<HRegionInfo> newRegions;
private UserGroupInformation user;
private User user;
public CreateTableProcedure() {
// Required by the Procedure framework to create the procedure on replay
@ -87,8 +87,8 @@ public class CreateTableProcedure
throws IOException {
this.hTableDescriptor = hTableDescriptor;
this.newRegions = newRegions != null ? Lists.newArrayList(newRegions) : null;
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
// used for compatibility with clients without procedures
// they need a sync TableExistsException
@ -307,13 +307,7 @@ public class CreateTableProcedure
if (cpHost != null) {
final HRegionInfo[] regions = newRegions == null ? null :
newRegions.toArray(new HRegionInfo[newRegions.size()]);
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
cpHost.preCreateTableAction(hTableDescriptor, regions);
return null;
}
});
cpHost.preCreateTableAction(hTableDescriptor, regions, user);
}
}
@ -323,13 +317,7 @@ public class CreateTableProcedure
if (cpHost != null) {
final HRegionInfo[] regions = (newRegions == null) ? null :
newRegions.toArray(new HRegionInfo[newRegions.size()]);
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
cpHost.postCompletedCreateTableAction(hTableDescriptor, regions);
return null;
}
});
cpHost.postCompletedCreateTableAction(hTableDescriptor, regions, user);
}
}

View File

@ -38,9 +38,9 @@ import org.apache.hadoop.hbase.procedure2.StateMachineProcedure;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.DeleteColumnFamilyState;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.ByteStringer;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.security.UserGroupInformation;
/**
* The procedure to delete a column family from an existing table.
@ -57,7 +57,7 @@ public class DeleteColumnFamilyProcedure
private TableName tableName;
private byte [] familyName;
private boolean hasMob;
private UserGroupInformation user;
private User user;
private List<HRegionInfo> regionInfoList;
private Boolean traceEnabled;
@ -74,8 +74,8 @@ public class DeleteColumnFamilyProcedure
final byte[] familyName) throws IOException {
this.tableName = tableName;
this.familyName = familyName;
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
this.unmodifiedHTableDescriptor = null;
this.regionInfoList = null;
this.traceEnabled = null;
@ -403,22 +403,16 @@ public class DeleteColumnFamilyProcedure
final DeleteColumnFamilyState state) throws IOException, InterruptedException {
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
switch (state) {
case DELETE_COLUMN_FAMILY_PRE_OPERATION:
cpHost.preDeleteColumnFamilyAction(tableName, familyName);
cpHost.preDeleteColumnFamilyAction(tableName, familyName, user);
break;
case DELETE_COLUMN_FAMILY_POST_OPERATION:
cpHost.postCompletedDeleteColumnFamilyAction(tableName, familyName);
cpHost.postCompletedDeleteColumnFamilyAction(tableName, familyName, user);
break;
default:
throw new UnsupportedOperationException(this + " unhandled state=" + state);
}
return null;
}
});
}
}

View File

@ -55,8 +55,8 @@ import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.DeleteTableState;
import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.FSUtils;
import org.apache.hadoop.security.UserGroupInformation;
@InterfaceAudience.Private
public class DeleteTableProcedure
@ -65,7 +65,7 @@ public class DeleteTableProcedure
private static final Log LOG = LogFactory.getLog(DeleteTableProcedure.class);
private List<HRegionInfo> regions;
private UserGroupInformation user;
private User user;
private TableName tableName;
// used for compatibility with old clients
@ -84,8 +84,8 @@ public class DeleteTableProcedure
public DeleteTableProcedure(final MasterProcedureEnv env, final TableName tableName,
final ProcedurePrepareLatch syncLatch) throws IOException {
this.tableName = tableName;
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
// used for compatibility with clients without procedures
// they need a sync TableNotFoundException, TableNotDisabledException, ...
@ -266,13 +266,7 @@ public class DeleteTableProcedure
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
final TableName tableName = this.tableName;
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
cpHost.preDeleteTableAction(tableName);
return null;
}
});
cpHost.preDeleteTableAction(tableName, user);
}
return true;
}
@ -284,13 +278,7 @@ public class DeleteTableProcedure
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
final TableName tableName = this.tableName;
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
cpHost.postCompletedDeleteTableAction(tableName);
return null;
}
});
cpHost.postCompletedDeleteTableAction(tableName, user);
}
}

View File

@ -46,6 +46,7 @@ import org.apache.hadoop.hbase.procedure2.StateMachineProcedure;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.DisableTableState;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.htrace.Trace;
@ -63,7 +64,7 @@ public class DisableTableProcedure
private TableName tableName;
private boolean skipTableStateCheck;
private UserGroupInformation user;
private User user;
private Boolean traceEnabled = null;
@ -105,8 +106,8 @@ public class DisableTableProcedure
final ProcedurePrepareLatch syncLatch) throws IOException {
this.tableName = tableName;
this.skipTableStateCheck = skipTableStateCheck;
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
// Compatible with 1.0: We use latch to make sure that this procedure implementation is
// compatible with 1.0 asynchronized operations. We need to lock the table and check
@ -458,22 +459,16 @@ public class DisableTableProcedure
throws IOException, InterruptedException {
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
switch (state) {
case DISABLE_TABLE_PRE_OPERATION:
cpHost.preDisableTableAction(tableName);
cpHost.preDisableTableAction(tableName, user);
break;
case DISABLE_TABLE_POST_OPERATION:
cpHost.postCompletedDisableTableAction(tableName);
cpHost.postCompletedDisableTableAction(tableName, user);
break;
default:
throw new UnsupportedOperationException(this + " unhandled state=" + state);
}
return null;
}
});
}
}

View File

@ -46,8 +46,8 @@ import org.apache.hadoop.hbase.procedure2.StateMachineProcedure;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.DispatchMergingRegionsState;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.security.UserGroupInformation;
/**
* The procedure to Merge a region in a table.
@ -66,7 +66,7 @@ implements TableProcedureInterface {
private String regionsToMergeListFullName;
private String regionsToMergeListEncodedName;
private UserGroupInformation user;
private User user;
private TableName tableName;
private HRegionInfo [] regionsToMerge;
private boolean forcible;
@ -94,8 +94,8 @@ implements TableProcedureInterface {
this.regionsToMerge = regionsToMerge;
this.forcible = forcible;
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
this.timeout = -1;
this.regionsToMergeListFullName = getRegionsToMergeListFullNameString();

View File

@ -50,9 +50,9 @@ import org.apache.hadoop.hbase.procedure2.StateMachineProcedure;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.EnableTableState;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.hbase.zookeeper.MetaTableLocator;
import org.apache.hadoop.security.UserGroupInformation;
@InterfaceAudience.Private
public class EnableTableProcedure
@ -67,7 +67,7 @@ public class EnableTableProcedure
private TableName tableName;
private boolean skipTableStateCheck;
private UserGroupInformation user;
private User user;
private Boolean traceEnabled = null;
@ -103,8 +103,8 @@ public class EnableTableProcedure
final ProcedurePrepareLatch syncLatch) throws IOException {
this.tableName = tableName;
this.skipTableStateCheck = skipTableStateCheck;
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
// Compatible with 1.0: We use latch to make sure that this procedure implementation is
// compatible with 1.0 asynchronized operations. We need to lock the table and check
@ -561,22 +561,16 @@ public class EnableTableProcedure
throws IOException, InterruptedException {
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
switch (state) {
case ENABLE_TABLE_PRE_OPERATION:
cpHost.preEnableTableAction(getTableName());
cpHost.preEnableTableAction(getTableName(), user);
break;
case ENABLE_TABLE_POST_OPERATION:
cpHost.postCompletedEnableTableAction(getTableName());
cpHost.postCompletedEnableTableAction(getTableName(), user);
break;
default:
throw new UnsupportedOperationException(this + " unhandled state=" + state);
}
return null;
}
});
}
}
}

View File

@ -23,6 +23,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.classification.InterfaceStability;
import org.apache.hadoop.hbase.protobuf.generated.RPCProtos.UserInformation;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.security.UserGroupInformation;
@InterfaceAudience.Private
@ -32,24 +33,24 @@ public final class MasterProcedureUtil {
private MasterProcedureUtil() {}
public static UserInformation toProtoUserInfo(UserGroupInformation ugi) {
public static UserInformation toProtoUserInfo(User user) {
UserInformation.Builder userInfoPB = UserInformation.newBuilder();
userInfoPB.setEffectiveUser(ugi.getUserName());
if (ugi.getRealUser() != null) {
userInfoPB.setRealUser(ugi.getRealUser().getUserName());
userInfoPB.setEffectiveUser(user.getName());
if (user.getUGI().getRealUser() != null) {
userInfoPB.setRealUser(user.getUGI().getRealUser().getUserName());
}
return userInfoPB.build();
}
public static UserGroupInformation toUserInfo(UserInformation userInfoProto) {
public static User toUserInfo(UserInformation userInfoProto) {
if (userInfoProto.hasEffectiveUser()) {
String effectiveUser = userInfoProto.getEffectiveUser();
if (userInfoProto.hasRealUser()) {
String realUser = userInfoProto.getRealUser();
UserGroupInformation realUserUgi = UserGroupInformation.createRemoteUser(realUser);
return UserGroupInformation.createProxyUser(effectiveUser, realUserUgi);
return User.create(UserGroupInformation.createProxyUser(effectiveUser, realUserUgi));
}
return UserGroupInformation.createRemoteUser(effectiveUser);
return User.create(UserGroupInformation.createRemoteUser(effectiveUser));
}
return null;
}

View File

@ -39,7 +39,7 @@ import org.apache.hadoop.hbase.procedure2.StateMachineProcedure;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.ModifyColumnFamilyState;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.hbase.security.User;
/**
* The procedure to modify a column family from an existing table.
@ -55,7 +55,7 @@ public class ModifyColumnFamilyProcedure
private TableName tableName;
private HTableDescriptor unmodifiedHTableDescriptor;
private HColumnDescriptor cfDescriptor;
private UserGroupInformation user;
private User user;
private Boolean traceEnabled;
@ -70,8 +70,8 @@ public class ModifyColumnFamilyProcedure
final HColumnDescriptor cfDescriptor) throws IOException {
this.tableName = tableName;
this.cfDescriptor = cfDescriptor;
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
this.unmodifiedHTableDescriptor = null;
this.traceEnabled = null;
}
@ -359,22 +359,16 @@ public class ModifyColumnFamilyProcedure
final ModifyColumnFamilyState state) throws IOException, InterruptedException {
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
switch (state) {
case MODIFY_COLUMN_FAMILY_PRE_OPERATION:
cpHost.preModifyColumnFamilyAction(tableName, cfDescriptor);
cpHost.preModifyColumnFamilyAction(tableName, cfDescriptor, user);
break;
case MODIFY_COLUMN_FAMILY_POST_OPERATION:
cpHost.postCompletedModifyColumnFamilyAction(tableName, cfDescriptor);
cpHost.postCompletedModifyColumnFamilyAction(tableName, cfDescriptor, user);
break;
default:
throw new UnsupportedOperationException(this + " unhandled state=" + state);
}
return null;
}
});
}
}
}

View File

@ -49,8 +49,8 @@ import org.apache.hadoop.hbase.procedure2.StateMachineProcedure;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.ModifyTableState;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.ServerRegionReplicaUtil;
import org.apache.hadoop.security.UserGroupInformation;
@InterfaceAudience.Private
public class ModifyTableProcedure
@ -62,7 +62,7 @@ public class ModifyTableProcedure
private HTableDescriptor unmodifiedHTableDescriptor = null;
private HTableDescriptor modifiedHTableDescriptor;
private UserGroupInformation user;
private User user;
private boolean deleteColumnFamilyInModify;
private List<HRegionInfo> regionInfoList;
@ -77,8 +77,8 @@ public class ModifyTableProcedure
final HTableDescriptor htd) throws IOException {
initilize();
this.modifiedHTableDescriptor = htd;
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
}
private void initilize() {
@ -467,22 +467,16 @@ public class ModifyTableProcedure
throws IOException, InterruptedException {
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
switch (state) {
case MODIFY_TABLE_PRE_OPERATION:
cpHost.preModifyTableAction(getTableName(), modifiedHTableDescriptor);
cpHost.preModifyTableAction(getTableName(), modifiedHTableDescriptor, user);
break;
case MODIFY_TABLE_POST_OPERATION:
cpHost.postCompletedModifyTableAction(getTableName(), modifiedHTableDescriptor);
cpHost.postCompletedModifyTableAction(getTableName(), modifiedHTableDescriptor, user);
break;
default:
throw new UnsupportedOperationException(this + " unhandled state=" + state);
}
return null;
}
});
}
}

View File

@ -53,12 +53,12 @@ import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.RestoreSnapshotState;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
import org.apache.hadoop.hbase.snapshot.RestoreSnapshotHelper;
import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
import org.apache.hadoop.hbase.snapshot.SnapshotManifest;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.security.UserGroupInformation;
@InterfaceAudience.Private
public class RestoreSnapshotProcedure
@ -75,7 +75,7 @@ public class RestoreSnapshotProcedure
private Map<String, Pair<String, String>> parentsToChildrenPairMap =
new HashMap<String, Pair<String, String>>();
private UserGroupInformation user;
private User user;
private SnapshotDescription snapshot;
// Monitor
@ -106,8 +106,8 @@ public class RestoreSnapshotProcedure
// Snapshot information
this.snapshot = snapshot;
// User and owner information
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
// Monitor
getMonitorStatus();

View File

@ -41,8 +41,8 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.TruncateTableState;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.procedure2.StateMachineProcedure;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.ModifyRegionUtils;
import org.apache.hadoop.security.UserGroupInformation;
@InterfaceAudience.Private
public class TruncateTableProcedure
@ -52,7 +52,7 @@ public class TruncateTableProcedure
private boolean preserveSplits;
private List<HRegionInfo> regions;
private UserGroupInformation user;
private User user;
private HTableDescriptor hTableDescriptor;
private TableName tableName;
@ -64,8 +64,8 @@ public class TruncateTableProcedure
boolean preserveSplits) throws IOException {
this.tableName = tableName;
this.preserveSplits = preserveSplits;
this.user = env.getRequestUser().getUGI();
this.setOwner(this.user.getShortUserName());
this.user = env.getRequestUser();
this.setOwner(this.user.getShortName());
}
@Override
@ -261,13 +261,7 @@ public class TruncateTableProcedure
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
final TableName tableName = getTableName();
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
cpHost.preTruncateTableAction(tableName);
return null;
}
});
cpHost.preTruncateTableAction(tableName, user);
}
return true;
}
@ -277,13 +271,7 @@ public class TruncateTableProcedure
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
final TableName tableName = getTableName();
user.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
cpHost.postCompletedTruncateTableAction(tableName);
return null;
}
});
cpHost.postCompletedTruncateTableAction(tableName, user);
}
}
}

View File

@ -1284,23 +1284,7 @@ public class HStore implements Store {
final StoreFile sf = moveFileIntoPlace(newFile);
if (this.getCoprocessorHost() != null) {
final Store thisStore = this;
if (user == null) {
getCoprocessorHost().postCompact(thisStore, sf, cr);
} else {
try {
user.getUGI().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
getCoprocessorHost().postCompact(thisStore, sf, cr);
return null;
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
getCoprocessorHost().postCompact(thisStore, sf, cr, user);
}
assert sf != null;
sfs.add(sf);
@ -1507,7 +1491,7 @@ public class HStore implements Store {
// Move the compaction into place.
StoreFile sf = moveFileIntoPlace(newFile);
if (this.getCoprocessorHost() != null) {
this.getCoprocessorHost().postCompact(this, sf, null);
this.getCoprocessorHost().postCompact(this, sf, null, null);
}
replaceStoreFiles(filesToCompact, Lists.newArrayList(sf));
completeCompaction(filesToCompact);
@ -1568,29 +1552,12 @@ public class HStore implements Store {
this.lock.readLock().lock();
try {
synchronized (filesCompacting) {
final Store thisStore = this;
// First, see if coprocessor would want to override selection.
if (this.getCoprocessorHost() != null) {
final List<StoreFile> candidatesForCoproc = compaction.preSelect(this.filesCompacting);
boolean override = false;
if (user == null) {
override = getCoprocessorHost().preCompactSelection(this, candidatesForCoproc,
baseRequest);
} else {
try {
override = user.getUGI().doAs(new PrivilegedExceptionAction<Boolean>() {
@Override
public Boolean run() throws Exception {
return getCoprocessorHost().preCompactSelection(thisStore, candidatesForCoproc,
baseRequest);
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
baseRequest, user);
if (override) {
// Coprocessor is overriding normal file selection.
compaction.forceSelect(new CompactionRequest(candidatesForCoproc));
@ -1618,25 +1585,8 @@ public class HStore implements Store {
}
}
if (this.getCoprocessorHost() != null) {
if (user == null) {
this.getCoprocessorHost().postCompactSelection(
this, ImmutableList.copyOf(compaction.getRequest().getFiles()), baseRequest);
} else {
try {
user.getUGI().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
getCoprocessorHost().postCompactSelection(
thisStore,ImmutableList.copyOf(compaction.getRequest().getFiles()),baseRequest);
return null;
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
this, ImmutableList.copyOf(compaction.getRequest().getFiles()), baseRequest, user);
}
// Selected files; see if we have a compaction with some custom base request.

View File

@ -74,9 +74,11 @@ import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper;
import org.apache.hadoop.hbase.io.Reference;
import org.apache.hadoop.hbase.io.hfile.CacheConfig;
import org.apache.hadoop.hbase.ipc.RpcServer;
import org.apache.hadoop.hbase.regionserver.Region.Operation;
import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.wal.WALKey;
import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
import org.apache.hadoop.hbase.util.Bytes;
@ -532,9 +534,9 @@ public class RegionCoprocessorHost
*/
public InternalScanner preCompactScannerOpen(final Store store,
final List<StoreFileScanner> scanners, final ScanType scanType, final long earliestPutTs,
final CompactionRequest request) throws IOException {
final CompactionRequest request, final User user) throws IOException {
return execOperationWithResult(null,
coprocessors.isEmpty() ? null : new RegionOperationWithResult<InternalScanner>() {
coprocessors.isEmpty() ? null : new RegionOperationWithResult<InternalScanner>(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -554,8 +556,8 @@ public class RegionCoprocessorHost
* @throws IOException
*/
public boolean preCompactSelection(final Store store, final List<StoreFile> candidates,
final CompactionRequest request) throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new RegionOperation() {
final CompactionRequest request, final User user) throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new RegionOperation(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -572,9 +574,9 @@ public class RegionCoprocessorHost
* @param request custom compaction
*/
public void postCompactSelection(final Store store, final ImmutableList<StoreFile> selected,
final CompactionRequest request) {
final CompactionRequest request, final User user) {
try {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation() {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -595,9 +597,10 @@ public class RegionCoprocessorHost
* @throws IOException
*/
public InternalScanner preCompact(final Store store, final InternalScanner scanner,
final ScanType scanType, final CompactionRequest request) throws IOException {
final ScanType scanType, final CompactionRequest request, final User user)
throws IOException {
return execOperationWithResult(false, scanner,
coprocessors.isEmpty() ? null : new RegionOperationWithResult<InternalScanner>() {
coprocessors.isEmpty() ? null : new RegionOperationWithResult<InternalScanner>(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -614,8 +617,8 @@ public class RegionCoprocessorHost
* @throws IOException
*/
public void postCompact(final Store store, final StoreFile resultFile,
final CompactionRequest request) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation() {
final CompactionRequest request, final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -704,8 +707,8 @@ public class RegionCoprocessorHost
* @throws IOException
*/
// TODO: Deprecate this
public void preSplit() throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation() {
public void preSplit(final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -718,8 +721,8 @@ public class RegionCoprocessorHost
* Invoked just before a split
* @throws IOException
*/
public void preSplit(final byte[] splitRow) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation() {
public void preSplit(final byte[] splitRow, final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -734,8 +737,8 @@ public class RegionCoprocessorHost
* @param r the new right-hand daughter region
* @throws IOException
*/
public void postSplit(final Region l, final Region r) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation() {
public void postSplit(final Region l, final Region r, final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -745,8 +748,8 @@ public class RegionCoprocessorHost
}
public boolean preSplitBeforePONR(final byte[] splitKey,
final List<Mutation> metaEntries) throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new RegionOperation() {
final List<Mutation> metaEntries, final User user) throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new RegionOperation(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -755,8 +758,8 @@ public class RegionCoprocessorHost
});
}
public void preSplitAfterPONR() throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation() {
public void preSplitAfterPONR(final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -769,8 +772,8 @@ public class RegionCoprocessorHost
* Invoked just before the rollback of a failed split is started
* @throws IOException
*/
public void preRollBackSplit() throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation() {
public void preRollBackSplit(final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -783,8 +786,8 @@ public class RegionCoprocessorHost
* Invoked just after the rollback of a failed split is done
* @throws IOException
*/
public void postRollBackSplit() throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation() {
public void postRollBackSplit(final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new RegionOperation(user) {
@Override
public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx)
throws IOException {
@ -1656,6 +1659,14 @@ public class RegionCoprocessorHost
private static abstract class CoprocessorOperation
extends ObserverContext<RegionCoprocessorEnvironment> {
public CoprocessorOperation() {
this(RpcServer.getRequestUser());
}
public CoprocessorOperation(User user) {
super(user);
}
public abstract void call(Coprocessor observer,
ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException;
public abstract boolean hasCall(Coprocessor observer);
@ -1663,6 +1674,13 @@ public class RegionCoprocessorHost
}
private static abstract class RegionOperation extends CoprocessorOperation {
public RegionOperation() {
}
public RegionOperation(User user) {
super(user);
}
public abstract void call(RegionObserver observer,
ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException;
@ -1677,6 +1695,13 @@ public class RegionCoprocessorHost
}
private static abstract class RegionOperationWithResult<T> extends RegionOperation {
public RegionOperationWithResult() {
}
public RegionOperationWithResult(User user) {
super (user);
}
private T result = null;
public void setResult(final T result) { this.result = result; }
public T getResult() { return this.result; }

View File

@ -247,23 +247,7 @@ public class RegionMergeTransactionImpl implements RegionMergeTransaction {
}
final HRegion mergedRegion = createMergedRegion(server, services, user);
if (rsCoprocessorHost != null) {
if (user == null) {
rsCoprocessorHost.postMergeCommit(this.region_a, this.region_b, mergedRegion);
} else {
try {
user.getUGI().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
rsCoprocessorHost.postMergeCommit(region_a, region_b, mergedRegion);
return null;
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
rsCoprocessorHost.postMergeCommit(this.region_a, this.region_b, mergedRegion, user);
}
stepsAfterPONR(server, services, mergedRegion, user);
@ -277,23 +261,7 @@ public class RegionMergeTransactionImpl implements RegionMergeTransaction {
final HRegion mergedRegion, User user) throws IOException {
openMergedRegion(server, services, mergedRegion);
if (rsCoprocessorHost != null) {
if (user == null) {
rsCoprocessorHost.postMerge(region_a, region_b, mergedRegion);
} else {
try {
user.getUGI().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
rsCoprocessorHost.postMerge(region_a, region_b, mergedRegion);
return null;
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
rsCoprocessorHost.postMerge(region_a, region_b, mergedRegion, user);
}
}
@ -315,23 +283,7 @@ public class RegionMergeTransactionImpl implements RegionMergeTransaction {
}
if (rsCoprocessorHost != null) {
boolean ret = false;
if (user == null) {
ret = rsCoprocessorHost.preMerge(region_a, region_b);
} else {
try {
ret = user.getUGI().doAs(new PrivilegedExceptionAction<Boolean>() {
@Override
public Boolean run() throws Exception {
return rsCoprocessorHost.preMerge(region_a, region_b);
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
boolean ret = rsCoprocessorHost.preMerge(region_a, region_b, user);
if (ret) {
throw new IOException("Coprocessor bypassing regions " + this.region_a + " "
+ this.region_b + " merge.");
@ -347,23 +299,7 @@ public class RegionMergeTransactionImpl implements RegionMergeTransaction {
@MetaMutationAnnotation
final List<Mutation> metaEntries = new ArrayList<Mutation>();
if (rsCoprocessorHost != null) {
boolean ret = false;
if (user == null) {
ret = rsCoprocessorHost.preMergeCommit(region_a, region_b, metaEntries);
} else {
try {
ret = user.getUGI().doAs(new PrivilegedExceptionAction<Boolean>() {
@Override
public Boolean run() throws Exception {
return rsCoprocessorHost.preMergeCommit(region_a, region_b, metaEntries);
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
boolean ret = rsCoprocessorHost.preMergeCommit(region_a, region_b, metaEntries, user);
if (ret) {
throw new IOException("Coprocessor bypassing regions " + this.region_a + " "
@ -658,23 +594,7 @@ public class RegionMergeTransactionImpl implements RegionMergeTransaction {
this.rsServices = services;
// Coprocessor callback
if (rsCoprocessorHost != null) {
if (user == null) {
rsCoprocessorHost.preRollBackMerge(region_a, region_b);
} else {
try {
user.getUGI().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
rsCoprocessorHost.preRollBackMerge(region_a, region_b);
return null;
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
rsCoprocessorHost.preRollBackMerge(region_a, region_b, user);
}
boolean result = true;
@ -759,23 +679,7 @@ public class RegionMergeTransactionImpl implements RegionMergeTransaction {
}
// Coprocessor callback
if (rsCoprocessorHost != null) {
if (user == null) {
rsCoprocessorHost.postRollBackMerge(region_a, region_b);
} else {
try {
user.getUGI().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
rsCoprocessorHost.postRollBackMerge(region_a, region_b);
return null;
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
rsCoprocessorHost.postRollBackMerge(region_a, region_b, user);
}
return result;

View File

@ -39,8 +39,10 @@ import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.RegionServerObserver;
import org.apache.hadoop.hbase.coprocessor.SingletonCoprocessorService;
import org.apache.hadoop.hbase.ipc.RpcServer;
import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.WALEntry;
import org.apache.hadoop.hbase.replication.ReplicationEndpoint;
import org.apache.hadoop.hbase.security.User;
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
@InterfaceStability.Evolving
@ -91,8 +93,8 @@ public class RegionServerCoprocessorHost extends
});
}
public boolean preMerge(final HRegion regionA, final HRegion regionB) throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
public boolean preMerge(final HRegion regionA, final HRegion regionB, final User user) throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(RegionServerObserver oserver,
ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException {
@ -101,9 +103,10 @@ public class RegionServerCoprocessorHost extends
});
}
public void postMerge(final HRegion regionA, final HRegion regionB, final HRegion mergedRegion)
public void postMerge(final HRegion regionA, final HRegion regionB, final HRegion mergedRegion,
final User user)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(RegionServerObserver oserver,
ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException {
@ -113,8 +116,9 @@ public class RegionServerCoprocessorHost extends
}
public boolean preMergeCommit(final HRegion regionA, final HRegion regionB,
final @MetaMutationAnnotation List<Mutation> metaEntries) throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
final @MetaMutationAnnotation List<Mutation> metaEntries, final User user)
throws IOException {
return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(RegionServerObserver oserver,
ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException {
@ -124,8 +128,8 @@ public class RegionServerCoprocessorHost extends
}
public void postMergeCommit(final HRegion regionA, final HRegion regionB,
final HRegion mergedRegion) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
final HRegion mergedRegion, final User user) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(RegionServerObserver oserver,
ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException {
@ -134,8 +138,9 @@ public class RegionServerCoprocessorHost extends
});
}
public void preRollBackMerge(final HRegion regionA, final HRegion regionB) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
public void preRollBackMerge(final HRegion regionA, final HRegion regionB, final User user)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(RegionServerObserver oserver,
ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException {
@ -144,8 +149,9 @@ public class RegionServerCoprocessorHost extends
});
}
public void postRollBackMerge(final HRegion regionA, final HRegion regionB) throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
public void postRollBackMerge(final HRegion regionA, final HRegion regionB, final User user)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) {
@Override
public void call(RegionServerObserver oserver,
ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException {
@ -220,6 +226,11 @@ public class RegionServerCoprocessorHost extends
private static abstract class CoprocessorOperation
extends ObserverContext<RegionServerCoprocessorEnvironment> {
public CoprocessorOperation() {
this(RpcServer.getRequestUser());
}
public CoprocessorOperation(User user) {
super(user);
}
public abstract void call(RegionServerObserver oserver,

View File

@ -151,7 +151,7 @@ public class SecureBulkLoadManager {
if (bulkLoadObservers != null && bulkLoadObservers.size() != 0) {
ObserverContext<RegionCoprocessorEnvironment> ctx =
new ObserverContext<RegionCoprocessorEnvironment>();
new ObserverContext<RegionCoprocessorEnvironment>(getActiveUser());
ctx.prepare((RegionCoprocessorEnvironment) region.getCoprocessorHost()
.findCoprocessorEnvironment(BulkLoadObserver.class).get(0));
@ -173,7 +173,7 @@ public class SecureBulkLoadManager {
if (bulkLoadObservers != null && bulkLoadObservers.size() != 0) {
ObserverContext<RegionCoprocessorEnvironment> ctx =
new ObserverContext<RegionCoprocessorEnvironment>();
new ObserverContext<RegionCoprocessorEnvironment>(getActiveUser());
ctx.prepare((RegionCoprocessorEnvironment) region.getCoprocessorHost()
.findCoprocessorEnvironment(BulkLoadObserver.class).get(0));

View File

@ -228,26 +228,9 @@ public class SplitTransactionImpl implements SplitTransaction {
// Coprocessor callback
if (this.parent.getCoprocessorHost() != null) {
if (user == null) {
// TODO: Remove one of these
parent.getCoprocessorHost().preSplit();
parent.getCoprocessorHost().preSplit(splitrow);
} else {
try {
user.getUGI().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
parent.getCoprocessorHost().preSplit();
parent.getCoprocessorHost().preSplit(splitrow);
return null;
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
parent.getCoprocessorHost().preSplit(user);
parent.getCoprocessorHost().preSplit(splitrow, user);
}
transition(SplitTransactionPhase.AFTER_PRE_SPLIT_HOOK);
@ -264,22 +247,7 @@ public class SplitTransactionImpl implements SplitTransaction {
final List<Mutation> metaEntries = new ArrayList<Mutation>();
boolean ret = false;
if (this.parent.getCoprocessorHost() != null) {
if (user == null) {
ret = parent.getCoprocessorHost().preSplitBeforePONR(splitrow, metaEntries);
} else {
try {
ret = user.getUGI().doAs(new PrivilegedExceptionAction<Boolean>() {
@Override
public Boolean run() throws Exception {
return parent.getCoprocessorHost().preSplitBeforePONR(splitrow, metaEntries);
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
ret = parent.getCoprocessorHost().preSplitBeforePONR(splitrow, metaEntries, user);
if (ret) {
throw new IOException("Coprocessor bypassing region "
+ parent.getRegionInfo().getRegionNameAsString() + " split.");
@ -510,23 +478,7 @@ public class SplitTransactionImpl implements SplitTransaction {
final RegionServerServices services, final PairOfSameType<Region> regions, User user)
throws IOException {
if (this.parent.getCoprocessorHost() != null) {
if (user == null) {
parent.getCoprocessorHost().preSplitAfterPONR();
} else {
try {
user.getUGI().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
parent.getCoprocessorHost().preSplitAfterPONR();
return null;
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
parent.getCoprocessorHost().preSplitAfterPONR(user);
}
openDaughters(server, services, regions.getFirst(), regions.getSecond());
@ -535,23 +487,7 @@ public class SplitTransactionImpl implements SplitTransaction {
// Coprocessor callback
if (parent.getCoprocessorHost() != null) {
if (user == null) {
this.parent.getCoprocessorHost().postSplit(regions.getFirst(), regions.getSecond());
} else {
try {
user.getUGI().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
parent.getCoprocessorHost().postSplit(regions.getFirst(), regions.getSecond());
return null;
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
this.parent.getCoprocessorHost().postSplit(regions.getFirst(), regions.getSecond(), user);
}
transition(SplitTransactionPhase.AFTER_POST_SPLIT_HOOK);
@ -780,23 +716,7 @@ public class SplitTransactionImpl implements SplitTransaction {
this.rsServices = services;
// Coprocessor callback
if (this.parent.getCoprocessorHost() != null) {
if (user == null) {
this.parent.getCoprocessorHost().preRollBackSplit();
} else {
try {
user.getUGI().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
parent.getCoprocessorHost().preRollBackSplit();
return null;
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
this.parent.getCoprocessorHost().preRollBackSplit(user);
}
boolean result = true;
@ -875,23 +795,7 @@ public class SplitTransactionImpl implements SplitTransaction {
}
// Coprocessor callback
if (this.parent.getCoprocessorHost() != null) {
if (user == null) {
this.parent.getCoprocessorHost().postRollBackSplit();
} else {
try {
user.getUGI().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
parent.getCoprocessorHost().postRollBackSplit();
return null;
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
this.parent.getCoprocessorHost().postRollBackSplit(user);
}
return result;
}

View File

@ -357,24 +357,8 @@ public abstract class Compactor<T extends CellSink> {
if (store.getCoprocessorHost() == null) {
return null;
}
if (user == null) {
return store.getCoprocessorHost().preCompactScannerOpen(store, scanners, scanType,
earliestPutTs, request);
} else {
try {
return user.getUGI().doAs(new PrivilegedExceptionAction<InternalScanner>() {
@Override
public InternalScanner run() throws Exception {
return store.getCoprocessorHost().preCompactScannerOpen(store, scanners,
scanType, earliestPutTs, request);
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
earliestPutTs, request, user);
}
/**
@ -389,22 +373,7 @@ public abstract class Compactor<T extends CellSink> {
if (store.getCoprocessorHost() == null) {
return scanner;
}
if (user == null) {
return store.getCoprocessorHost().preCompact(store, scanner, scanType, request);
} else {
try {
return user.getUGI().doAs(new PrivilegedExceptionAction<InternalScanner>() {
@Override
public InternalScanner run() throws Exception {
return store.getCoprocessorHost().preCompact(store, scanner, scanType, request);
}
});
} catch (InterruptedException ie) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(ie);
throw iioe;
}
}
return store.getCoprocessorHost().preCompact(store, scanner, scanType, request, user);
}
/**

View File

@ -414,8 +414,8 @@ public class AccessController extends BaseMasterAndRegionObserver
* If we are in the context of an RPC call, the remote user is used,
* otherwise the currently logged in user is used.
*/
private User getActiveUser() throws IOException {
User user = RpcServer.getRequestUser();
private User getActiveUser(ObserverContext ctx) throws IOException {
User user = ctx.getCaller();
if (user == null) {
// for non-rpc handling, fallback to system user
user = userProvider.getCurrent();
@ -432,9 +432,8 @@ public class AccessController extends BaseMasterAndRegionObserver
* @throws IOException if obtaining the current user fails
* @throws AccessDeniedException if user has no authorization
*/
private void requirePermission(String request, TableName tableName, byte[] family,
private void requirePermission(User user, String request, TableName tableName, byte[] family,
byte[] qualifier, Action... permissions) throws IOException {
User user = getActiveUser();
AuthResult result = null;
for (Action permission : permissions) {
@ -463,9 +462,8 @@ public class AccessController extends BaseMasterAndRegionObserver
* @throws IOException if obtaining the current user fails
* @throws AccessDeniedException if user has no authorization
*/
private void requireTablePermission(String request, TableName tableName, byte[] family,
private void requireTablePermission(User user, String request, TableName tableName, byte[] family,
byte[] qualifier, Action... permissions) throws IOException {
User user = getActiveUser();
AuthResult result = null;
for (Action permission : permissions) {
@ -495,9 +493,8 @@ public class AccessController extends BaseMasterAndRegionObserver
* @throws IOException if obtaining the current user fails
* @throws AccessDeniedException if user has no authorization
*/
private void requireAccess(String request, TableName tableName,
private void requireAccess(User user, String request, TableName tableName,
Action... permissions) throws IOException {
User user = getActiveUser();
AuthResult result = null;
for (Action permission : permissions) {
@ -523,8 +520,8 @@ public class AccessController extends BaseMasterAndRegionObserver
* @throws IOException if obtaining the current user fails
* @throws AccessDeniedException if authorization is denied
*/
private void requirePermission(String request, Action perm) throws IOException {
requireGlobalPermission(request, perm, null, null);
private void requirePermission(User user, String request, Action perm) throws IOException {
requireGlobalPermission(user, request, perm, null, null);
}
/**
@ -535,9 +532,8 @@ public class AccessController extends BaseMasterAndRegionObserver
* @param tableName Affected table name.
* @param familyMap Affected column families.
*/
private void requireGlobalPermission(String request, Action perm, TableName tableName,
private void requireGlobalPermission(User user, String request, Action perm, TableName tableName,
Map<byte[], ? extends Collection<byte[]>> familyMap) throws IOException {
User user = getActiveUser();
AuthResult result = null;
if (authManager.authorize(user, perm)) {
result = AuthResult.allow(request, "Global check allowed", user, perm, tableName, familyMap);
@ -562,9 +558,8 @@ public class AccessController extends BaseMasterAndRegionObserver
* @param perm Action being requested
* @param namespace
*/
private void requireGlobalPermission(String request, Action perm,
private void requireGlobalPermission(User user, String request, Action perm,
String namespace) throws IOException {
User user = getActiveUser();
AuthResult authResult = null;
if (authManager.authorize(user, perm)) {
authResult = AuthResult.allow(request, "Global check allowed", user, perm, null);
@ -587,9 +582,8 @@ public class AccessController extends BaseMasterAndRegionObserver
* @param namespace
* @param permissions Actions being requested
*/
public void requireNamespacePermission(String request, String namespace,
public void requireNamespacePermission(User user, String request, String namespace,
Action... permissions) throws IOException {
User user = getActiveUser();
AuthResult result = null;
for (Action permission : permissions) {
@ -615,10 +609,10 @@ public class AccessController extends BaseMasterAndRegionObserver
* @param namespace
* @param permissions Actions being requested
*/
public void requireNamespacePermission(String request, String namespace, TableName tableName,
Map<byte[], ? extends Collection<byte[]>> familyMap, Action... permissions)
public void requireNamespacePermission(User user, String request, String namespace,
TableName tableName, Map<byte[], ? extends Collection<byte[]>> familyMap,
Action... permissions)
throws IOException {
User user = getActiveUser();
AuthResult result = null;
for (Action permission : permissions) {
@ -711,14 +705,13 @@ public class AccessController extends BaseMasterAndRegionObserver
* @return false if cell ACLs failed to grant access, true otherwise
* @throws IOException
*/
private boolean checkCoveringPermission(OpType request, RegionCoprocessorEnvironment e,
private boolean checkCoveringPermission(User user, OpType request, RegionCoprocessorEnvironment e,
byte[] row, Map<byte[], ? extends Collection<?>> familyMap, long opTs, Action... actions)
throws IOException {
if (!cellFeaturesEnabled) {
return false;
}
long cellGrants = 0;
User user = getActiveUser();
long latestCellTs = 0;
Get get = new Get(row);
// Only in case of Put/Delete op, consider TS within cell (if set for individual cells).
@ -1000,8 +993,8 @@ public class AccessController extends BaseMasterAndRegionObserver
for (byte[] family: families) {
familyMap.put(family, null);
}
requireNamespacePermission("createTable", desc.getTableName().getNamespaceAsString(),
desc.getTableName(), familyMap, Action.CREATE);
requireNamespacePermission(getActiveUser(c), "createTable",
desc.getTableName().getNamespaceAsString(), desc.getTableName(), familyMap, Action.CREATE);
}
@Override
@ -1035,7 +1028,7 @@ public class AccessController extends BaseMasterAndRegionObserver
String owner = desc.getOwnerString();
// default the table owner to current user, if not specified.
if (owner == null)
owner = getActiveUser().getShortName();
owner = getActiveUser(c).getShortName();
final UserPermission userperm = new UserPermission(Bytes.toBytes(owner),
desc.getTableName(), null, Action.values());
// switch to the real hbase master user for doing the RPC on the ACL table
@ -1054,7 +1047,8 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName)
throws IOException {
requirePermission("deleteTable", tableName, null, null, Action.ADMIN, Action.CREATE);
requirePermission(getActiveUser(c), "deleteTable", tableName, null, null,
Action.ADMIN, Action.CREATE);
}
@Override
@ -1074,7 +1068,8 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preTruncateTable(ObserverContext<MasterCoprocessorEnvironment> c,
final TableName tableName) throws IOException {
requirePermission("truncateTable", tableName, null, null, Action.ADMIN, Action.CREATE);
requirePermission(getActiveUser(c), "truncateTable", tableName, null, null,
Action.ADMIN, Action.CREATE);
final Configuration conf = c.getEnvironment().getConfiguration();
User.runAsLoginUser(new PrivilegedExceptionAction<Void>() {
@ -1111,7 +1106,8 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preModifyTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName,
HTableDescriptor htd) throws IOException {
requirePermission("modifyTable", tableName, null, null, Action.ADMIN, Action.CREATE);
requirePermission(getActiveUser(c), "modifyTable", tableName, null, null,
Action.ADMIN, Action.CREATE);
}
@Override
@ -1120,7 +1116,7 @@ public class AccessController extends BaseMasterAndRegionObserver
final Configuration conf = c.getEnvironment().getConfiguration();
// default the table owner to current user, if not specified.
final String owner = (htd.getOwnerString() != null) ? htd.getOwnerString() :
getActiveUser().getShortName();
getActiveUser(c).getShortName();
User.runAsLoginUser(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
@ -1136,22 +1132,23 @@ public class AccessController extends BaseMasterAndRegionObserver
public void preAddColumnFamily(ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName, HColumnDescriptor columnFamily)
throws IOException {
requireTablePermission("addColumn", tableName, columnFamily.getName(), null, Action.ADMIN,
Action.CREATE);
requireTablePermission(getActiveUser(ctx), "addColumn", tableName, columnFamily.getName(), null,
Action.ADMIN, Action.CREATE);
}
@Override
public void preModifyColumnFamily(ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName, HColumnDescriptor columnFamily)
throws IOException {
requirePermission("modifyColumn", tableName, columnFamily.getName(), null, Action.ADMIN,
Action.CREATE);
requirePermission(getActiveUser(ctx), "modifyColumn", tableName, columnFamily.getName(), null,
Action.ADMIN, Action.CREATE);
}
@Override
public void preDeleteColumnFamily(ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName, byte[] columnFamily) throws IOException {
requirePermission("deleteColumn", tableName, columnFamily, null, Action.ADMIN, Action.CREATE);
requirePermission(getActiveUser(ctx), "deleteColumn", tableName, columnFamily, null,
Action.ADMIN, Action.CREATE);
}
@Override
@ -1170,7 +1167,8 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preEnableTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName)
throws IOException {
requirePermission("enableTable", tableName, null, null, Action.ADMIN, Action.CREATE);
requirePermission(getActiveUser(c), "enableTable", tableName, null, null,
Action.ADMIN, Action.CREATE);
}
@Override
@ -1184,7 +1182,8 @@ public class AccessController extends BaseMasterAndRegionObserver
throw new AccessDeniedException("Not allowed to disable "
+ AccessControlLists.ACL_TABLE_NAME + " table with AccessController installed");
}
requirePermission("disableTable", tableName, null, null, Action.ADMIN, Action.CREATE);
requirePermission(getActiveUser(c), "disableTable", tableName, null, null,
Action.ADMIN, Action.CREATE);
}
@Override
@ -1192,10 +1191,10 @@ public class AccessController extends BaseMasterAndRegionObserver
ObserverContext<MasterCoprocessorEnvironment> ctx,
final ProcedureExecutor<MasterProcedureEnv> procEnv,
final long procId) throws IOException {
if (!procEnv.isProcedureOwner(procId, getActiveUser())) {
if (!procEnv.isProcedureOwner(procId, getActiveUser(ctx))) {
// If the user is not the procedure owner, then we should further probe whether
// he can abort the procedure.
requirePermission("abortProcedure", Action.ADMIN);
requirePermission(getActiveUser(ctx), "abortProcedure", Action.ADMIN);
}
}
@ -1223,14 +1222,14 @@ public class AccessController extends BaseMasterAndRegionObserver
// Retains only those which passes authorization checks, as the checks weren't done as part
// of preListProcedures.
Iterator<ProcedureInfo> itr = procInfoList.iterator();
User user = getActiveUser();
User user = getActiveUser(ctx);
while (itr.hasNext()) {
ProcedureInfo procInfo = itr.next();
try {
if (!ProcedureInfo.isProcedureOwner(procInfo, user)) {
// If the user is not the procedure owner, then we should further probe whether
// he can see the procedure.
requirePermission("listProcedures", Action.ADMIN);
requirePermission(user, "listProcedures", Action.ADMIN);
}
} catch (AccessDeniedException e) {
itr.remove();
@ -1241,31 +1240,32 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preMove(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo region,
ServerName srcServer, ServerName destServer) throws IOException {
requirePermission("move", region.getTable(), null, null, Action.ADMIN);
requirePermission(getActiveUser(c), "move", region.getTable(), null, null, Action.ADMIN);
}
@Override
public void preAssign(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo)
throws IOException {
requirePermission("assign", regionInfo.getTable(), null, null, Action.ADMIN);
requirePermission(getActiveUser(c), "assign", regionInfo.getTable(), null, null, Action.ADMIN);
}
@Override
public void preUnassign(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo,
boolean force) throws IOException {
requirePermission("unassign", regionInfo.getTable(), null, null, Action.ADMIN);
requirePermission(getActiveUser(c), "unassign", regionInfo.getTable(), null, null, Action.ADMIN);
}
@Override
public void preRegionOffline(ObserverContext<MasterCoprocessorEnvironment> c,
HRegionInfo regionInfo) throws IOException {
requirePermission("regionOffline", regionInfo.getTable(), null, null, Action.ADMIN);
requirePermission(getActiveUser(c), "regionOffline", regionInfo.getTable(), null, null,
Action.ADMIN);
}
@Override
public boolean preSetSplitOrMergeEnabled(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final boolean newValue, final MasterSwitchType switchType) throws IOException {
requirePermission("setSplitOrMergeEnabled", Action.ADMIN);
requirePermission(getActiveUser(ctx), "setSplitOrMergeEnabled", Action.ADMIN);
return false;
}
@ -1277,26 +1277,26 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preBalance(ObserverContext<MasterCoprocessorEnvironment> c)
throws IOException {
requirePermission("balance", Action.ADMIN);
requirePermission(getActiveUser(c), "balance", Action.ADMIN);
}
@Override
public boolean preBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> c,
boolean newValue) throws IOException {
requirePermission("balanceSwitch", Action.ADMIN);
requirePermission(getActiveUser(c), "balanceSwitch", Action.ADMIN);
return newValue;
}
@Override
public void preShutdown(ObserverContext<MasterCoprocessorEnvironment> c)
throws IOException {
requirePermission("shutdown", Action.ADMIN);
requirePermission(getActiveUser(c), "shutdown", Action.ADMIN);
}
@Override
public void preStopMaster(ObserverContext<MasterCoprocessorEnvironment> c)
throws IOException {
requirePermission("stopMaster", Action.ADMIN);
requirePermission(getActiveUser(c), "stopMaster", Action.ADMIN);
}
@Override
@ -1315,18 +1315,19 @@ public class AccessController extends BaseMasterAndRegionObserver
public void preSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
throws IOException {
requirePermission("snapshot", hTableDescriptor.getTableName(), null, null,
requirePermission(getActiveUser(ctx), "snapshot", hTableDescriptor.getTableName(), null, null,
Permission.Action.ADMIN);
}
@Override
public void preListSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx,
final SnapshotDescription snapshot) throws IOException {
if (SnapshotDescriptionUtils.isSnapshotOwner(snapshot, getActiveUser())) {
User user = getActiveUser(ctx);
if (SnapshotDescriptionUtils.isSnapshotOwner(snapshot, user)) {
// list it, if user is the owner of snapshot
// TODO: We are not logging this for audit
} else {
requirePermission("listSnapshot", Action.ADMIN);
requirePermission(user, "listSnapshot", Action.ADMIN);
}
}
@ -1334,42 +1335,44 @@ public class AccessController extends BaseMasterAndRegionObserver
public void preCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
throws IOException {
requirePermission("clone", Action.ADMIN);
requirePermission(getActiveUser(ctx), "clone", Action.ADMIN);
}
@Override
public void preRestoreSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
throws IOException {
if (SnapshotDescriptionUtils.isSnapshotOwner(snapshot, getActiveUser())) {
requirePermission("restoreSnapshot", hTableDescriptor.getTableName(), null, null,
User user = getActiveUser(ctx);
if (SnapshotDescriptionUtils.isSnapshotOwner(snapshot, user)) {
requirePermission(user, "restoreSnapshot", hTableDescriptor.getTableName(), null, null,
Permission.Action.ADMIN);
} else {
requirePermission("restoreSnapshot", Action.ADMIN);
requirePermission(user, "restoreSnapshot", Action.ADMIN);
}
}
@Override
public void preDeleteSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final SnapshotDescription snapshot) throws IOException {
if (SnapshotDescriptionUtils.isSnapshotOwner(snapshot, getActiveUser())) {
User user = getActiveUser(ctx);
if (SnapshotDescriptionUtils.isSnapshotOwner(snapshot, user)) {
// Snapshot owner is allowed to delete the snapshot
// TODO: We are not logging this for audit
} else {
requirePermission("deleteSnapshot", Action.ADMIN);
requirePermission(user, "deleteSnapshot", Action.ADMIN);
}
}
@Override
public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx,
NamespaceDescriptor ns) throws IOException {
requireGlobalPermission("createNamespace", Action.ADMIN, ns.getName());
requireGlobalPermission(getActiveUser(ctx), "createNamespace", Action.ADMIN, ns.getName());
}
@Override
public void preDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace)
throws IOException {
requireGlobalPermission("deleteNamespace", Action.ADMIN, namespace);
requireGlobalPermission(getActiveUser(ctx), "deleteNamespace", Action.ADMIN, namespace);
}
@Override
@ -1392,13 +1395,13 @@ public class AccessController extends BaseMasterAndRegionObserver
NamespaceDescriptor ns) throws IOException {
// We require only global permission so that
// a user with NS admin cannot altering namespace configurations. i.e. namespace quota
requireGlobalPermission("modifyNamespace", Action.ADMIN, ns.getName());
requireGlobalPermission(getActiveUser(ctx), "modifyNamespace", Action.ADMIN, ns.getName());
}
@Override
public void preGetNamespaceDescriptor(ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace)
throws IOException {
requireNamespacePermission("getNamespaceDescriptor", namespace, Action.ADMIN);
requireNamespacePermission(getActiveUser(ctx), "getNamespaceDescriptor", namespace, Action.ADMIN);
}
@Override
@ -1407,10 +1410,11 @@ public class AccessController extends BaseMasterAndRegionObserver
// Retains only those which passes authorization checks, as the checks weren't done as part
// of preGetTableDescriptors.
Iterator<NamespaceDescriptor> itr = descriptors.iterator();
User user = getActiveUser(ctx);
while (itr.hasNext()) {
NamespaceDescriptor desc = itr.next();
try {
requireNamespacePermission("listNamespaces", desc.getName(), Action.ADMIN);
requireNamespacePermission(user, "listNamespaces", desc.getName(), Action.ADMIN);
} catch (AccessDeniedException e) {
itr.remove();
}
@ -1420,24 +1424,25 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preTableFlush(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final TableName tableName) throws IOException {
requirePermission("flushTable", tableName, null, null, Action.ADMIN, Action.CREATE);
requirePermission(getActiveUser(ctx), "flushTable", tableName, null, null,
Action.ADMIN, Action.CREATE);
}
/* ---- RegionObserver implementation ---- */
@Override
public void preOpen(ObserverContext<RegionCoprocessorEnvironment> e)
public void preOpen(ObserverContext<RegionCoprocessorEnvironment> c)
throws IOException {
RegionCoprocessorEnvironment env = e.getEnvironment();
RegionCoprocessorEnvironment env = c.getEnvironment();
final Region region = env.getRegion();
if (region == null) {
LOG.error("NULL region from RegionCoprocessorEnvironment in preOpen()");
} else {
HRegionInfo regionInfo = region.getRegionInfo();
if (regionInfo.getTable().isSystemTable()) {
checkSystemOrSuperUser();
checkSystemOrSuperUser(getActiveUser(c));
} else {
requirePermission("preOpen", Action.ADMIN);
requirePermission(getActiveUser(c), "preOpen", Action.ADMIN);
}
}
}
@ -1481,28 +1486,30 @@ public class AccessController extends BaseMasterAndRegionObserver
}
@Override
public void preFlush(ObserverContext<RegionCoprocessorEnvironment> e) throws IOException {
requirePermission("flush", getTableName(e.getEnvironment()), null, null, Action.ADMIN,
Action.CREATE);
public void preFlush(ObserverContext<RegionCoprocessorEnvironment> c) throws IOException {
requirePermission(getActiveUser(c), "flush", getTableName(c.getEnvironment()), null, null,
Action.ADMIN, Action.CREATE);
}
@Override
public void preSplit(ObserverContext<RegionCoprocessorEnvironment> e) throws IOException {
requirePermission("split", getTableName(e.getEnvironment()), null, null, Action.ADMIN);
public void preSplit(ObserverContext<RegionCoprocessorEnvironment> c) throws IOException {
requirePermission(getActiveUser(c), "split", getTableName(c.getEnvironment()), null, null,
Action.ADMIN);
}
@Override
public void preSplit(ObserverContext<RegionCoprocessorEnvironment> e,
public void preSplit(ObserverContext<RegionCoprocessorEnvironment> c,
byte[] splitRow) throws IOException {
requirePermission("split", getTableName(e.getEnvironment()), null, null, Action.ADMIN);
requirePermission(getActiveUser(c), "split", getTableName(c.getEnvironment()), null, null,
Action.ADMIN);
}
@Override
public InternalScanner preCompact(ObserverContext<RegionCoprocessorEnvironment> e,
public InternalScanner preCompact(ObserverContext<RegionCoprocessorEnvironment> c,
final Store store, final InternalScanner scanner, final ScanType scanType)
throws IOException {
requirePermission("compact", getTableName(e.getEnvironment()), null, null, Action.ADMIN,
Action.CREATE);
requirePermission(getActiveUser(c), "compact", getTableName(c.getEnvironment()), null, null,
Action.ADMIN, Action.CREATE);
return scanner;
}
@ -1513,7 +1520,7 @@ public class AccessController extends BaseMasterAndRegionObserver
if (filter != null && filter instanceof AccessControlFilter) {
return;
}
User user = getActiveUser();
User user = getActiveUser(c);
RegionCoprocessorEnvironment env = c.getEnvironment();
Map<byte[],? extends Collection<byte[]>> families = null;
switch (opType) {
@ -1626,7 +1633,7 @@ public class AccessController extends BaseMasterAndRegionObserver
public void prePut(final ObserverContext<RegionCoprocessorEnvironment> c,
final Put put, final WALEdit edit, final Durability durability)
throws IOException {
User user = getActiveUser();
User user = getActiveUser(c);
checkForReservedTagPresence(user, put);
// Require WRITE permission to the table, CF, or top visible value, if any.
@ -1681,7 +1688,7 @@ public class AccessController extends BaseMasterAndRegionObserver
// by a tombstone already) then we have to disallow this operation.
RegionCoprocessorEnvironment env = c.getEnvironment();
Map<byte[],? extends Collection<Cell>> families = delete.getFamilyCellMap();
User user = getActiveUser();
User user = getActiveUser(c);
AuthResult authResult = permissionGranted(OpType.DELETE, user, env, families, Action.WRITE);
logResult(authResult);
if (!authResult.isAllowed()) {
@ -1699,6 +1706,7 @@ public class AccessController extends BaseMasterAndRegionObserver
MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
if (cellFeaturesEnabled && !compatibleEarlyTermination) {
TableName table = c.getEnvironment().getRegion().getRegionInfo().getTable();
User user = getActiveUser(c);
for (int i = 0; i < miniBatchOp.size(); i++) {
Mutation m = miniBatchOp.getOperation(i);
if (m.getAttribute(CHECK_COVERING_PERM) != null) {
@ -1706,19 +1714,19 @@ public class AccessController extends BaseMasterAndRegionObserver
// perm check
OpType opType;
if (m instanceof Put) {
checkForReservedTagPresence(getActiveUser(), m);
checkForReservedTagPresence(user, m);
opType = OpType.PUT;
} else {
opType = OpType.DELETE;
}
AuthResult authResult = null;
if (checkCoveringPermission(opType, c.getEnvironment(), m.getRow(),
if (checkCoveringPermission(user, opType, c.getEnvironment(), m.getRow(),
m.getFamilyCellMap(), m.getTimeStamp(), Action.WRITE)) {
authResult = AuthResult.allow(opType.toString(), "Covering cell set",
getActiveUser(), Action.WRITE, table, m.getFamilyCellMap());
user, Action.WRITE, table, m.getFamilyCellMap());
} else {
authResult = AuthResult.deny(opType.toString(), "Covering cell set",
getActiveUser(), Action.WRITE, table, m.getFamilyCellMap());
user, Action.WRITE, table, m.getFamilyCellMap());
}
logResult(authResult);
if (authorizationEnabled && !authResult.isAllowed()) {
@ -1745,7 +1753,7 @@ public class AccessController extends BaseMasterAndRegionObserver
final CompareFilter.CompareOp compareOp,
final ByteArrayComparable comparator, final Put put,
final boolean result) throws IOException {
User user = getActiveUser();
User user = getActiveUser(c);
checkForReservedTagPresence(user, put);
// Require READ and WRITE permissions on the table, CF, and KV to update
@ -1785,13 +1793,14 @@ public class AccessController extends BaseMasterAndRegionObserver
TableName table = c.getEnvironment().getRegion().getRegionInfo().getTable();
Map<byte[], ? extends Collection<byte[]>> families = makeFamilyMap(family, qualifier);
AuthResult authResult = null;
if (checkCoveringPermission(OpType.CHECK_AND_PUT, c.getEnvironment(), row, families,
User user = getActiveUser(c);
if (checkCoveringPermission(user, OpType.CHECK_AND_PUT, c.getEnvironment(), row, families,
HConstants.LATEST_TIMESTAMP, Action.READ)) {
authResult = AuthResult.allow(OpType.CHECK_AND_PUT.toString(), "Covering cell set",
getActiveUser(), Action.READ, table, families);
user, Action.READ, table, families);
} else {
authResult = AuthResult.deny(OpType.CHECK_AND_PUT.toString(), "Covering cell set",
getActiveUser(), Action.READ, table, families);
user, Action.READ, table, families);
}
logResult(authResult);
if (authorizationEnabled && !authResult.isAllowed()) {
@ -1816,7 +1825,7 @@ public class AccessController extends BaseMasterAndRegionObserver
// by the delete
RegionCoprocessorEnvironment env = c.getEnvironment();
Map<byte[],? extends Collection<byte[]>> families = makeFamilyMap(family, qualifier);
User user = getActiveUser();
User user = getActiveUser(c);
AuthResult authResult = permissionGranted(OpType.CHECK_AND_DELETE, user, env, families,
Action.READ, Action.WRITE);
logResult(authResult);
@ -1843,13 +1852,14 @@ public class AccessController extends BaseMasterAndRegionObserver
TableName table = c.getEnvironment().getRegion().getRegionInfo().getTable();
Map<byte[], ? extends Collection<byte[]>> families = makeFamilyMap(family, qualifier);
AuthResult authResult = null;
if (checkCoveringPermission(OpType.CHECK_AND_DELETE, c.getEnvironment(), row, families,
User user = getActiveUser(c);
if (checkCoveringPermission(user, OpType.CHECK_AND_DELETE, c.getEnvironment(), row, families,
HConstants.LATEST_TIMESTAMP, Action.READ)) {
authResult = AuthResult.allow(OpType.CHECK_AND_DELETE.toString(), "Covering cell set",
getActiveUser(), Action.READ, table, families);
user, Action.READ, table, families);
} else {
authResult = AuthResult.deny(OpType.CHECK_AND_DELETE.toString(), "Covering cell set",
getActiveUser(), Action.READ, table, families);
user, Action.READ, table, families);
}
logResult(authResult);
if (authorizationEnabled && !authResult.isAllowed()) {
@ -1868,11 +1878,11 @@ public class AccessController extends BaseMasterAndRegionObserver
// incremented value
RegionCoprocessorEnvironment env = c.getEnvironment();
Map<byte[],? extends Collection<byte[]>> families = makeFamilyMap(family, qualifier);
User user = getActiveUser();
User user = getActiveUser(c);
AuthResult authResult = permissionGranted(OpType.INCREMENT_COLUMN_VALUE, user, env, families,
Action.WRITE);
if (!authResult.isAllowed() && cellFeaturesEnabled && !compatibleEarlyTermination) {
authResult.setAllowed(checkCoveringPermission(OpType.INCREMENT_COLUMN_VALUE, env, row,
authResult.setAllowed(checkCoveringPermission(user, OpType.INCREMENT_COLUMN_VALUE, env, row,
families, HConstants.LATEST_TIMESTAMP, Action.WRITE));
authResult.setReason("Covering cell set");
}
@ -1886,7 +1896,7 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public Result preAppend(ObserverContext<RegionCoprocessorEnvironment> c, Append append)
throws IOException {
User user = getActiveUser();
User user = getActiveUser(c);
checkForReservedTagPresence(user, append);
// Require WRITE permission to the table, CF, and the KV to be appended
@ -1923,13 +1933,14 @@ public class AccessController extends BaseMasterAndRegionObserver
// perm check
TableName table = c.getEnvironment().getRegion().getRegionInfo().getTable();
AuthResult authResult = null;
if (checkCoveringPermission(OpType.APPEND, c.getEnvironment(), append.getRow(),
User user = getActiveUser(c);
if (checkCoveringPermission(user, OpType.APPEND, c.getEnvironment(), append.getRow(),
append.getFamilyCellMap(), HConstants.LATEST_TIMESTAMP, Action.WRITE)) {
authResult = AuthResult.allow(OpType.APPEND.toString(), "Covering cell set",
getActiveUser(), Action.WRITE, table, append.getFamilyCellMap());
user, Action.WRITE, table, append.getFamilyCellMap());
} else {
authResult = AuthResult.deny(OpType.APPEND.toString(), "Covering cell set",
getActiveUser(), Action.WRITE, table, append.getFamilyCellMap());
user, Action.WRITE, table, append.getFamilyCellMap());
}
logResult(authResult);
if (authorizationEnabled && !authResult.isAllowed()) {
@ -1944,7 +1955,7 @@ public class AccessController extends BaseMasterAndRegionObserver
public Result preIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
final Increment increment)
throws IOException {
User user = getActiveUser();
User user = getActiveUser(c);
checkForReservedTagPresence(user, increment);
// Require WRITE permission to the table, CF, and the KV to be replaced by
@ -1983,13 +1994,14 @@ public class AccessController extends BaseMasterAndRegionObserver
// perm check
TableName table = c.getEnvironment().getRegion().getRegionInfo().getTable();
AuthResult authResult = null;
if (checkCoveringPermission(OpType.INCREMENT, c.getEnvironment(), increment.getRow(),
User user = getActiveUser(c);
if (checkCoveringPermission(user, OpType.INCREMENT, c.getEnvironment(), increment.getRow(),
increment.getFamilyCellMap(), increment.getTimeRange().getMax(), Action.WRITE)) {
authResult = AuthResult.allow(OpType.INCREMENT.toString(), "Covering cell set",
getActiveUser(), Action.WRITE, table, increment.getFamilyCellMap());
user, Action.WRITE, table, increment.getFamilyCellMap());
} else {
authResult = AuthResult.deny(OpType.INCREMENT.toString(), "Covering cell set",
getActiveUser(), Action.WRITE, table, increment.getFamilyCellMap());
user, Action.WRITE, table, increment.getFamilyCellMap());
}
logResult(authResult);
if (authorizationEnabled && !authResult.isAllowed()) {
@ -2067,7 +2079,7 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public RegionScanner postScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
final Scan scan, final RegionScanner s) throws IOException {
User user = getActiveUser();
User user = getActiveUser(c);
if (user != null && user.getShortName() != null) {
// store reference to scanner owner for later checks
scannerOwners.put(s, user.getShortName());
@ -2127,8 +2139,9 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preBulkLoadHFile(ObserverContext<RegionCoprocessorEnvironment> ctx,
List<Pair<byte[], String>> familyPaths) throws IOException {
User user = getActiveUser(ctx);
for(Pair<byte[],String> el : familyPaths) {
requirePermission("preBulkLoadHFile",
requirePermission(user, "preBulkLoadHFile",
ctx.getEnvironment().getRegion().getTableDesc().getTableName(),
el.getFirst(),
null,
@ -2146,7 +2159,7 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void prePrepareBulkLoad(ObserverContext<RegionCoprocessorEnvironment> ctx,
PrepareBulkLoadRequest request) throws IOException {
requireAccess("prePareBulkLoad",
requireAccess(getActiveUser(ctx), "prePrepareBulkLoad",
ctx.getEnvironment().getRegion().getTableDesc().getTableName(), Action.CREATE);
}
@ -2160,7 +2173,7 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preCleanupBulkLoad(ObserverContext<RegionCoprocessorEnvironment> ctx,
CleanupBulkLoadRequest request) throws IOException {
requireAccess("preCleanupBulkLoad",
requireAccess(getActiveUser(ctx), "preCleanupBulkLoad",
ctx.getEnvironment().getRegion().getTableDesc().getTableName(), Action.CREATE);
}
@ -2172,8 +2185,8 @@ public class AccessController extends BaseMasterAndRegionObserver
// Don't intercept calls to our own AccessControlService, we check for
// appropriate permissions in the service handlers
if (shouldCheckExecPermission && !(service instanceof AccessControlService)) {
requirePermission("invoke(" + service.getDescriptorForType().getName() + "." +
methodName + ")",
requirePermission(getActiveUser(ctx),
"invoke(" + service.getDescriptorForType().getName() + "." + methodName + ")",
getTableName(ctx.getEnvironment()), null, null,
Action.EXEC);
}
@ -2202,15 +2215,16 @@ public class AccessController extends BaseMasterAndRegionObserver
if (LOG.isDebugEnabled()) {
LOG.debug("Received request to grant access permission " + perm.toString());
}
User caller = RpcServer.getRequestUser();
switch(request.getUserPermission().getPermission().getType()) {
case Global :
case Table :
requirePermission("grant", perm.getTableName(), perm.getFamily(),
perm.getQualifier(), Action.ADMIN);
requirePermission(caller, "grant", perm.getTableName(),
perm.getFamily(), perm.getQualifier(), Action.ADMIN);
break;
case Namespace :
requireNamespacePermission("grant", perm.getNamespace(), Action.ADMIN);
requireNamespacePermission(caller, "grant", perm.getNamespace(), Action.ADMIN);
break;
}
@ -2253,15 +2267,16 @@ public class AccessController extends BaseMasterAndRegionObserver
if (LOG.isDebugEnabled()) {
LOG.debug("Received request to revoke access permission " + perm.toString());
}
User caller = RpcServer.getRequestUser();
switch(request.getUserPermission().getPermission().getType()) {
case Global :
case Table :
requirePermission("revoke", perm.getTableName(), perm.getFamily(),
requirePermission(caller, "revoke", perm.getTableName(), perm.getFamily(),
perm.getQualifier(), Action.ADMIN);
break;
case Namespace :
requireNamespacePermission("revoke", perm.getNamespace(), Action.ADMIN);
requireNamespacePermission(caller, "revoke", perm.getNamespace(), Action.ADMIN);
break;
}
@ -2300,11 +2315,13 @@ public class AccessController extends BaseMasterAndRegionObserver
if (!initialized) {
throw new CoprocessorException("AccessController not yet initialized");
}
User caller = RpcServer.getRequestUser();
List<UserPermission> perms = null;
if (request.getType() == AccessControlProtos.Permission.Type.Table) {
final TableName table = request.hasTableName() ?
ProtobufUtil.toTableName(request.getTableName()) : null;
requirePermission("userPermissions", table, null, null, Action.ADMIN);
requirePermission(caller, "userPermissions", table, null, null, Action.ADMIN);
perms = User.runAsLoginUser(new PrivilegedExceptionAction<List<UserPermission>>() {
@Override
public List<UserPermission> run() throws Exception {
@ -2313,7 +2330,7 @@ public class AccessController extends BaseMasterAndRegionObserver
});
} else if (request.getType() == AccessControlProtos.Permission.Type.Namespace) {
final String namespace = request.getNamespaceName().toStringUtf8();
requireNamespacePermission("userPermissions", namespace, Action.ADMIN);
requireNamespacePermission(caller, "userPermissions", namespace, Action.ADMIN);
perms = User.runAsLoginUser(new PrivilegedExceptionAction<List<UserPermission>>() {
@Override
public List<UserPermission> run() throws Exception {
@ -2322,7 +2339,7 @@ public class AccessController extends BaseMasterAndRegionObserver
}
});
} else {
requirePermission("userPermissions", Action.ADMIN);
requirePermission(caller, "userPermissions", Action.ADMIN);
perms = User.runAsLoginUser(new PrivilegedExceptionAction<List<UserPermission>>() {
@Override
public List<UserPermission> run() throws Exception {
@ -2359,7 +2376,7 @@ public class AccessController extends BaseMasterAndRegionObserver
}
AccessControlProtos.CheckPermissionsResponse response = null;
try {
User user = getActiveUser();
User user = RpcServer.getRequestUser();
TableName tableName = regionEnv.getRegion().getTableDesc().getTableName();
for (Permission permission : permissions) {
if (permission instanceof TablePermission) {
@ -2453,17 +2470,16 @@ public class AccessController extends BaseMasterAndRegionObserver
}
@Override
public void preClose(ObserverContext<RegionCoprocessorEnvironment> e, boolean abortRequested)
public void preClose(ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested)
throws IOException {
requirePermission("preClose", Action.ADMIN);
requirePermission(getActiveUser(c), "preClose", Action.ADMIN);
}
private void checkSystemOrSuperUser() throws IOException {
private void checkSystemOrSuperUser(User activeUser) throws IOException {
// No need to check if we're not going to throw
if (!authorizationEnabled) {
return;
}
User activeUser = getActiveUser();
if (!Superusers.isSuperUser(activeUser)) {
throw new AccessDeniedException("User '" + (activeUser != null ?
activeUser.getShortName() : "null") + "' is not system or super user.");
@ -2472,9 +2488,9 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preStopRegionServer(
ObserverContext<RegionServerCoprocessorEnvironment> env)
ObserverContext<RegionServerCoprocessorEnvironment> ctx)
throws IOException {
requirePermission("preStopRegionServer", Action.ADMIN);
requirePermission(getActiveUser(ctx), "preStopRegionServer", Action.ADMIN);
}
private Map<byte[], ? extends Collection<byte[]>> makeFamilyMap(byte[] family,
@ -2502,7 +2518,7 @@ public class AccessController extends BaseMasterAndRegionObserver
// Skip checks for a table that does not exist
if (!masterServices.getTableStateManager().isTablePresent(tableName))
continue;
requirePermission("getTableDescriptors", tableName, null, null,
requirePermission(getActiveUser(ctx), "getTableDescriptors", tableName, null, null,
Action.ADMIN, Action.CREATE);
}
}
@ -2523,7 +2539,7 @@ public class AccessController extends BaseMasterAndRegionObserver
while (itr.hasNext()) {
HTableDescriptor htd = itr.next();
try {
requirePermission("getTableDescriptors", htd.getTableName(), null, null,
requirePermission(getActiveUser(ctx), "getTableDescriptors", htd.getTableName(), null, null,
Action.ADMIN, Action.CREATE);
} catch (AccessDeniedException e) {
itr.remove();
@ -2539,7 +2555,7 @@ public class AccessController extends BaseMasterAndRegionObserver
while (itr.hasNext()) {
HTableDescriptor htd = itr.next();
try {
requireAccess("getTableNames", htd.getTableName(), Action.values());
requireAccess(getActiveUser(ctx), "getTableNames", htd.getTableName(), Action.values());
} catch (AccessDeniedException e) {
itr.remove();
}
@ -2549,15 +2565,15 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preDispatchMerge(final ObserverContext<MasterCoprocessorEnvironment> ctx,
HRegionInfo regionA, HRegionInfo regionB) throws IOException {
requirePermission("mergeRegions", regionA.getTable(), null, null,
requirePermission(getActiveUser(ctx), "mergeRegions", regionA.getTable(), null, null,
Action.ADMIN);
}
@Override
public void preMerge(ObserverContext<RegionServerCoprocessorEnvironment> ctx, Region regionA,
Region regionB) throws IOException {
requirePermission("mergeRegions", regionA.getTableDesc().getTableName(), null, null,
Action.ADMIN);
requirePermission(getActiveUser(ctx), "mergeRegions", regionA.getTableDesc().getTableName(),
null, null, Action.ADMIN);
}
@Override
@ -2583,7 +2599,7 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preRollWALWriterRequest(ObserverContext<RegionServerCoprocessorEnvironment> ctx)
throws IOException {
requirePermission("preRollLogWriterRequest", Permission.Action.ADMIN);
requirePermission(getActiveUser(ctx), "preRollLogWriterRequest", Permission.Action.ADMIN);
}
@Override
@ -2593,31 +2609,31 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final String userName, final Quotas quotas) throws IOException {
requirePermission("setUserQuota", Action.ADMIN);
requirePermission(getActiveUser(ctx), "setUserQuota", Action.ADMIN);
}
@Override
public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final String userName, final TableName tableName, final Quotas quotas) throws IOException {
requirePermission("setUserTableQuota", tableName, null, null, Action.ADMIN);
requirePermission(getActiveUser(ctx), "setUserTableQuota", tableName, null, null, Action.ADMIN);
}
@Override
public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final String userName, final String namespace, final Quotas quotas) throws IOException {
requirePermission("setUserNamespaceQuota", Action.ADMIN);
requirePermission(getActiveUser(ctx), "setUserNamespaceQuota", Action.ADMIN);
}
@Override
public void preSetTableQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final TableName tableName, final Quotas quotas) throws IOException {
requirePermission("setTableQuota", tableName, null, null, Action.ADMIN);
requirePermission(getActiveUser(ctx), "setTableQuota", tableName, null, null, Action.ADMIN);
}
@Override
public void preSetNamespaceQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final String namespace, final Quotas quotas) throws IOException {
requirePermission("setNamespaceQuota", Action.ADMIN);
requirePermission(getActiveUser(ctx), "setNamespaceQuota", Action.ADMIN);
}
@Override
@ -2629,7 +2645,7 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preReplicateLogEntries(ObserverContext<RegionServerCoprocessorEnvironment> ctx,
List<WALEntry> entries, CellScanner cells) throws IOException {
requirePermission("replicateLogEntries", Action.WRITE);
requirePermission(getActiveUser(ctx), "replicateLogEntries", Action.WRITE);
}
@Override
@ -2640,30 +2656,30 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override
public void preMoveServers(ObserverContext<MasterCoprocessorEnvironment> ctx,
Set<HostAndPort> servers, String targetGroup) throws IOException {
requirePermission("moveServers", Action.ADMIN);
requirePermission(getActiveUser(ctx), "moveServers", Action.ADMIN);
}
@Override
public void preMoveTables(ObserverContext<MasterCoprocessorEnvironment> ctx,
Set<TableName> tables, String targetGroup) throws IOException {
requirePermission("moveTables", Action.ADMIN);
requirePermission(getActiveUser(ctx), "moveTables", Action.ADMIN);
}
@Override
public void preAddRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
String name) throws IOException {
requirePermission("addRSGroup", Action.ADMIN);
requirePermission(getActiveUser(ctx), "addRSGroup", Action.ADMIN);
}
@Override
public void preRemoveRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
String name) throws IOException {
requirePermission("removeRSGroup", Action.ADMIN);
requirePermission(getActiveUser(ctx), "removeRSGroup", Action.ADMIN);
}
@Override
public void preBalanceRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
String groupName) throws IOException {
requirePermission("balanceRSGroup", Action.ADMIN);
requirePermission(getActiveUser(ctx), "balanceRSGroup", Action.ADMIN);
}
}