From 06b2eceb76fed768b4a48ca6dd5bccb9864740ed Mon Sep 17 00:00:00 2001 From: Inigo Goiri Date: Tue, 16 Apr 2019 10:34:31 -0700 Subject: [PATCH] HDFS-14418. Remove redundant super user priveledge checks from namenode. Contributed by Ayush Saxena. (cherry picked from commit be6c8014e66be919388269b70cb2966c35b8c578) --- .../hdfs/server/namenode/FSNamesystem.java | 3 - .../server/namenode/NameNodeRpcServer.java | 1 - .../hdfs/TestDistributedFileSystem.java | 55 +++++++++++++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java index 94d4af31b56..cfc4cf48f37 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java @@ -7362,7 +7362,6 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean, Metadata metadata = FSDirEncryptionZoneOp.ensureKeyIsInitialized(dir, keyName, src); final FSPermissionChecker pc = getPermissionChecker(); - checkSuperuserPrivilege(pc); checkOperation(OperationCategory.WRITE); final FileStatus resultingStat; writeLock(); @@ -7424,7 +7423,6 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean, boolean success = false; checkOperation(OperationCategory.READ); final FSPermissionChecker pc = getPermissionChecker(); - checkSuperuserPrivilege(pc); readLock(); try { checkOperation(OperationCategory.READ); @@ -7462,7 +7460,6 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean, boolean success = false; checkOperation(OperationCategory.READ); final FSPermissionChecker pc = getPermissionChecker(); - checkSuperuserPrivilege(pc); readLock(); try { checkOperation(OperationCategory.READ); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeRpcServer.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeRpcServer.java index 44f397b61b3..a784107e2fa 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeRpcServer.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeRpcServer.java @@ -1307,7 +1307,6 @@ public class NameNodeRpcServer implements NamenodeProtocols { @Override // NamenodeProtocol public CheckpointSignature rollEditLog() throws IOException { checkNNStartup(); - namesystem.checkSuperuserPrivilege(); return namesystem.rollEditLog(); } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java index 394ec388c49..f1d30a38374 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java @@ -94,6 +94,7 @@ import org.apache.hadoop.hdfs.server.datanode.fsdataset.FsVolumeSpi; import org.apache.hadoop.hdfs.server.namenode.ErasureCodingPolicyManager; import org.apache.hadoop.hdfs.web.WebHdfsConstants; import org.apache.hadoop.io.erasurecode.ECSchema; +import org.apache.hadoop.ipc.RemoteException; import org.apache.hadoop.net.DNSToSwitchMapping; import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.net.ScriptBasedMapping; @@ -101,6 +102,7 @@ import org.apache.hadoop.net.StaticMapping; import org.apache.hadoop.security.AccessControlException; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.test.GenericTestUtils; +import org.apache.hadoop.test.LambdaTestUtils; import org.apache.hadoop.test.Whitebox; import org.apache.hadoop.util.DataChecksum; import org.apache.hadoop.util.Time; @@ -1664,6 +1666,59 @@ public class TestDistributedFileSystem { } } + @Test + public void testSuperUserPrivilege() throws Exception { + HdfsConfiguration conf = new HdfsConfiguration(); + File tmpDir = GenericTestUtils.getTestDir(UUID.randomUUID().toString()); + final Path jksPath = new Path(tmpDir.toString(), "test.jks"); + conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_KEY_PROVIDER_PATH, + JavaKeyStoreProvider.SCHEME_NAME + "://file" + jksPath.toUri()); + + try (MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).build()) { + cluster.waitActive(); + final DistributedFileSystem dfs = cluster.getFileSystem(); + Path dir = new Path("/testPrivilege"); + dfs.mkdirs(dir); + + final KeyProvider provider = + cluster.getNameNode().getNamesystem().getProvider(); + final KeyProvider.Options options = KeyProvider.options(conf); + provider.createKey("key", options); + provider.flush(); + + // Create a non-super user. + UserGroupInformation user = UserGroupInformation.createUserForTesting( + "Non_SuperUser", new String[] {"Non_SuperGroup"}); + + DistributedFileSystem userfs = (DistributedFileSystem) user.doAs( + (PrivilegedExceptionAction) () -> FileSystem.get(conf)); + + LambdaTestUtils.intercept(AccessControlException.class, + "Superuser privilege is required", + () -> userfs.createEncryptionZone(dir, "key")); + + RemoteException re = LambdaTestUtils.intercept(RemoteException.class, + "Superuser privilege is required", + () -> userfs.listEncryptionZones().hasNext()); + assertTrue(re.unwrapRemoteException() instanceof AccessControlException); + + re = LambdaTestUtils.intercept(RemoteException.class, + "Superuser privilege is required", + () -> userfs.listReencryptionStatus().hasNext()); + assertTrue(re.unwrapRemoteException() instanceof AccessControlException); + + LambdaTestUtils.intercept(AccessControlException.class, + "Superuser privilege is required", + () -> user.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + cluster.getNameNode().getRpcServer().rollEditLog(); + return null; + } + })); + } + } + @Test public void testRemoveErasureCodingPolicy() throws Exception { Configuration conf = getTestConfiguration();