diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java
index 83eb5ad8bc..f24009d40d 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java
@@ -149,6 +149,10 @@ public class LdapGroupsMapping
public static final String BIND_PASSWORD_FILE_KEY = BIND_PASSWORD_KEY + ".file";
public static final String BIND_PASSWORD_FILE_DEFAULT = "";
+ public static final String BIND_PASSWORD_ALIAS_KEY =
+ BIND_PASSWORD_KEY + ".alias";
+ public static final String BIND_PASSWORD_ALIAS_DEFAULT = "";
+
/*
* Base distinguished name to use for searches
*/
@@ -662,12 +666,19 @@ public synchronized void setConf(Configuration conf) {
}
bindUser = conf.get(BIND_USER_KEY, BIND_USER_DEFAULT);
- bindPassword = getPassword(conf, BIND_PASSWORD_KEY, BIND_PASSWORD_DEFAULT);
+
+ String alias = conf.get(BIND_PASSWORD_ALIAS_KEY,
+ BIND_PASSWORD_ALIAS_DEFAULT);
+ bindPassword = getPasswordFromCredentialProviders(conf, alias, "");
if (bindPassword.isEmpty()) {
- bindPassword = extractPassword(
- conf.get(BIND_PASSWORD_FILE_KEY, BIND_PASSWORD_FILE_DEFAULT));
+ bindPassword = getPassword(conf, BIND_PASSWORD_KEY,
+ BIND_PASSWORD_DEFAULT);
+ if (bindPassword.isEmpty()) {
+ bindPassword = extractPassword(
+ conf.get(BIND_PASSWORD_FILE_KEY, BIND_PASSWORD_FILE_DEFAULT));
+ }
}
-
+
String baseDN = conf.getTrimmed(BASE_DN_KEY, BASE_DN_DEFAULT);
// User search base which defaults to base dn.
@@ -755,10 +766,10 @@ private void loadSslConf(Configuration sslConf) {
}
String getPasswordFromCredentialProviders(
- Configuration conf, String alias, String defaultPass) {
+ Configuration config, String alias, String defaultPass) {
String password = defaultPass;
try {
- char[] passchars = conf.getPasswordFromCredentialProviders(alias);
+ char[] passchars = config.getPasswordFromCredentialProviders(alias);
if (passchars != null) {
password = new String(passchars);
}
diff --git a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml
index 28e910ba26..f7d61c6d01 100644
--- a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml
+++ b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml
@@ -370,6 +370,16 @@
+
+ hadoop.security.group.mapping.ldap.bind.password.alias
+
+
+ The alias of the bind user to be used to get the password from credential
+ providers. If the alias is empty, property
+ hadoop.security.group.mapping.ldap.bind.password is used instead.
+
+
+
hadoop.security.group.mapping.ldap.bind.password.file
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMapping.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMapping.java
index a361d04a72..174333859b 100644
--- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMapping.java
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMapping.java
@@ -300,13 +300,53 @@ public void testConfGetPassword() throws Exception {
mapping.getPassword(conf, LdapGroupsMapping.BIND_PASSWORD_KEY, ""));
Assert.assertEquals("storepass",
mapping.getPassword(conf, LdapGroupsMapping.LDAP_KEYSTORE_PASSWORD_KEY,
- ""));
+ ""));
// let's make sure that a password that doesn't exist returns an
// empty string as currently expected and used to trigger a call to
// extract password
Assert.assertEquals("", mapping.getPassword(conf,"invalid-alias", ""));
}
+ @Test
+ public void testConfGetPasswordUsingAlias() throws Exception {
+ File testDir = GenericTestUtils.getTestDir();
+ Configuration conf = getBaseConf();
+ final Path jksPath = new Path(testDir.toString(), "test.jks");
+ final String ourUrl =
+ JavaKeyStoreProvider.SCHEME_NAME + "://file" + jksPath.toUri();
+
+ File file = new File(testDir, "test.jks");
+ file.delete();
+ conf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, ourUrl);
+
+ // Set alias
+ String bindpassAlias = "bindpassAlias";
+ conf.set(LdapGroupsMapping.BIND_PASSWORD_ALIAS_KEY, bindpassAlias);
+
+ CredentialProvider provider =
+ CredentialProviderFactory.getProviders(conf).get(0);
+ char[] bindpass = "bindpass".toCharArray();
+
+ // Ensure that we get null when the key isn't there
+ assertNull(provider.getCredentialEntry(bindpassAlias));
+
+ // Create credential for the alias
+ provider.createCredentialEntry(bindpassAlias, bindpass);
+ provider.flush();
+
+ // Make sure we get back the right key
+ assertArrayEquals(bindpass, provider.getCredentialEntry(
+ bindpassAlias).getCredential());
+
+ LdapGroupsMapping mapping = new LdapGroupsMapping();
+ Assert.assertEquals("bindpass",
+ mapping.getPasswordFromCredentialProviders(conf, bindpassAlias, ""));
+
+ // Empty for an invalid alias
+ Assert.assertEquals("", mapping.getPasswordFromCredentialProviders(
+ conf, "invalid-alias", ""));
+ }
+
/**
* Test that if the {@link LdapGroupsMapping#CONNECTION_TIMEOUT} is set in the
* configuration, the LdapGroupsMapping connection will timeout by this value