Skip to content

Commit c867ebe

Browse files
committed
HDFS-4983. Numeric usernames do not work with WebHDFS FS. Contributed by Yongjun Zhang.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1548968 13f79535-47bb-0310-9956-ffa450edef68
1 parent 14f4623 commit c867ebe

File tree

8 files changed

+83
-6
lines changed

8 files changed

+83
-6
lines changed

hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,9 @@ Release 2.4.0 - UNRELEASED
584584

585585
HDFS-5633. Improve OfflineImageViewer to use less memory. (jing9)
586586

587+
HDFS-4983. Numeric usernames do not work with WebHDFS FS. (Yongjun Zhang via
588+
jing9)
589+
587590
OPTIMIZATIONS
588591

589592
HDFS-5239. Allow FSNamesystem lock fairness to be configurable (daryn)

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSConfigKeys.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ public class DFSConfigKeys extends CommonConfigurationKeys {
164164
public static final int DFS_NAMENODE_REPLICATION_STREAMS_HARD_LIMIT_DEFAULT = 4;
165165
public static final String DFS_WEBHDFS_ENABLED_KEY = "dfs.webhdfs.enabled";
166166
public static final boolean DFS_WEBHDFS_ENABLED_DEFAULT = true;
167+
public static final String DFS_WEBHDFS_USER_PATTERN_KEY = "dfs.webhdfs.user.provider.user.pattern";
168+
public static final String DFS_WEBHDFS_USER_PATTERN_DEFAULT = "^[A-Za-z_][A-Za-z0-9._-]*[$]?$";
167169
public static final String DFS_PERMISSIONS_ENABLED_KEY = "dfs.permissions.enabled";
168170
public static final boolean DFS_PERMISSIONS_ENABLED_DEFAULT = true;
169171
public static final String DFS_PERMISSIONS_SUPERUSERGROUP_KEY = "dfs.permissions.superusergroup";

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeHttpServer.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.apache.hadoop.hdfs.web.AuthFilter;
4040
import org.apache.hadoop.hdfs.web.WebHdfsFileSystem;
4141
import org.apache.hadoop.hdfs.web.resources.Param;
42+
import org.apache.hadoop.hdfs.web.resources.UserParam;
4243
import org.apache.hadoop.http.HttpConfig;
4344
import org.apache.hadoop.http.HttpServer;
4445
import org.apache.hadoop.net.NetUtils;
@@ -73,7 +74,10 @@ public class NameNodeHttpServer {
7374

7475
private void initWebHdfs(Configuration conf) throws IOException {
7576
if (WebHdfsFileSystem.isEnabled(conf, HttpServer.LOG)) {
76-
//add SPNEGO authentication filter for webhdfs
77+
// set user pattern based on configuration file
78+
UserParam.setUserPattern(conf.get(DFSConfigKeys.DFS_WEBHDFS_USER_PATTERN_KEY, DFSConfigKeys.DFS_WEBHDFS_USER_PATTERN_DEFAULT));
79+
80+
// add SPNEGO authentication filter for webhdfs
7781
final String name = "SPNEGO";
7882
final String classname = AuthFilter.class.getName();
7983
final String pathSpec = WebHdfsFileSystem.PATH_PREFIX + "/*";

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/WebHdfsFileSystem.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ public synchronized void initialize(URI uri, Configuration conf
157157
) throws IOException {
158158
super.initialize(uri, conf);
159159
setConf(conf);
160+
/** set user pattern based on configuration file */
161+
UserParam.setUserPattern(conf.get(DFSConfigKeys.DFS_WEBHDFS_USER_PATTERN_KEY, DFSConfigKeys.DFS_WEBHDFS_USER_PATTERN_DEFAULT));
160162
connectionFactory = URLConnectionFactory
161163
.newDefaultURLConnectionFactory(conf);
162164
initializeTokenAspect();

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/resources/UserParam.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
*/
1818
package org.apache.hadoop.hdfs.web.resources;
1919

20+
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_WEBHDFS_USER_PATTERN_DEFAULT;
2021
import org.apache.hadoop.security.UserGroupInformation;
21-
22+
import com.google.common.annotations.VisibleForTesting;
23+
2224
import java.text.MessageFormat;
2325
import java.util.regex.Pattern;
2426

@@ -29,8 +31,21 @@ public class UserParam extends StringParam {
2931
/** Default parameter value. */
3032
public static final String DEFAULT = "";
3133

32-
private static final Domain DOMAIN = new Domain(NAME,
33-
Pattern.compile("^[A-Za-z_][A-Za-z0-9._-]*[$]?$"));
34+
private static Domain domain = new Domain(NAME, Pattern.compile(DFS_WEBHDFS_USER_PATTERN_DEFAULT));
35+
36+
@VisibleForTesting
37+
public static Domain getUserPatternDomain() {
38+
return domain;
39+
}
40+
41+
@VisibleForTesting
42+
public static void setUserPatternDomain(Domain dm) {
43+
domain = dm;
44+
}
45+
46+
public static void setUserPattern(String pattern) {
47+
domain = new Domain(NAME, Pattern.compile(pattern));
48+
}
3449

3550
private static String validateLength(String str) {
3651
if (str == null) {
@@ -50,7 +65,7 @@ private static String validateLength(String str) {
5065
* @param str a string representation of the parameter value.
5166
*/
5267
public UserParam(final String str) {
53-
super(DOMAIN, str == null || str.equals(DEFAULT)? null : validateLength(str));
68+
super(domain, str == null || str.equals(DEFAULT)? null : validateLength(str));
5469
}
5570

5671
/**
@@ -64,4 +79,4 @@ public UserParam(final UserGroupInformation ugi) {
6479
public String getName() {
6580
return NAME;
6681
}
67-
}
82+
}

hadoop-hdfs-project/hadoop-hdfs/src/main/resources/hdfs-default.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,4 +1593,12 @@
15931593
</description>
15941594
</property>
15951595

1596+
<property>
1597+
<name>dfs.webhdfs.user.provider.user.pattern</name>
1598+
<value>^[A-Za-z_][A-Za-z0-9._-]*[$]?$</value>
1599+
<description>
1600+
Valid pattern for user and group names for webhdfs, it must be a valid java regex.
1601+
</description>
1602+
</property>
1603+
15961604
</configuration>

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestWebHDFS.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,34 @@ public Void run() throws IOException, URISyntaxException {
261261
}
262262
}
263263

264+
@Test(timeout=300000)
265+
public void testNumericalUserName() throws Exception {
266+
final Configuration conf = WebHdfsTestUtil.createConf();
267+
conf.set(DFSConfigKeys.DFS_WEBHDFS_USER_PATTERN_KEY, "^[A-Za-z0-9_][A-Za-z0-9._-]*[$]?$");
268+
final MiniDFSCluster cluster =
269+
new MiniDFSCluster.Builder(conf).numDataNodes(1).build();
270+
try {
271+
cluster.waitActive();
272+
WebHdfsTestUtil.getWebHdfsFileSystem(conf, WebHdfsFileSystem.SCHEME)
273+
.setPermission(new Path("/"),
274+
new FsPermission(FsAction.ALL, FsAction.ALL, FsAction.ALL));
275+
276+
UserGroupInformation.createUserForTesting("123", new String[]{"my-group"})
277+
.doAs(new PrivilegedExceptionAction<Void>() {
278+
@Override
279+
public Void run() throws IOException, URISyntaxException {
280+
FileSystem fs = WebHdfsTestUtil.getWebHdfsFileSystem(conf,
281+
WebHdfsFileSystem.SCHEME);
282+
Path d = new Path("/my-dir");
283+
Assert.assertTrue(fs.mkdirs(d));
284+
return null;
285+
}
286+
});
287+
} finally {
288+
cluster.shutdown();
289+
}
290+
}
291+
264292
/**
265293
* WebHdfs should be enabled by default after HDFS-5532
266294
*

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/resources/TestParam.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,4 +285,19 @@ public void testConcatSourcesParam() {
285285
Assert.assertEquals(expected, computed.getValue());
286286
}
287287
}
288+
289+
@Test
290+
public void testUserNameOkAfterResettingPattern() {
291+
UserParam.Domain oldDomain = UserParam.getUserPatternDomain();
292+
293+
String newPattern = "^[A-Za-z0-9_][A-Za-z0-9._-]*[$]?$";
294+
UserParam.setUserPattern(newPattern);
295+
296+
UserParam userParam = new UserParam("1x");
297+
assertNotNull(userParam.getValue());
298+
userParam = new UserParam("123");
299+
assertNotNull(userParam.getValue());
300+
301+
UserParam.setUserPatternDomain(oldDomain);
302+
}
288303
}

0 commit comments

Comments
 (0)