diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt
index c0ccd0a58e..6d56c095a5 100644
--- a/hadoop-common-project/hadoop-common/CHANGES.txt
+++ b/hadoop-common-project/hadoop-common/CHANGES.txt
@@ -379,6 +379,8 @@ Trunk (Unreleased)
NativeAzureFileSystem#NativeAzureFsInputStream#close().
(Chen He via cnauroth)
+ HADOOP-10831. UserProvider is not thread safe. (Benoy Antony via umamahesh)
+
OPTIMIZATIONS
HADOOP-7761. Improve the performance of raw comparisons. (todd)
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/CredentialProvider.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/CredentialProvider.java
index bded4b972a..63c1cb48bf 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/CredentialProvider.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/CredentialProvider.java
@@ -29,6 +29,8 @@
* abstraction to separate credential storage from users of them. It
* is intended to support getting or storing passwords in a variety of ways,
* including third party bindings.
+ *
+ * CredentialProvider
implementations must be thread safe.
*/
@InterfaceAudience.Public
@InterfaceStability.Unstable
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/UserProvider.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/UserProvider.java
index 9e724c070b..99d6d0060d 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/UserProvider.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/UserProvider.java
@@ -55,7 +55,7 @@ public boolean isTransient() {
}
@Override
- public CredentialEntry getCredentialEntry(String alias) {
+ public synchronized CredentialEntry getCredentialEntry(String alias) {
byte[] bytes = credentials.getSecretKey(new Text(alias));
if (bytes == null) {
return null;
@@ -64,7 +64,7 @@ public CredentialEntry getCredentialEntry(String alias) {
}
@Override
- public CredentialEntry createCredentialEntry(String name, char[] credential)
+ public synchronized CredentialEntry createCredentialEntry(String name, char[] credential)
throws IOException {
Text nameT = new Text(name);
if (credentials.getSecretKey(nameT) != null) {
@@ -77,7 +77,7 @@ public CredentialEntry createCredentialEntry(String name, char[] credential)
}
@Override
- public void deleteCredentialEntry(String name) throws IOException {
+ public synchronized void deleteCredentialEntry(String name) throws IOException {
byte[] cred = credentials.getSecretKey(new Text(name));
if (cred != null) {
credentials.removeSecretKey(new Text(name));
@@ -95,7 +95,7 @@ public String toString() {
}
@Override
- public void flush() {
+ public synchronized void flush() {
user.addCredentials(credentials);
}
@@ -112,7 +112,7 @@ public CredentialProvider createProvider(URI providerName,
}
@Override
- public List getAliases() throws IOException {
+ public synchronized List getAliases() throws IOException {
List list = new ArrayList();
List aliases = credentials.getAllSecretKeys();
for (Text key : aliases) {