public boolean matchPermission( User user, byte[] table, byte[] family, byte[] qualifier, TablePermission.Action action) { PermissionCache<TablePermission> tablePerms = tableCache.get(table); if (tablePerms != null) { List<TablePermission> userPerms = tablePerms.getUser(user.getShortName()); if (userPerms != null) { for (TablePermission p : userPerms) { if (p.matchesFamilyQualifier(table, family, qualifier, action)) { return true; } } } String[] groups = user.getGroupNames(); if (groups != null) { for (String group : groups) { List<TablePermission> groupPerms = tablePerms.getGroup(group); if (groupPerms != null) { for (TablePermission p : groupPerms) { if (p.matchesFamilyQualifier(table, family, qualifier, action)) { return true; } } } } } } return false; }
/** * Returns a new {@code PermissionCache} initialized with permission assignments from the {@code * hbase.superuser} configuration key. */ private PermissionCache<Permission> initGlobal(Configuration conf) throws IOException { UserProvider userProvider = UserProvider.instantiate(conf); User user = userProvider.getCurrent(); if (user == null) { throw new IOException( "Unable to obtain the current user, " + "authorization checks for internal operations will not work correctly!"); } PermissionCache<Permission> newCache = new PermissionCache<Permission>(); String currentUser = user.getShortName(); // the system user is always included List<String> superusers = Lists.asList( currentUser, conf.getStrings(AccessControlLists.SUPERUSER_CONF_KEY, new String[0])); if (superusers != null) { for (String name : superusers) { if (AccessControlLists.isGroupPrincipal(name)) { newCache.putGroup( AccessControlLists.getGroupName(name), new Permission(Permission.Action.values())); } else { newCache.putUser(name, new Permission(Permission.Action.values())); } } } return newCache; }
private User getActiveUser() { User user = RequestContext.getRequestUser(); if (!RequestContext.isInRequestContext()) { 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 boolean authorize( User user, byte[] table, byte[] family, byte[] qualifier, Permission.Action action) { if (authorizeUser(user.getShortName(), table, family, qualifier, action)) { return true; } String[] groups = user.getGroupNames(); if (groups != null) { for (String group : groups) { if (authorizeGroup(group, table, family, action)) { return true; } } } return false; }
@Override // simply use the default Object#hashcode() ? public int hashCode() { return (address.hashCode() + PRIME * (PRIME * System.identityHashCode(protocol) ^ (ticket == null ? 0 : ticket.hashCode()))) ^ rpcTimeout; }
@Override public boolean rollback(final Server server, final RegionServerServices services) throws IOException { if (User.isHBaseSecurityEnabled(parent.getBaseConf())) { LOG.warn("Should use rollback(Server, RegionServerServices, User)"); } return rollback(server, services, null); }
@Override public PairOfSameType<Region> execute(final Server server, final RegionServerServices services) throws IOException { if (User.isHBaseSecurityEnabled(parent.getBaseConf())) { LOG.warn("Should use execute(Server, RegionServerServices, User)"); } return execute(server, services, null); }
@Override public void whoAmI( RpcController controller, AuthenticationProtos.WhoAmIRequest request, RpcCallback<AuthenticationProtos.WhoAmIResponse> done) { User requestUser = RequestContext.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()); }
Connection(ConnectionId remoteId) throws IOException { if (remoteId.getAddress().isUnresolved()) { throw new UnknownHostException("unknown host: " + remoteId.getAddress().getHostName()); } this.remoteId = remoteId; User ticket = remoteId.getTicket(); Class<? extends VersionedProtocol> protocol = remoteId.getProtocol(); header = new ConnectionHeader(protocol == null ? null : protocol.getName(), ticket); this.setName( "IPC Client (" + socketFactory.hashCode() + ") connection to " + remoteId.getAddress().toString() + ((ticket == null) ? " from an unknown user" : (" from " + ticket.getName()))); this.setDaemon(true); }
@BeforeClass public static void setupBeforeClass() throws Exception { conf = TEST_UTIL.getConfiguration(); // Enable security enableSecurity(conf); // Verify enableSecurity sets up what we require verifyConfiguration(conf); TEST_UTIL.startMiniCluster(); // Wait for the ACL table to become available TEST_UTIL.waitUntilAllRegionsAssigned(AccessControlLists.ACL_TABLE_NAME); TESTGROUP1_USER1 = User.createUserForTesting(conf, "testgroup1_user1", new String[] {TESTGROUP_1}); TESTGROUP2_USER1 = User.createUserForTesting(conf, "testgroup2_user2", new String[] {TESTGROUP_2}); connection = ConnectionFactory.createConnection(conf); }
public JVMClusterUtil.MasterThread addMaster(final Configuration c, final int index, User user) throws IOException, InterruptedException { return user.runAs( new PrivilegedExceptionAction<JVMClusterUtil.MasterThread>() { public JVMClusterUtil.MasterThread run() throws Exception { return addMaster(c, index); } }); }
/** * Authorize a global permission based on ACLs for the given user and the user's groups. * * @param user * @param action * @return */ public boolean authorize(User user, Permission.Action action) { if (user == null) { return false; } if (authorize(globalCache.getUser(user.getShortName()), action)) { return true; } String[] groups = user.getGroupNames(); if (groups != null) { for (String group : groups) { if (authorize(globalCache.getGroup(group), action)) { return true; } } } return false; }
private Path createStagingDir(Path baseDir, User user, TableName tableName) throws IOException { String tblName = tableName.getNameAsString().replace(":", "_"); String randomDir = user.getShortName() + "__" + tblName + "__" + (new BigInteger(RANDOM_WIDTH, random).toString(RANDOM_RADIX)); return createStagingDir(baseDir, user, randomDir); }
@Override public boolean equals(Object obj) { if (obj instanceof ConnectionId) { ConnectionId id = (ConnectionId) obj; return address.equals(id.address) && protocol == id.protocol && ((ticket != null && ticket.equals(id.ticket)) || (ticket == id.ticket)) && rpcTimeout == id.rpcTimeout; } return false; }
public boolean authorize(User user, byte[] table, KeyValue kv, TablePermission.Action action) { PermissionCache<TablePermission> tablePerms = tableCache.get(table); if (tablePerms != null) { List<TablePermission> userPerms = tablePerms.getUser(user.getShortName()); if (authorize(userPerms, table, kv, action)) { return true; } String[] groupNames = user.getGroupNames(); if (groupNames != null) { for (String group : groupNames) { List<TablePermission> groupPerms = tablePerms.getGroup(group); if (authorize(groupPerms, table, kv, action)) { return true; } } } } return false; }
@Test public void testCreateWithCorrectOwner() throws Exception { // Create a test user final User testUser = User.createUserForTesting(TEST_UTIL.getConfiguration(), "TestUser", new String[0]); // Grant the test user the ability to create tables SecureTestUtil.grantGlobal(TEST_UTIL, testUser.getShortName(), Action.CREATE); verifyAllowed( new AccessTestAction() { @Override public Object run() throws Exception { HTableDescriptor desc = new HTableDescriptor(TEST_TABLE.getTableName()); desc.addFamily(new HColumnDescriptor(TEST_FAMILY)); try (Connection connection = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration(), testUser)) { try (Admin admin = connection.getAdmin()) { admin.createTable(desc); } } return null; } }, testUser); TEST_UTIL.waitTableEnabled(TEST_TABLE.getTableName()); // Verify that owner permissions have been granted to the test user on the // table just created List<TablePermission> perms = AccessControlLists.getTablePermissions(conf, TEST_TABLE.getTableName()) .get(testUser.getShortName()); assertNotNull(perms); assertFalse(perms.isEmpty()); // Should be RWXCA assertTrue(perms.get(0).implies(Permission.Action.READ)); assertTrue(perms.get(0).implies(Permission.Action.WRITE)); assertTrue(perms.get(0).implies(Permission.Action.EXEC)); assertTrue(perms.get(0).implies(Permission.Action.CREATE)); assertTrue(perms.get(0).implies(Permission.Action.ADMIN)); }
@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 = RequestContext.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="******", 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()); }
@BeforeClass public static void setUpBeforeClass() throws Exception { conf = TEST_UTIL.getConfiguration(); // Set up superuser SecureTestUtil.configureSuperuser(conf); // Install the VisibilityController as a system processor VisibilityTestUtil.enableVisiblityLabels(conf); // Now, DISABLE active authorization conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, false); TEST_UTIL.startMiniCluster(); // Wait for the labels table to become available TEST_UTIL.waitUntilAllRegionsAssigned(LABELS_TABLE_NAME); // create a set of test users SUPERUSER = User.createUserForTesting(conf, "admin", new String[] {"supergroup"}); USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]); // Define test labels SUPERUSER.runAs( new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { try (Connection conn = ConnectionFactory.createConnection(conf)) { VisibilityClient.addLabels(conn, new String[] {SECRET, CONFIDENTIAL, PRIVATE}); VisibilityClient.setAuths( conn, new String[] {SECRET, CONFIDENTIAL}, USER_RW.getShortName()); } catch (Throwable t) { fail("Should not have failed"); } return null; } }); }
@BeforeClass public static void setUpOnce() throws Exception { miniCluster = System.getProperty("cluster.type").equals("mini"); securedCluster = System.getProperty("cluster.secured").equals("true"); System.out.println("realCluster - " + !miniCluster); System.out.println("securedCluster - " + securedCluster); Util.setLoggingThreshold("ERROR"); if (miniCluster) { if (hbase == null) { hbase = new HBaseTestingUtility(); conf = hbase.getConfiguration(); conf.set("zookeeper.session.timeout", "3600000"); conf.set("dfs.client.socket-timeout", "3600000"); if (securedCluster) { hbase.startMiniCluster(RS_COUNT); hbase.waitTableEnabled(AccessControlLists.ACL_TABLE_NAME, 30000L); admin = new HBaseAdminWrapper(conf); } else { hbase.startMiniCluster(RS_COUNT); admin = hbase.getHBaseAdmin(); } } } else { if (admin == null) { final String argsFileName = securedCluster ? "../../testClusterRealSecured.args" : "../../testClusterRealNonSecured.args"; if (!Util.isFile(argsFileName)) { throw new IllegalStateException( "You have to define args file " + argsFileName + " for tests."); } String[] testArgs = {argsFileName}; Args args = new TestArgs(testArgs); admin = HBaseClient.getAdmin(args); conf = admin.getConfiguration(); RS_COUNT = getServerNameList().size(); } } previousBalancerRunning = admin.setBalancerRunning(false, true); hConnection = HConnectionManager.createConnection(conf); USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]); }
@Test public void testListNamespaces() throws Exception { AccessTestAction listAction = new AccessTestAction() { @Override public Object run() throws Exception { Connection unmanagedConnection = ConnectionFactory.createConnection(UTIL.getConfiguration()); Admin admin = unmanagedConnection.getAdmin(); try { return Arrays.asList(admin.listNamespaceDescriptors()); } finally { admin.close(); unmanagedConnection.close(); } } }; // listNamespaces : All access* // * Returned list will only show what you can call getNamespaceDescriptor() verifyAllowed(listAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN, USER_GROUP_ADMIN); // we have 3 namespaces: [default, hbase, TEST_NAMESPACE, TEST_NAMESPACE2] assertEquals(4, ((List) SUPERUSER.runAs(listAction)).size()); assertEquals(4, ((List) USER_GLOBAL_ADMIN.runAs(listAction)).size()); assertEquals(4, ((List) USER_GROUP_ADMIN.runAs(listAction)).size()); assertEquals(2, ((List) USER_NS_ADMIN.runAs(listAction)).size()); assertEquals(0, ((List) USER_GLOBAL_CREATE.runAs(listAction)).size()); assertEquals(0, ((List) USER_GLOBAL_WRITE.runAs(listAction)).size()); assertEquals(0, ((List) USER_GLOBAL_READ.runAs(listAction)).size()); assertEquals(0, ((List) USER_GLOBAL_EXEC.runAs(listAction)).size()); assertEquals(0, ((List) USER_NS_CREATE.runAs(listAction)).size()); assertEquals(0, ((List) USER_NS_WRITE.runAs(listAction)).size()); assertEquals(0, ((List) USER_NS_READ.runAs(listAction)).size()); assertEquals(0, ((List) USER_NS_EXEC.runAs(listAction)).size()); assertEquals(0, ((List) USER_TABLE_CREATE.runAs(listAction)).size()); assertEquals(0, ((List) USER_TABLE_WRITE.runAs(listAction)).size()); assertEquals(0, ((List) USER_GROUP_CREATE.runAs(listAction)).size()); assertEquals(0, ((List) USER_GROUP_READ.runAs(listAction)).size()); assertEquals(0, ((List) USER_GROUP_WRITE.runAs(listAction)).size()); }
/** * Take a snapshot based on the enabled/disabled state of the table. * * @param snapshot * @throws HBaseSnapshotException when a snapshot specific exception occurs. * @throws IOException when some sort of generic IO exception occurs. */ public void takeSnapshot(SnapshotDescription snapshot) throws IOException { // check to see if we already completed the snapshot if (isSnapshotCompleted(snapshot)) { throw new SnapshotExistsException( "Snapshot '" + snapshot.getName() + "' already stored on the filesystem.", ProtobufUtil.createSnapshotDesc(snapshot)); } LOG.debug("No existing snapshot, attempting snapshot..."); // stop tracking "abandoned" handlers cleanupSentinels(); // check to see if the table exists HTableDescriptor desc = null; try { desc = master.getTableDescriptors().get(TableName.valueOf(snapshot.getTable())); } catch (FileNotFoundException e) { String msg = "Table:" + snapshot.getTable() + " info doesn't exist!"; LOG.error(msg); throw new SnapshotCreationException(msg, e, ProtobufUtil.createSnapshotDesc(snapshot)); } catch (IOException e) { throw new SnapshotCreationException( "Error while geting table description for table " + snapshot.getTable(), e, ProtobufUtil.createSnapshotDesc(snapshot)); } if (desc == null) { throw new SnapshotCreationException( "Table '" + snapshot.getTable() + "' doesn't exist, can't take snapshot.", ProtobufUtil.createSnapshotDesc(snapshot)); } SnapshotDescription.Builder builder = snapshot.toBuilder(); // if not specified, set the snapshot format if (!snapshot.hasVersion()) { builder.setVersion(SnapshotDescriptionUtils.SNAPSHOT_LAYOUT_VERSION); } User user = RpcServer.getRequestUser(); if (User.isHBaseSecurityEnabled(master.getConfiguration()) && user != null) { builder.setOwner(user.getShortName()); } snapshot = builder.build(); // call pre coproc hook MasterCoprocessorHost cpHost = master.getMasterCoprocessorHost(); if (cpHost != null) { cpHost.preSnapshot(snapshot, desc); } // if the table is enabled, then have the RS run actually the snapshot work TableName snapshotTable = TableName.valueOf(snapshot.getTable()); if (master.getTableStateManager().isTableState(snapshotTable, TableState.State.ENABLED)) { LOG.debug("Table enabled, starting distributed snapshot."); snapshotEnabledTable(snapshot); LOG.debug("Started snapshot: " + ClientSnapshotDescriptionUtils.toString(snapshot)); } // For disabled table, snapshot is created by the master else if (master.getTableStateManager().isTableState(snapshotTable, TableState.State.DISABLED)) { LOG.debug("Table is disabled, running snapshot entirely on master."); snapshotDisabledTable(snapshot); LOG.debug("Started snapshot: " + ClientSnapshotDescriptionUtils.toString(snapshot)); } else { LOG.error( "Can't snapshot table '" + snapshot.getTable() + "', isn't open or closed, we don't know what to do!"); TablePartiallyOpenException tpoe = new TablePartiallyOpenException(snapshot.getTable() + " isn't fully open."); throw new SnapshotCreationException( "Table is not entirely open or closed", tpoe, ProtobufUtil.createSnapshotDesc(snapshot)); } // call post coproc hook if (cpHost != null) { cpHost.postSnapshot(snapshot, desc); } }
@Override public void secureBulkLoadHFiles( RpcController controller, SecureBulkLoadHFilesRequest request, RpcCallback<SecureBulkLoadHFilesResponse> done) { final List<Pair<byte[], String>> familyPaths = new ArrayList<Pair<byte[], String>>(); for (ClientProtos.BulkLoadHFileRequest.FamilyPath el : request.getFamilyPathList()) { familyPaths.add(new Pair(el.getFamily().toByteArray(), el.getPath())); } Token userToken = null; if (userProvider.isHadoopSecurityEnabled()) { userToken = new Token( request.getFsToken().getIdentifier().toByteArray(), request.getFsToken().getPassword().toByteArray(), new Text(request.getFsToken().getKind()), new Text(request.getFsToken().getService())); } final String bulkToken = request.getBulkToken(); User user = getActiveUser(); final UserGroupInformation ugi = user.getUGI(); if (userToken != null) { ugi.addToken(userToken); } else if (userProvider.isHadoopSecurityEnabled()) { // we allow this to pass through in "simple" security mode // for mini cluster testing ResponseConverter.setControllerException( controller, new DoNotRetryIOException("User token cannot be null")); done.run(SecureBulkLoadHFilesResponse.newBuilder().setLoaded(false).build()); return; } HRegion region = env.getRegion(); boolean bypass = false; if (region.getCoprocessorHost() != null) { try { bypass = region.getCoprocessorHost().preBulkLoadHFile(familyPaths); } catch (IOException e) { ResponseConverter.setControllerException(controller, e); done.run(SecureBulkLoadHFilesResponse.newBuilder().setLoaded(false).build()); return; } } boolean loaded = false; if (!bypass) { // Get the target fs (HBase region server fs) delegation token // Since we have checked the permission via 'preBulkLoadHFile', now let's give // the 'request user' necessary token to operate on the target fs. // After this point the 'doAs' user will hold two tokens, one for the source fs // ('request user'), another for the target fs (HBase region server principal). if (userProvider.isHadoopSecurityEnabled()) { FsDelegationToken targetfsDelegationToken = new FsDelegationToken(userProvider, "renewer"); try { targetfsDelegationToken.acquireDelegationToken(fs); } catch (IOException e) { ResponseConverter.setControllerException(controller, e); done.run(SecureBulkLoadHFilesResponse.newBuilder().setLoaded(false).build()); return; } Token<?> targetFsToken = targetfsDelegationToken.getUserToken(); if (targetFsToken != null && (userToken == null || !targetFsToken.getService().equals(userToken.getService()))) { ugi.addToken(targetFsToken); } } loaded = ugi.doAs( new PrivilegedAction<Boolean>() { @Override public Boolean run() { FileSystem fs = null; try { Configuration conf = env.getConfiguration(); fs = FileSystem.get(conf); for (Pair<byte[], String> el : familyPaths) { Path p = new Path(el.getSecond()); Path stageFamily = new Path(bulkToken, Bytes.toString(el.getFirst())); if (!fs.exists(stageFamily)) { fs.mkdirs(stageFamily); fs.setPermission(stageFamily, PERM_ALL_ACCESS); } } // We call bulkLoadHFiles as requesting user // To enable access prior to staging return env.getRegion() .bulkLoadHFiles( familyPaths, true, new SecureBulkLoadListener(fs, bulkToken, conf)); } catch (Exception e) { LOG.error("Failed to complete bulk load", e); } return false; } }); } if (region.getCoprocessorHost() != null) { try { loaded = region.getCoprocessorHost().postBulkLoadHFile(familyPaths, loaded); } catch (IOException e) { ResponseConverter.setControllerException(controller, e); done.run(SecureBulkLoadHFilesResponse.newBuilder().setLoaded(false).build()); return; } } done.run(SecureBulkLoadHFilesResponse.newBuilder().setLoaded(loaded).build()); }
@BeforeClass public static void beforeClass() throws Exception { conf = UTIL.getConfiguration(); enableSecurity(conf); SUPERUSER = User.createUserForTesting(conf, "admin", new String[] {"supergroup"}); // Users with global permissions USER_GLOBAL_ADMIN = User.createUserForTesting(conf, "global_admin", new String[0]); USER_GLOBAL_CREATE = User.createUserForTesting(conf, "global_create", new String[0]); USER_GLOBAL_WRITE = User.createUserForTesting(conf, "global_write", new String[0]); USER_GLOBAL_READ = User.createUserForTesting(conf, "global_read", new String[0]); USER_GLOBAL_EXEC = User.createUserForTesting(conf, "global_exec", new String[0]); USER_NS_ADMIN = User.createUserForTesting(conf, "namespace_admin", new String[0]); USER_NS_CREATE = User.createUserForTesting(conf, "namespace_create", new String[0]); USER_NS_WRITE = User.createUserForTesting(conf, "namespace_write", new String[0]); USER_NS_READ = User.createUserForTesting(conf, "namespace_read", new String[0]); USER_NS_EXEC = User.createUserForTesting(conf, "namespace_exec", new String[0]); USER_TABLE_CREATE = User.createUserForTesting(conf, "table_create", new String[0]); USER_TABLE_WRITE = User.createUserForTesting(conf, "table_write", new String[0]); USER_GROUP_ADMIN = User.createUserForTesting(conf, "user_group_admin", new String[] {GROUP_ADMIN}); USER_GROUP_NS_ADMIN = User.createUserForTesting(conf, "user_group_ns_admin", new String[] {GROUP_NS_ADMIN}); USER_GROUP_CREATE = User.createUserForTesting(conf, "user_group_create", new String[] {GROUP_CREATE}); USER_GROUP_READ = User.createUserForTesting(conf, "user_group_read", new String[] {GROUP_READ}); USER_GROUP_WRITE = User.createUserForTesting(conf, "user_group_write", new String[] {GROUP_WRITE}); // TODO: other table perms UTIL.startMiniCluster(); // Wait for the ACL table to become available UTIL.waitTableAvailable(AccessControlLists.ACL_TABLE_NAME.getName(), 30 * 1000); ACCESS_CONTROLLER = (AccessController) UTIL.getMiniHBaseCluster() .getMaster() .getRegionServerCoprocessorHost() .findCoprocessor(AccessController.class.getName()); UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE).build()); UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE2).build()); // grants on global grantGlobal(UTIL, USER_GLOBAL_ADMIN.getShortName(), Permission.Action.ADMIN); grantGlobal(UTIL, USER_GLOBAL_CREATE.getShortName(), Permission.Action.CREATE); grantGlobal(UTIL, USER_GLOBAL_WRITE.getShortName(), Permission.Action.WRITE); grantGlobal(UTIL, USER_GLOBAL_READ.getShortName(), Permission.Action.READ); grantGlobal(UTIL, USER_GLOBAL_EXEC.getShortName(), Permission.Action.EXEC); // grants on namespace grantOnNamespace(UTIL, USER_NS_ADMIN.getShortName(), TEST_NAMESPACE, Permission.Action.ADMIN); grantOnNamespace(UTIL, USER_NS_CREATE.getShortName(), TEST_NAMESPACE, Permission.Action.CREATE); grantOnNamespace(UTIL, USER_NS_WRITE.getShortName(), TEST_NAMESPACE, Permission.Action.WRITE); grantOnNamespace(UTIL, USER_NS_READ.getShortName(), TEST_NAMESPACE, Permission.Action.READ); grantOnNamespace(UTIL, USER_NS_EXEC.getShortName(), TEST_NAMESPACE, Permission.Action.EXEC); grantOnNamespace(UTIL, toGroupEntry(GROUP_NS_ADMIN), TEST_NAMESPACE, Permission.Action.ADMIN); grantOnNamespace(UTIL, USER_NS_ADMIN.getShortName(), TEST_NAMESPACE2, Permission.Action.ADMIN); grantGlobal(UTIL, toGroupEntry(GROUP_ADMIN), Permission.Action.ADMIN); grantGlobal(UTIL, toGroupEntry(GROUP_CREATE), Permission.Action.CREATE); grantGlobal(UTIL, toGroupEntry(GROUP_READ), Permission.Action.READ); grantGlobal(UTIL, toGroupEntry(GROUP_WRITE), Permission.Action.WRITE); }
@Test public void testACLTableAccess() throws Exception { final Configuration conf = TEST_UTIL.getConfiguration(); // Superuser User superUser = User.createUserForTesting(conf, "admin", new String[] {"supergroup"}); // Global users User globalRead = User.createUserForTesting(conf, "globalRead", new String[0]); User globalWrite = User.createUserForTesting(conf, "globalWrite", new String[0]); User globalCreate = User.createUserForTesting(conf, "globalCreate", new String[0]); User globalAdmin = User.createUserForTesting(conf, "globalAdmin", new String[0]); SecureTestUtil.grantGlobal(TEST_UTIL, globalRead.getShortName(), Action.READ); SecureTestUtil.grantGlobal(TEST_UTIL, globalWrite.getShortName(), Action.WRITE); SecureTestUtil.grantGlobal(TEST_UTIL, globalCreate.getShortName(), Action.CREATE); SecureTestUtil.grantGlobal(TEST_UTIL, globalAdmin.getShortName(), Action.ADMIN); // Namespace users User nsRead = User.createUserForTesting(conf, "nsRead", new String[0]); User nsWrite = User.createUserForTesting(conf, "nsWrite", new String[0]); User nsCreate = User.createUserForTesting(conf, "nsCreate", new String[0]); User nsAdmin = User.createUserForTesting(conf, "nsAdmin", new String[0]); SecureTestUtil.grantOnNamespace( TEST_UTIL, nsRead.getShortName(), TEST_TABLE.getTableName().getNamespaceAsString(), Action.READ); SecureTestUtil.grantOnNamespace( TEST_UTIL, nsWrite.getShortName(), TEST_TABLE.getTableName().getNamespaceAsString(), Action.WRITE); SecureTestUtil.grantOnNamespace( TEST_UTIL, nsCreate.getShortName(), TEST_TABLE.getTableName().getNamespaceAsString(), Action.CREATE); SecureTestUtil.grantOnNamespace( TEST_UTIL, nsAdmin.getShortName(), TEST_TABLE.getTableName().getNamespaceAsString(), Action.ADMIN); // Table users User tableRead = User.createUserForTesting(conf, "tableRead", new String[0]); User tableWrite = User.createUserForTesting(conf, "tableWrite", new String[0]); User tableCreate = User.createUserForTesting(conf, "tableCreate", new String[0]); User tableAdmin = User.createUserForTesting(conf, "tableAdmin", new String[0]); SecureTestUtil.grantOnTable( TEST_UTIL, tableRead.getShortName(), TEST_TABLE.getTableName(), null, null, Action.READ); SecureTestUtil.grantOnTable( TEST_UTIL, tableWrite.getShortName(), TEST_TABLE.getTableName(), null, null, Action.WRITE); SecureTestUtil.grantOnTable( TEST_UTIL, tableCreate.getShortName(), TEST_TABLE.getTableName(), null, null, Action.CREATE); SecureTestUtil.grantOnTable( TEST_UTIL, tableAdmin.getShortName(), TEST_TABLE.getTableName(), null, null, Action.ADMIN); // Write tests AccessTestAction writeAction = new AccessTestAction() { @Override public Object run() throws Exception { try (Connection conn = ConnectionFactory.createConnection(conf); Table t = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) { t.put( new Put(TEST_ROW) .add(AccessControlLists.ACL_LIST_FAMILY, TEST_QUALIFIER, TEST_VALUE)); return null; } finally { } } }; // All writes to ACL table denied except for GLOBAL WRITE permission and superuser verifyDenied(writeAction, globalAdmin, globalCreate, globalRead); verifyDenied(writeAction, nsAdmin, nsCreate, nsRead, nsWrite); verifyDenied(writeAction, tableAdmin, tableCreate, tableRead, tableWrite); verifyAllowed(writeAction, superUser, globalWrite); // Read tests AccessTestAction scanAction = new AccessTestAction() { @Override public Object run() throws Exception { try (Connection conn = ConnectionFactory.createConnection(conf); Table t = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) { ResultScanner s = t.getScanner(new Scan()); try { for (Result r = s.next(); r != null; r = s.next()) { // do nothing } } finally { s.close(); } return null; } } }; // All reads from ACL table denied except for GLOBAL READ and superuser verifyDenied(scanAction, globalAdmin, globalCreate, globalWrite); verifyDenied(scanAction, nsCreate, nsAdmin, nsRead, nsWrite); verifyDenied(scanAction, tableCreate, tableAdmin, tableRead, tableWrite); verifyAllowed(scanAction, superUser, globalRead); }
@Test public void testManageUserAuths() throws Throwable { // Even though authorization is disabled, we should be able to manage user auths SUPERUSER.runAs( new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { try (Connection conn = ConnectionFactory.createConnection(conf)) { VisibilityClient.setAuths( conn, new String[] {SECRET, CONFIDENTIAL}, USER_RW.getShortName()); } catch (Throwable t) { fail("Should not have failed"); } return null; } }); PrivilegedExceptionAction<List<String>> getAuths = new PrivilegedExceptionAction<List<String>>() { public List<String> run() throws Exception { GetAuthsResponse authsResponse = null; try (Connection conn = ConnectionFactory.createConnection(conf)) { authsResponse = VisibilityClient.getAuths(conn, USER_RW.getShortName()); } catch (Throwable t) { fail("Should not have failed"); } List<String> authsList = new ArrayList<String>(); for (ByteString authBS : authsResponse.getAuthList()) { authsList.add(Bytes.toString(authBS.toByteArray())); } return authsList; } }; List<String> authsList = SUPERUSER.runAs(getAuths); assertEquals(2, authsList.size()); assertTrue(authsList.contains(SECRET)); assertTrue(authsList.contains(CONFIDENTIAL)); SUPERUSER.runAs( new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { try (Connection conn = ConnectionFactory.createConnection(conf)) { VisibilityClient.clearAuths(conn, new String[] {SECRET}, USER_RW.getShortName()); } catch (Throwable t) { fail("Should not have failed"); } return null; } }); authsList = SUPERUSER.runAs(getAuths); assertEquals(1, authsList.size()); assertTrue(authsList.contains(CONFIDENTIAL)); SUPERUSER.runAs( new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { try (Connection conn = ConnectionFactory.createConnection(conf)) { VisibilityClient.clearAuths( conn, new String[] {CONFIDENTIAL}, USER_RW.getShortName()); } catch (Throwable t) { fail("Should not have failed"); } return null; } }); authsList = SUPERUSER.runAs(getAuths); assertEquals(0, authsList.size()); }