Skip to content

Commit 730d484

Browse files
authored
Allow only root user to read fate and scanref tables by default (#6203)
Allow only root user to read fate and scanref tables by default Closes #6137
1 parent e65f1b2 commit 730d484

File tree

2 files changed

+62
-6
lines changed

2 files changed

+62
-6
lines changed

server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import org.apache.accumulo.core.client.TableNotFoundException;
3232
import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
3333
import org.apache.accumulo.core.clientImpl.Credentials;
34-
import org.apache.accumulo.core.clientImpl.Namespace;
3534
import org.apache.accumulo.core.clientImpl.thrift.SecurityErrorCode;
3635
import org.apache.accumulo.core.clientImpl.thrift.ThriftSecurityException;
3736
import org.apache.accumulo.core.conf.Property;
@@ -355,6 +354,7 @@ private boolean _hasTablePermission(String user, TableId table, TablePermission
355354
boolean useCached) throws ThriftSecurityException {
356355
targetUserExists(user);
357356

357+
// Allow all users to read root and metadata tables
358358
if ((table.equals(SystemTables.METADATA.tableId()) || table.equals(SystemTables.ROOT.tableId()))
359359
&& permission.equals(TablePermission.READ)) {
360360
return true;
@@ -384,10 +384,6 @@ private boolean _hasNamespacePermission(String user, NamespaceId namespace,
384384

385385
targetUserExists(user);
386386

387-
if (namespace.equals(Namespace.ACCUMULO.id()) && permission.equals(NamespacePermission.READ)) {
388-
return true;
389-
}
390-
391387
try {
392388
if (useCached) {
393389
return permHandle.hasCachedNamespacePermission(user, namespace.canonical(), permission);

test/src/main/java/org/apache/accumulo/test/functional/PermissionsIT.java

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static org.junit.jupiter.api.Assertions.assertEquals;
2323
import static org.junit.jupiter.api.Assertions.assertFalse;
2424
import static org.junit.jupiter.api.Assertions.assertNotNull;
25+
import static org.junit.jupiter.api.Assertions.assertThrows;
2526
import static org.junit.jupiter.api.Assertions.assertTrue;
2627
import static org.junit.jupiter.api.Assumptions.assumeTrue;
2728

@@ -694,6 +695,42 @@ public void tablePermissionTest() throws Exception {
694695
}
695696
loginAs(rootUser);
696697
try (AccumuloClient c = Accumulo.newClient().from(getClientProps()).build()) {
698+
699+
// check root user permissions on FATE and SCAN_REF tables
700+
verifyHasOnlyTheseTablePermissions(c, c.whoami(), SystemTables.FATE.tableName());
701+
verifyHasOnlyTheseTablePermissions(c, c.whoami(), SystemTables.SCAN_REF.tableName());
702+
for (String tn : SystemTables.tableNames()) {
703+
try (Scanner s = c.createScanner(tn)) {
704+
if (SystemTables.ROOT.tableName().equals(tn)
705+
|| SystemTables.METADATA.tableName().equals(tn)) {
706+
@SuppressWarnings("unused")
707+
var unused = s.iterator().hasNext();
708+
} else {
709+
IllegalStateException ise =
710+
assertThrows(IllegalStateException.class, () -> s.iterator().hasNext());
711+
assertTrue(ise.getMessage().contains("Error PERMISSION_DENIED for user"),
712+
"Permission denied error not thrown for root user scan of table: " + tn
713+
+ ". Message = " + ise.getMessage());
714+
}
715+
}
716+
}
717+
718+
// Give the root user the read permission and try again.
719+
c.securityOperations().grantTablePermission(rootUser.getPrincipal(),
720+
SystemTables.FATE.tableName(), TablePermission.READ);
721+
c.securityOperations().grantTablePermission(rootUser.getPrincipal(),
722+
SystemTables.SCAN_REF.tableName(), TablePermission.READ);
723+
verifyHasOnlyTheseTablePermissions(c, c.whoami(), SystemTables.FATE.tableName(),
724+
TablePermission.READ);
725+
verifyHasOnlyTheseTablePermissions(c, c.whoami(), SystemTables.SCAN_REF.tableName(),
726+
TablePermission.READ);
727+
for (String tn : SystemTables.tableNames()) {
728+
try (Scanner s = c.createScanner(tn)) {
729+
@SuppressWarnings("unused")
730+
var unused = s.iterator().hasNext();
731+
}
732+
}
733+
697734
c.securityOperations().createLocalUser(principal, passwordToken);
698735
loginAs(testUser);
699736
try (AccumuloClient test_user_client =
@@ -703,8 +740,31 @@ public void tablePermissionTest() throws Exception {
703740
loginAs(rootUser);
704741
verifyHasOnlyTheseTablePermissions(c, c.whoami(), SystemTables.METADATA.tableName(),
705742
TablePermission.READ, TablePermission.ALTER_TABLE);
706-
String tableName = getUniqueNames(1)[0] + "__TABLE_PERMISSION_TEST__";
707743

744+
// check test user permissions on FATE and SCAN_REF tables
745+
loginAs(testUser);
746+
verifyHasOnlyTheseTablePermissions(c, test_user_client.whoami(),
747+
SystemTables.FATE.tableName());
748+
verifyHasOnlyTheseTablePermissions(c, test_user_client.whoami(),
749+
SystemTables.SCAN_REF.tableName());
750+
for (String tn : SystemTables.tableNames()) {
751+
try (Scanner s = test_user_client.createScanner(tn)) {
752+
if (SystemTables.ROOT.tableName().equals(tn)
753+
|| SystemTables.METADATA.tableName().equals(tn)) {
754+
@SuppressWarnings("unused")
755+
var unused = s.iterator().hasNext();
756+
} else {
757+
IllegalStateException ise =
758+
assertThrows(IllegalStateException.class, () -> s.iterator().hasNext());
759+
assertTrue(ise.getMessage().contains("Error PERMISSION_DENIED for user"),
760+
"Permission denied error not thrown for root user scan of table: " + tn
761+
+ ". Message = " + ise.getMessage());
762+
}
763+
}
764+
}
765+
766+
loginAs(rootUser);
767+
String tableName = getUniqueNames(1)[0] + "__TABLE_PERMISSION_TEST__";
708768
// test each permission
709769
for (TablePermission perm : TablePermission.values()) {
710770
if (perm == TablePermission.ALTER_TABLE) {

0 commit comments

Comments
 (0)