Author: atm
Date: Thu May 17 10:23:18 2012
New Revision: 1339540
URL: http://svn.apache.org/viewvc?rev=1339540&view=rev
Log:
HDFS-3433. GetImageServlet should allow administrative requestors when security
is enabled. Contributed by Aaron T. Myers.
Modified:
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/GetImageServlet.java
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestGetImageServlet.java
Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt?rev=1339540&r1=1339539&r2=1339540&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt (original)
+++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt Thu May 17
10:23:18 2012
@@ -208,6 +208,9 @@ Release 2.0.1-alpha - UNRELEASED
HDFS-3422. TestStandbyIsHot timeouts too aggressive (todd)
+ HDFS-3433. GetImageServlet should allow administrative requestors when
+ security is enabled. (atm)
+
Release 2.0.0-alpha - UNRELEASED
INCOMPATIBLE CHANGES
Modified:
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/GetImageServlet.java
URL:
http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/GetImageServlet.java?rev=1339540&r1=1339539&r2=1339540&view=diff
==============================================================================
---
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/GetImageServlet.java
(original)
+++
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/GetImageServlet.java
Thu May 17 10:23:18 2012
@@ -44,6 +44,7 @@ import org.apache.hadoop.hdfs.server.com
import org.apache.hadoop.hdfs.server.protocol.RemoteEditLog;
import org.apache.hadoop.hdfs.util.DataTransferThrottler;
import org.apache.hadoop.hdfs.util.MD5FileUtils;
+import org.apache.hadoop.http.HttpServer;
import org.apache.hadoop.io.MD5Hash;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.util.StringUtils;
@@ -85,11 +86,12 @@ public class GetImageServlet extends Htt
final Configuration conf =
(Configuration)getServletContext().getAttribute(JspHelper.CURRENT_CONF);
- if(UserGroupInformation.isSecurityEnabled() &&
- !isValidRequestor(request.getUserPrincipal().getName(), conf)) {
+ if (UserGroupInformation.isSecurityEnabled() &&
+ !isValidRequestor(context, request.getUserPrincipal().getName(),
conf)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN,
- "Only Namenode and Secondary Namenode may access this servlet");
- LOG.warn("Received non-NN/SNN request for image or edits from "
+ "Only Namenode, Secondary Namenode, and administrators may access
" +
+ "this servlet");
+ LOG.warn("Received non-NN/SNN/administrator request for image or edits
from "
+ request.getUserPrincipal().getName() + " at " +
request.getRemoteHost());
return;
}
@@ -209,8 +211,8 @@ public class GetImageServlet extends Htt
}
@VisibleForTesting
- static boolean isValidRequestor(String remoteUser, Configuration conf)
- throws IOException {
+ static boolean isValidRequestor(ServletContext context, String remoteUser,
+ Configuration conf) throws IOException {
if(remoteUser == null) { // This really shouldn't happen...
LOG.warn("Received null remoteUser while authorizing access to getImage
servlet");
return false;
@@ -237,11 +239,17 @@ public class GetImageServlet extends Htt
for(String v : validRequestors) {
if(v != null && v.equals(remoteUser)) {
- if(LOG.isInfoEnabled()) LOG.info("GetImageServlet allowing: " +
remoteUser);
+ LOG.info("GetImageServlet allowing checkpointer: " + remoteUser);
return true;
}
}
- if(LOG.isInfoEnabled()) LOG.info("GetImageServlet rejecting: " +
remoteUser);
+
+ if (HttpServer.userHasAdministratorAccess(context, remoteUser)) {
+ LOG.info("GetImageServlet allowing administrator: " + remoteUser);
+ return true;
+ }
+
+ LOG.info("GetImageServlet rejecting: " + remoteUser);
return false;
}
Modified:
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestGetImageServlet.java
URL:
http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestGetImageServlet.java?rev=1339540&r1=1339539&r2=1339540&view=diff
==============================================================================
---
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestGetImageServlet.java
(original)
+++
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestGetImageServlet.java
Thu May 17 10:23:18 2012
@@ -21,17 +21,26 @@ import static org.junit.Assert.*;
import java.io.IOException;
+import javax.servlet.ServletContext;
+
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.DFSUtil;
import org.apache.hadoop.hdfs.HdfsConfiguration;
+import org.apache.hadoop.http.HttpServer;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authentication.util.KerberosName;
+import org.apache.hadoop.security.authorize.AccessControlList;
import org.junit.Test;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mockito;
public class TestGetImageServlet {
@Test
- public void testIsValidRequestorWithHa() throws IOException {
+ public void testIsValidRequestor() throws IOException {
Configuration conf = new HdfsConfiguration();
+ KerberosName.setRules("RULE:[1:$1]\nRULE:[2:$1]");
// Set up generic HA configs.
conf.set(DFSConfigKeys.DFS_FEDERATION_NAMESERVICES, "ns1");
@@ -53,8 +62,33 @@ public class TestGetImageServlet {
// Initialize this conf object as though we're running on NN1.
NameNode.initializeGenericKeys(conf, "ns1", "nn1");
+ AccessControlList acls = Mockito.mock(AccessControlList.class);
+
Mockito.when(acls.isUserAllowed(Mockito.<UserGroupInformation>any())).thenReturn(false);
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(HttpServer.ADMINS_ACL)).thenReturn(acls);
+
// Make sure that NN2 is considered a valid fsimage/edits requestor.
- assertTrue(GetImageServlet.isValidRequestor("hdfs/[email protected]",
- conf));
+ assertTrue(GetImageServlet.isValidRequestor(context,
+ "hdfs/[email protected]", conf));
+
+ // Mark atm as an admin.
+ Mockito.when(acls.isUserAllowed(Mockito.argThat(new
ArgumentMatcher<UserGroupInformation>() {
+ @Override
+ public boolean matches(Object argument) {
+ return ((UserGroupInformation)
argument).getShortUserName().equals("atm");
+ }
+ }))).thenReturn(true);
+
+ // Make sure that NN2 is still considered a valid requestor.
+ assertTrue(GetImageServlet.isValidRequestor(context,
+ "hdfs/[email protected]", conf));
+
+ // Make sure an admin is considered a valid requestor.
+ assertTrue(GetImageServlet.isValidRequestor(context,
+ "[email protected]", conf));
+
+ // Make sure other users are *not* considered valid requestors.
+ assertFalse(GetImageServlet.isValidRequestor(context,
+ "[email protected]", conf));
}
}