/** * Check the quota for the current (rpc-context) user. Returns the OperationQuota used to get the * available quota and to report the data/usage of the operation. * @param region the region where the operation will be performed * @param numWrites number of writes to perform * @param numReads number of short-reads to perform * @param numScans number of scan to perform * @return the OperationQuota * @throws ThrottlingException if the operation cannot be executed due to quota exceeded. */ private OperationQuota checkQuota(final Region region, final int numWrites, final int numReads, final int numScans) throws IOException, ThrottlingException { User user = RpcServer.getRequestUser(); UserGroupInformation ugi; if (user != null) { ugi = user.getUGI(); } else { ugi = User.getCurrent().getUGI(); } TableName table = region.getTableDesc().getTableName(); OperationQuota quota = getQuota(ugi, table); try { quota.checkQuota(numWrites, numReads, numScans); } catch (ThrottlingException e) { LOG.debug("Throttling exception for user=" + ugi.getUserName() + " table=" + table + " numWrites=" + numWrites + " numReads=" + numReads + " numScans=" + numScans + ": " + e.getMessage()); throw e; } return quota; }
/** * @return Get remote side's InetAddress * @throws UnknownHostException */ InetAddress getRemoteInetAddress(final int port, final long serverStartCode) throws UnknownHostException { // Do it out here in its own little method so can fake an address when // mocking up in tests. InetAddress ia = RpcServer.getRemoteIp(); // The call could be from the local regionserver, // in which case, there is no remote address. if (ia == null && serverStartCode == startcode) { InetSocketAddress isa = rpcServices.getSocketAddress(); if (isa != null && isa.getPort() == port) { ia = isa.getAddress(); } } return ia; }
@Override public AuthenticationProtos.GetAuthenticationTokenResponse getAuthenticationToken( RpcController controller, AuthenticationProtos.GetAuthenticationTokenRequest request) throws ServiceException { LOG.debug("Authentication token request from " + RpcServer.getRequestUserName()); // ignore passed in controller -- it's always null ServerRpcController serverController = new ServerRpcController(); BlockingRpcCallback<AuthenticationProtos.GetAuthenticationTokenResponse> callback = new BlockingRpcCallback<AuthenticationProtos.GetAuthenticationTokenResponse>(); getAuthenticationToken(serverController, request, callback); try { serverController.checkFailed(); return callback.get(); } catch (IOException ioe) { throw new ServiceException(ioe); } }
@Override public AuthenticationProtos.WhoAmIResponse whoAmI( RpcController controller, AuthenticationProtos.WhoAmIRequest request) throws ServiceException { LOG.debug("whoAmI() request from " + RpcServer.getRequestUserName()); // ignore passed in controller -- it's always null ServerRpcController serverController = new ServerRpcController(); BlockingRpcCallback<AuthenticationProtos.WhoAmIResponse> callback = new BlockingRpcCallback<AuthenticationProtos.WhoAmIResponse>(); whoAmI(serverController, request, callback); try { serverController.checkFailed(); return callback.get(); } catch (IOException ioe) { throw new ServiceException(ioe); } }
@BeforeClass public static void setUp() throws Exception { LOG.info("HBase minicluster: Starting"); ((Log4JLogger) RpcServer.LOG).getLogger().setLevel(Level.ALL); ((Log4JLogger) AbstractRpcClient.LOG).getLogger().setLevel(Level.ALL); ((Log4JLogger) ScannerCallable.LOG).getLogger().setLevel(Level.ALL); TEST_UTIL.startMiniCluster(1); // https://issues.apache.org/jira/browse/HBASE-11711 TEST_UTIL.getConfiguration().setInt("hbase.master.info.port", -1); // Make sure the zookeeper quorum value contains the right port number (varies per run). TEST_UTIL.getConfiguration().set("hbase.zookeeper.quorum", "localhost:" + TEST_UTIL.getZkCluster().getClientPort()); conf = initialize(TEST_UTIL.getConfiguration()); LOG.info("HBase minicluster: Running"); }
@BeforeClass public static void setUp() throws Exception { LOG.info("HBase minicluster: Starting"); ((Log4JLogger) RpcServer.LOG).getLogger().setLevel(Level.ALL); ((Log4JLogger) AbstractRpcClient.LOG).getLogger().setLevel(Level.ALL); ((Log4JLogger) ScannerCallable.LOG).getLogger().setLevel(Level.ALL); TEST_UTIL.startMiniCluster(1); // https://issues.apache.org/jira/browse/HBASE-11711 TEST_UTIL.getConfiguration().setInt("hbase.master.info.port", -1); // Make sure the zookeeper quorum value contains the right port number (varies per run). TEST_UTIL.getConfiguration().set("hbase.zookeeper.quorum", "localhost:" + TEST_UTIL.getZkCluster().getClientPort()); initialize(TEST_UTIL.getConfiguration()); LOG.info("HBase minicluster: Running"); }
public TokenServer(Configuration conf) throws IOException { this.conf = conf; this.startcode = EnvironmentEdgeManager.currentTime(); // Server to handle client requests. String hostname = Strings.domainNamePointerToHostName(DNS.getDefaultHost("default", "default")); int port = 0; // Creation of an ISA will force a resolve. InetSocketAddress initialIsa = new InetSocketAddress(hostname, port); if (initialIsa.getAddress() == null) { throw new IllegalArgumentException("Failed resolve of " + initialIsa); } final List<BlockingServiceAndInterface> sai = new ArrayList<BlockingServiceAndInterface>(1); BlockingService service = AuthenticationProtos.AuthenticationService.newReflectiveBlockingService(this); sai.add(new BlockingServiceAndInterface(service, AuthenticationProtos.AuthenticationService.BlockingInterface.class)); this.rpcServer = new RpcServer(this, "tokenServer", sai, initialIsa, conf, new FifoRpcScheduler(conf, 1)); this.isa = this.rpcServer.getListenerAddress(); this.sleeper = new Sleeper(1000, this); }
public TokenServer(Configuration conf) throws IOException { this.conf = conf; this.startcode = EnvironmentEdgeManager.currentTimeMillis(); // Server to handle client requests. String hostname = Strings.domainNamePointerToHostName(DNS.getDefaultHost("default", "default")); int port = 0; // Creation of an ISA will force a resolve. InetSocketAddress initialIsa = new InetSocketAddress(hostname, port); if (initialIsa.getAddress() == null) { throw new IllegalArgumentException("Failed resolve of " + initialIsa); } final List<BlockingServiceAndInterface> sai = new ArrayList<BlockingServiceAndInterface>(1); BlockingService service = AuthenticationProtos.AuthenticationService.newReflectiveBlockingService(this); sai.add(new BlockingServiceAndInterface(service, AuthenticationProtos.AuthenticationService.BlockingInterface.class)); this.rpcServer = new RpcServer(this, "tokenServer", sai, initialIsa, conf, new FifoRpcScheduler(conf, 1)); this.isa = this.rpcServer.getListenerAddress(); this.sleeper = new Sleeper(1000, this); }
@Override public void start(CoprocessorEnvironment env) { super.start(env); // if running at region if (env instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment regionEnv = (RegionCoprocessorEnvironment)env; RpcServer server = regionEnv.getRegionServerServices().getRpcServer(); if (server instanceof SecureServer) { SecretManager mgr = ((SecureServer)server).getSecretManager(); if (mgr instanceof AuthenticationTokenSecretManager) { secretManager = (AuthenticationTokenSecretManager)mgr; } } } }
@BeforeClass public static void setupBeforeClass() throws Exception { TEST_UTIL = new HBaseTestingUtility(); Configuration conf = TEST_UTIL.getConfiguration(); conf.set(HBaseRPC.RPC_ENGINE_PROP, SecureRpcEngine.class.getName()); conf.set("hbase.coprocessor.region.classes", IdentityCoprocessor.class.getName()); TEST_UTIL.startMiniCluster(); HRegionServer rs = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0); RpcServer server = rs.getRpcServer(); assertTrue(server instanceof SecureServer); SecretManager mgr = ((SecureServer)server).getSecretManager(); assertTrue(mgr instanceof AuthenticationTokenSecretManager); secretManager = (AuthenticationTokenSecretManager)mgr; }
@Override public void start(CoprocessorEnvironment env) { // if running at region if (env instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment regionEnv = (RegionCoprocessorEnvironment)env; /* Getting the RpcServer from a RegionCE is wrong. There cannot be an expectation that Region is hosted inside a RegionServer. If you need RpcServer, then pass in a RegionServerCE. TODO: FIX. */ RegionServerServices rss = ((HasRegionServerServices)regionEnv).getRegionServerServices(); RpcServerInterface server = rss.getRpcServer(); SecretManager<?> mgr = ((RpcServer)server).getSecretManager(); if (mgr instanceof AuthenticationTokenSecretManager) { secretManager = (AuthenticationTokenSecretManager)mgr; } } }
/** * Check the quota for the current (rpc-context) user. * Returns the OperationQuota used to get the available quota and * to report the data/usage of the operation. * @param region the region where the operation will be performed * @param numWrites number of writes to perform * @param numReads number of short-reads to perform * @param numScans number of scan to perform * @return the OperationQuota * @throws ThrottlingException if the operation cannot be executed due to quota exceeded. */ private OperationQuota checkQuota(final Region region, final int numWrites, final int numReads, final int numScans) throws IOException, ThrottlingException { Optional<User> user = RpcServer.getRequestUser(); UserGroupInformation ugi; if (user.isPresent()) { ugi = user.get().getUGI(); } else { ugi = User.getCurrent().getUGI(); } TableName table = region.getTableDescriptor().getTableName(); OperationQuota quota = getQuota(ugi, table); try { quota.checkQuota(numWrites, numReads, numScans); } catch (ThrottlingException e) { LOG.debug("Throttling exception for user=" + ugi.getUserName() + " table=" + table + " numWrites=" + numWrites + " numReads=" + numReads + " numScans=" + numScans + ": " + e.getMessage()); throw e; } return quota; }
/** * @return Get remote side's InetAddress */ InetAddress getRemoteInetAddress(final int port, final long serverStartCode) throws UnknownHostException { // Do it out here in its own little method so can fake an address when // mocking up in tests. InetAddress ia = RpcServer.getRemoteIp(); // The call could be from the local regionserver, // in which case, there is no remote address. if (ia == null && serverStartCode == startcode) { InetSocketAddress isa = rpcServices.getSocketAddress(); if (isa != null && isa.getPort() == port) { ia = isa.getAddress(); } } return ia; }
@Override public AuthenticationProtos.GetAuthenticationTokenResponse getAuthenticationToken( RpcController controller, AuthenticationProtos.GetAuthenticationTokenRequest request) throws ServiceException { LOG.debug("Authentication token request from " + RpcServer.getRequestUserName().orElse(null)); // Ignore above passed in controller -- it is always null ServerRpcController serverController = new ServerRpcController(); final NonShadedBlockingRpcCallback<AuthenticationProtos.GetAuthenticationTokenResponse> callback = new NonShadedBlockingRpcCallback<>(); getAuthenticationToken(null, request, callback); try { serverController.checkFailed(); return callback.get(); } catch (IOException ioe) { throw new ServiceException(ioe); } }
@Override public AuthenticationProtos.WhoAmIResponse whoAmI( RpcController controller, AuthenticationProtos.WhoAmIRequest request) throws ServiceException { LOG.debug("whoAmI() request from " + RpcServer.getRequestUserName().orElse(null)); // Ignore above passed in controller -- it is always null ServerRpcController serverController = new ServerRpcController(); NonShadedBlockingRpcCallback<AuthenticationProtos.WhoAmIResponse> callback = new NonShadedBlockingRpcCallback<>(); whoAmI(null, request, callback); try { serverController.checkFailed(); return callback.get(); } catch (IOException ioe) { throw new ServiceException(ioe); } }
public TokenServer(Configuration conf) throws IOException { this.conf = conf; this.startcode = EnvironmentEdgeManager.currentTimeMillis(); // Server to handle client requests. String hostname = Strings.domainNamePointerToHostName(DNS.getDefaultHost("default", "default")); int port = 0; // Creation of an ISA will force a resolve. InetSocketAddress initialIsa = new InetSocketAddress(hostname, port); if (initialIsa.getAddress() == null) { throw new IllegalArgumentException("Failed resolve of " + initialIsa); } final List<BlockingServiceAndInterface> sai = new ArrayList<BlockingServiceAndInterface>(1); BlockingService service = AuthenticationProtos.AuthenticationService.newReflectiveBlockingService(this); sai.add(new BlockingServiceAndInterface(service, AuthenticationProtos.AuthenticationService.BlockingInterface.class)); this.rpcServer = new RpcServer(this, "tokenServer", sai, initialIsa, 3, 1, conf, HConstants.QOS_THRESHOLD); this.isa = this.rpcServer.getListenerAddress(); this.sleeper = new Sleeper(1000, this); }
public HRegionFacade(String rpcName) throws IOException { this.rpcName = rpcName; zooKeeper = new ZooKeeper(ZK_STRING, 300, this); c = HBaseConfiguration.create(); initialIsa = new InetSocketAddress(PORT_NUMBER); this.rpcServer = new RpcServer(this, this.rpcName, getServices(), initialIsa, 10, 10, c, HConstants.QOS_THRESHOLD); this.rpcServer.setErrorHandler(this); this.rpcServer.start(); }
/** * Verify, when servicing an RPC, that the caller is the scanner owner. If so, we assume that * access control is correctly enforced based on the checks performed in preScannerOpen() */ private void requireScannerOwner(InternalScanner s) throws AccessDeniedException { if (!RpcServer.isInRpcCallContext()) return; String requestUName = RpcServer.getRequestUserName(); String owner = scannerOwners.get(s); if (authorizationEnabled && owner != null && !owner.equals(requestUName)) { throw new AccessDeniedException("User '" + requestUName + "' is not the scanner owner!"); } }
private void logResult(boolean isAllowed, String request, String reason, byte[] user, List<byte[]> labelAuths, String regex) { if (AUDITLOG.isTraceEnabled()) { // This is more duplicated code! InetAddress remoteAddr = RpcServer.getRemoteAddress(); List<String> labelAuthsStr = new ArrayList<>(); if (labelAuths != null) { int labelAuthsSize = labelAuths.size(); labelAuthsStr = new ArrayList<>(labelAuthsSize); for (int i = 0; i < labelAuthsSize; i++) { labelAuthsStr.add(Bytes.toString(labelAuths.get(i))); } } User requestingUser = null; try { requestingUser = VisibilityUtils.getActiveUser(); } catch (IOException e) { LOG.warn("Failed to get active system user."); LOG.debug("Details on failure to get active system user.", e); } AUDITLOG.trace("Access " + (isAllowed ? "allowed" : "denied") + " for user " + (requestingUser != null ? requestingUser.getShortName() : "UNKNOWN") + "; reason: " + reason + "; remote address: " + (remoteAddr != null ? remoteAddr : "") + "; request: " + request + "; user: " + (user != null ? Bytes.toShort(user) : "null") + "; labels: " + labelAuthsStr + "; regex: " + regex); } }
/** * @return User who called RPC method. For non-RPC handling, falls back to system user * @throws IOException When there is IOE in getting the system user (During non-RPC handling). */ public static User getActiveUser() throws IOException { User user = RpcServer.getRequestUser(); if (user == null) { user = User.getCurrent(); } if (LOG.isTraceEnabled()) { LOG.trace("Current active user name is " + user.getShortName()); } return user; }
@Override public void start(CoprocessorEnvironment env) { // if running at region if (env instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment regionEnv = (RegionCoprocessorEnvironment)env; RpcServerInterface server = regionEnv.getRegionServerServices().getRpcServer(); SecretManager<?> mgr = ((RpcServer)server).getSecretManager(); if (mgr instanceof AuthenticationTokenSecretManager) { secretManager = (AuthenticationTokenSecretManager)mgr; } } }
@Override public void getAuthenticationToken(RpcController controller, AuthenticationProtos.GetAuthenticationTokenRequest request, RpcCallback<AuthenticationProtos.GetAuthenticationTokenResponse> done) { AuthenticationProtos.GetAuthenticationTokenResponse.Builder response = AuthenticationProtos.GetAuthenticationTokenResponse.newBuilder(); try { if (secretManager == null) { throw new IOException( "No secret manager configured for token authentication"); } User currentUser = RpcServer.getRequestUser(); UserGroupInformation ugi = null; if (currentUser != null) { ugi = currentUser.getUGI(); } if (currentUser == null) { throw new AccessDeniedException("No authenticated user for request!"); } else if (!isAllowedDelegationTokenOp(ugi)) { LOG.warn("Token generation denied for user="+currentUser.getName() +", authMethod="+ugi.getAuthenticationMethod()); throw new AccessDeniedException( "Token generation only allowed for Kerberos authenticated clients"); } Token<AuthenticationTokenIdentifier> token = secretManager.generateToken(currentUser.getName()); response.setToken(ProtobufUtil.toToken(token)).build(); } catch (IOException ioe) { ResponseConverter.setControllerException(controller, ioe); } done.run(response.build()); }
@Override public void whoAmI(RpcController controller, AuthenticationProtos.WhoAmIRequest request, RpcCallback<AuthenticationProtos.WhoAmIResponse> done) { User requestUser = RpcServer.getRequestUser(); AuthenticationProtos.WhoAmIResponse.Builder response = AuthenticationProtos.WhoAmIResponse.newBuilder(); if (requestUser != null) { response.setUsername(requestUser.getShortName()); AuthenticationMethod method = requestUser.getUGI().getAuthenticationMethod(); if (method != null) { response.setAuthMethod(method.name()); } } done.run(response.build()); }
private void logResult(AuthResult result) { if (AUDITLOG.isTraceEnabled()) { InetAddress remoteAddr = RpcServer.getRemoteAddress(); AUDITLOG.trace("Access " + (result.isAllowed() ? "allowed" : "denied") + " for user " + (result.getUser() != null ? result.getUser().getShortName() : "UNKNOWN") + "; reason: " + result.getReason() + "; remote address: " + (remoteAddr != null ? remoteAddr : "") + "; request: " + result.getRequest() + "; context: " + result.toContextString()); } }
/** * Returns the active user to which authorization checks should be applied. * 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(); if (user == null) { // for non-rpc handling, fallback to system user user = userProvider.getCurrent(); } return user; }
/** * Verify, when servicing an RPC, that the caller is the scanner owner. * If so, we assume that access control is correctly enforced based on * the checks performed in preScannerOpen() */ private void requireScannerOwner(InternalScanner s) throws AccessDeniedException { if (!RpcServer.isInRpcCallContext()) return; String requestUserName = RpcServer.getRequestUserName(); String owner = scannerOwners.get(s); if (authorizationEnabled && owner != null && !owner.equals(requestUserName)) { throw new AccessDeniedException("User '"+ requestUserName +"' is not the scanner owner!"); } }
private User getActiveUser() { User user = RpcServer.getRequestUser(); if (user == null) { return null; } //this is for testing if (userProvider.isHadoopSecurityEnabled() && "simple".equalsIgnoreCase(conf.get(User.HBASE_SECURITY_CONF_KEY))) { return User.createUserForTesting(conf, user.getShortName(), new String[]{}); } return user; }
public User getRequestUser() throws IOException { User user = RpcServer.getRequestUser(); if (user == null) { user = UserProvider.instantiate(getMasterConfiguration()).getCurrent(); } return user; }
/** * Split a region on the region server. * * @param controller the RPC controller * @param request the request * @throws ServiceException */ @Override @QosPriority(priority=HConstants.ADMIN_QOS) public SplitRegionResponse splitRegion(final RpcController controller, final SplitRegionRequest request) throws ServiceException { try { checkOpen(); requestCount.increment(); Region region = getRegion(request.getRegion()); region.startRegionOperation(Operation.SPLIT_REGION); if (region.getRegionInfo().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) { throw new IOException("Can't split replicas directly. " + "Replicas are auto-split when their primary is split."); } LOG.info("Splitting " + region.getRegionInfo().getRegionNameAsString()); long startTime = EnvironmentEdgeManager.currentTime(); FlushResult flushResult = region.flush(true); if (flushResult.isFlushSucceeded()) { long endTime = EnvironmentEdgeManager.currentTime(); regionServer.metricsRegionServer.updateFlushTime(endTime - startTime); } byte[] splitPoint = null; if (request.hasSplitPoint()) { splitPoint = request.getSplitPoint().toByteArray(); } ((HRegion)region).forceSplit(splitPoint); regionServer.compactSplitThread.requestSplit(region, ((HRegion)region).checkSplit(), RpcServer.getRequestUser()); return SplitRegionResponse.newBuilder().build(); } catch (DroppedSnapshotException ex) { regionServer.abort("Replay of WAL required. Forcing server shutdown", ex); throw new ServiceException(ex); } catch (IOException ie) { throw new ServiceException(ie); } }