Browse Source

AMBARI-22667: Use internal LDAP configuration values rather than ambari.properties values when accessing the configured LDAP server for LDAP sync and authentication

Sandor Molnar 8 năm trước cách đây
mục cha
commit
0aaf8c8534
33 tập tin đã thay đổi với 988 bổ sung926 xóa
  1. 0 1
      ambari-server/sbin/ambari-server
  2. 3 1
      ambari-server/src/main/java/org/apache/ambari/server/configuration/ComponentSSLConfiguration.java
  3. 6 440
      ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
  4. 29 0
      ambari-server/src/main/java/org/apache/ambari/server/configuration/LdapUsernameCollisionHandlingBehavior.java
  5. 2 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
  6. 6 1
      ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
  7. 34 0
      ambari-server/src/main/java/org/apache/ambari/server/events/JpaInitializedEvent.java
  8. 131 43
      ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfiguration.java
  9. 65 45
      ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationKeys.java
  10. 23 6
      ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
  11. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/orm/AmbariLocalSessionInterceptor.java
  12. 6 2
      ambari-server/src/main/java/org/apache/ambari/server/orm/GuiceJpaInitializer.java
  13. 9 6
      ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java
  14. 6 7
      ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java
  15. 6 84
      ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
  16. 3 3
      ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java
  17. 8 7
      ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
  18. 183 0
      ambari-server/src/main/java/org/apache/ambari/server/utils/PasswordUtils.java
  19. 5 0
      ambari-server/src/main/python/ambari-server.py
  20. 0 2
      ambari-server/src/main/windows/ambari-server.ps1
  21. 8 167
      ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java
  22. 143 0
      ambari-server/src/test/java/org/apache/ambari/server/ldap/AmbariLdapConfigurationTest.java
  23. 5 4
      ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderForDNWithSpaceTest.java
  24. 10 6
      ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderForDuplicateUserTest.java
  25. 17 11
      ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderTest.java
  26. 76 15
      ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticatorTest.java
  27. 2 1
      ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AuthorizationTestModule.java
  28. 3 2
      ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AuthorizationTestModuleForLdapDNWithSpace.java
  29. 6 14
      ambari-server/src/test/java/org/apache/ambari/server/security/authorization/LdapServerPropertiesTest.java
  30. 2 0
      ambari-server/src/test/java/org/apache/ambari/server/security/authorization/UsersTest.java
  31. 47 46
      ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
  32. 17 11
      ambari-server/src/test/java/org/apache/ambari/server/security/ldap/LdapPerformanceTest.java
  33. 126 0
      ambari-server/src/test/java/org/apache/ambari/server/utils/PasswordUtilsTest.java

+ 0 - 1
ambari-server/sbin/ambari-server

@@ -142,7 +142,6 @@ case "${1:-}" in
         $PYTHON "$AMBARI_PYTHON_EXECUTABLE" $@
         ;;
   setup-ldap)
-        echo -e "Setting up LDAP properties..."
         $PYTHON "$AMBARI_PYTHON_EXECUTABLE" $@
         ;;
   sync-ldap)

+ 3 - 1
ambari-server/src/main/java/org/apache/ambari/server/configuration/ComponentSSLConfiguration.java

@@ -17,6 +17,8 @@
  */
 package org.apache.ambari.server.configuration;
 
+import org.apache.ambari.server.utils.PasswordUtils;
+
 /**
  * Configuration for SSL communication between Ambari and 3rd party services.
  * Currently, the following services are supported with SSL communication:
@@ -116,7 +118,7 @@ public class ComponentSSLConfiguration {
 
   private String getPassword(Configuration configuration) {
     String rawPassword = configuration.getProperty(Configuration.SSL_TRUSTSTORE_PASSWORD.getKey());
-    String password    = configuration.readPasswordFromStore(rawPassword);
+    String password    = PasswordUtils.getInstance().readPasswordFromStore(rawPassword, configuration.getMasterKeyLocation(), configuration.isMasterKeyPersisted(), configuration.getMasterKeyStoreLocation());
 
     return password == null ? rawPassword : password;
   }

+ 6 - 440
ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java

@@ -51,7 +51,6 @@ import java.util.concurrent.TimeUnit;
 import org.apache.ambari.annotations.Experimental;
 import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.annotations.Markdown;
-import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.CommandExecutionType;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.Stage;
@@ -64,7 +63,6 @@ import org.apache.ambari.server.orm.dao.HostRoleCommandStatusSummaryDTO;
 import org.apache.ambari.server.orm.entities.StageEntity;
 import org.apache.ambari.server.security.ClientSecurityType;
 import org.apache.ambari.server.security.authentication.kerberos.AmbariKerberosAuthenticationProperties;
-import org.apache.ambari.server.security.authorization.LdapServerProperties;
 import org.apache.ambari.server.security.authorization.UserType;
 import org.apache.ambari.server.security.authorization.jwt.JwtAuthenticationProperties;
 import org.apache.ambari.server.security.encryption.CertificateUtils;
@@ -76,7 +74,7 @@ import org.apache.ambari.server.upgrade.AbstractUpgradeCatalog;
 import org.apache.ambari.server.utils.AmbariPath;
 import org.apache.ambari.server.utils.DateUtils;
 import org.apache.ambari.server.utils.HostUtils;
-import org.apache.ambari.server.utils.Parallel;
+import org.apache.ambari.server.utils.PasswordUtils;
 import org.apache.ambari.server.utils.ShellCommandUtil;
 import org.apache.ambari.server.utils.StageUtils;
 import org.apache.commons.cli.CommandLine;
@@ -163,7 +161,7 @@ public class Configuration {
    */
   @Inject
   private OsFamily osFamily;
-
+  
   /**
    * The filename of the {@link Properties} file which contains all of the
    * configurations for Ambari.
@@ -182,24 +180,6 @@ public class Configuration {
    */
   public static final float JDK_MIN_VERSION = 1.7f;
 
-  /**
-   * The default regex pattern to use when replacing the member attribute ID
-   * value with a placeholder, such as {@code ${member}}. This is used in cases
-   * where a UID of an LDAP member is not a full CN or unique ID.
-   */
-  private static final String LDAP_SYNC_MEMBER_REPLACE_PATTERN_DEFAULT = "";
-
-  /**
-   * The default LDAP filter to use when syncing user or group members. This
-   * default filter can include a {@code {member}} placeholder which allows
-   * substitution of a direct ID. For example:
-   *
-   * <pre>
-   * (&(objectclass=posixaccount)(dn={member})) -> (&(objectclass=posixaccount)(dn=cn=mycn,dc=apache,dc=org))
-   * </pre>
-   */
-  private static final String LDAP_SYNC_MEMBER_FILTER_DEFAULT = "";
-
   /**
    * The prefix for any configuration property which will be appended to
    * {@code eclipselink.jdbc.property.} before being passed into EclipseLink.
@@ -692,16 +672,6 @@ public class Configuration {
   public static final ConfigurationProperty<String> COMMON_SERVICES_DIR_PATH = new ConfigurationProperty<>(
       "common.services.path", null);
 
-  /**
-   * Determines whether an existing local users will be updated as LDAP users.
-   */
-  @Markdown(
-      description = "Determines how to handle username collision while updating from LDAP.",
-      examples = { "skip", "convert" }
-  )
-  public static final ConfigurationProperty<String> LDAP_SYNC_USERNAME_COLLISIONS_BEHAVIOR = new ConfigurationProperty<>(
-      "ldap.sync.username.collision.behavior", "convert");
-
   /**
    * The location on the Ambari Server where stack extensions exist.
    */
@@ -986,252 +956,6 @@ public class Configuration {
   public static final ConfigurationProperty<String> MYSQL_JAR_NAME = new ConfigurationProperty<>(
       "db.mysql.jdbc.name", "mysql-connector-java.jar");
 
-  /**
-   * For development purposes only, should be changed to 'false'
-   */
-  @Markdown(description = "An internal property used for unit testing and development purposes.")
-  public static final ConfigurationProperty<String> IS_LDAP_CONFIGURED = new ConfigurationProperty<>(
-      "ambari.ldap.isConfigured", "false");
-
-  /**
-   * Determines whether to use LDAP over SSL (LDAPS).
-   */
-  @Markdown(description = "Determines whether to use LDAP over SSL (LDAPS).")
-  public static final ConfigurationProperty<String> LDAP_USE_SSL = new ConfigurationProperty<>(
-      "authentication.ldap.useSSL", "false");
-
-  /**
-   * The default value is used for embedded purposes only.
-   */
-  @Markdown(description = "The LDAP URL used for connecting to an LDAP server when authenticating users. This should include both the host name and port.")
-  public static final ConfigurationProperty<String> LDAP_PRIMARY_URL = new ConfigurationProperty<>(
-      "authentication.ldap.primaryUrl", "localhost:33389");
-
-  /**
-   * A second LDAP URL to use as a backup when authenticating users.
-   */
-  @Markdown(description = "A second LDAP URL to use as a backup when authenticating users. This should include both the host name and port.")
-  public static final ConfigurationProperty<String> LDAP_SECONDARY_URL = new ConfigurationProperty<>(
-      "authentication.ldap.secondaryUrl", null);
-
-  /**
-   * The base DN to use when filtering LDAP users and groups.
-   */
-  @Markdown(description = "The base DN to use when filtering LDAP users and groups. This is only used when LDAP authentication is enabled.")
-  public static final ConfigurationProperty<String> LDAP_BASE_DN = new ConfigurationProperty<>(
-      "authentication.ldap.baseDn", "dc=ambari,dc=apache,dc=org");
-
-  /**
-   * Determines whether LDAP requests can connect anonymously or if a managed
-   * user is required to connect.
-   */
-  @Markdown(description = "Determines whether LDAP requests can connect anonymously or if a managed user is required to connect.")
-  public static final ConfigurationProperty<String> LDAP_BIND_ANONYMOUSLY = new ConfigurationProperty<>(
-      "authentication.ldap.bindAnonymously", "true");
-
-  /**
-   * The DN of the manager account to use when binding to LDAP if
-   * {@link #LDAP_BIND_ANONYMOUSLY} is turned off.
-   */
-  @Markdown(description = "The DN of the manager account to use when binding to LDAP if anonymous binding is disabled.")
-  public static final ConfigurationProperty<String> LDAP_MANAGER_DN = new ConfigurationProperty<>(
-      "authentication.ldap.managerDn", null);
-
-  /**
-   * The password for the account used to bind to LDAP if
-   * {@link #LDAP_BIND_ANONYMOUSLY} is turned off.
-   */
-  @Markdown(description = "The password for the manager account used to bind to LDAP if anonymous binding is disabled.")
-  public static final ConfigurationProperty<String> LDAP_MANAGER_PASSWORD = new ConfigurationProperty<>(
-      "authentication.ldap.managerPassword", null);
-
-  /**
-   * The attribute used for determining what the distinguished name property is.
-   */
-  @Markdown(description = "The attribute used for determining what the distinguished name property is.")
-  public static final ConfigurationProperty<String> LDAP_DN_ATTRIBUTE = new ConfigurationProperty<>(
-      "authentication.ldap.dnAttribute", "dn");
-
-  /**
-   * The attribute used for determining the user name.
-   */
-  @Markdown(description = "The attribute used for determining the user name, such as `uid`.")
-  public static final ConfigurationProperty<String> LDAP_USERNAME_ATTRIBUTE = new ConfigurationProperty<>(
-      "authentication.ldap.usernameAttribute", "uid");
-
-  /**
-   * Declares whether to force the ldap user name to be lowercase or leave as-is. This is useful when
-   * local user names are expected to be lowercase but the LDAP user names are not.
-   */
-  @Markdown(description = "Declares whether to force the ldap user name to be lowercase or leave as-is." +
-      " This is useful when local user names are expected to be lowercase but the LDAP user names are not.")
-  public static final ConfigurationProperty<String> LDAP_USERNAME_FORCE_LOWERCASE = new ConfigurationProperty<>(
-      "authentication.ldap.username.forceLowercase", "false");
-
-  /**
-   * The filter used when searching for users in LDAP.
-   */
-  @Markdown(description = "The filter used when searching for users in LDAP.")
-  public static final ConfigurationProperty<String> LDAP_USER_BASE = new ConfigurationProperty<>(
-      "authentication.ldap.userBase", "ou=people,dc=ambari,dc=apache,dc=org");
-
-  /**
-   * The class to which user objects in LDAP belong.
-   */
-  @Markdown(description = "The class to which user objects in LDAP belong.")
-  public static final ConfigurationProperty<String> LDAP_USER_OBJECT_CLASS = new ConfigurationProperty<>(
-      "authentication.ldap.userObjectClass", "person");
-
-  /**
-   * The filter used when searching for groups in LDAP.
-   */
-  @Markdown(description = "The filter used when searching for groups in LDAP.")
-  public static final ConfigurationProperty<String> LDAP_GROUP_BASE = new ConfigurationProperty<>(
-      "authentication.ldap.groupBase", "ou=groups,dc=ambari,dc=apache,dc=org");
-
-  /**
-   * The class to which group objects in LDAP belong.
-   */
-  @Markdown(description = "The class to which group objects in LDAP belong.")
-  public static final ConfigurationProperty<String> LDAP_GROUP_OBJECT_CLASS = new ConfigurationProperty<>(
-      "authentication.ldap.groupObjectClass", "group");
-
-  /**
-   * The attribute used to determine the group name.
-   */
-  @Markdown(description = "The attribute used to determine the group name in LDAP.")
-  public static final ConfigurationProperty<String> LDAP_GROUP_NAMING_ATTR = new ConfigurationProperty<>(
-      "authentication.ldap.groupNamingAttr", "cn");
-
-  /**
-   * The LDAP attribute which identifies group membership.
-   */
-  @Markdown(description = "The LDAP attribute which identifies group membership.")
-  public static final ConfigurationProperty<String> LDAP_GROUP_MEMBERSHIP_ATTR = new ConfigurationProperty<>(
-      "authentication.ldap.groupMembershipAttr", "member");
-
-  /**
-   * A comma-separate list of groups which would give a user administrative access to Ambari.
-   */
-  @Markdown(
-      description = "A comma-separate list of groups which would give a user administrative access to Ambari when syncing from LDAP. This is only used when `authorization.ldap.groupSearchFilter` is blank.",
-      examples = { "administrators", "Hadoop Admins,Hadoop Admins.*,DC Admins,.*Hadoop Operators" })
-  public static final ConfigurationProperty<String> LDAP_ADMIN_GROUP_MAPPING_RULES = new ConfigurationProperty<>(
-      "authorization.ldap.adminGroupMappingRules", "Ambari Administrators");
-
-  /**
-   * When authentication through LDAP is enabled then Ambari Server uses this
-   * filter to lookup the user in LDAP based on the provided ambari user name.
-   *
-   * If it is not set then
-   * {@code (&({usernameAttribute}={0})(objectClass={userObjectClass}))} is
-   * used.
-   */
-  @Markdown(
-      description = "A filter used to lookup a user in LDAP based on the Ambari user name",
-      examples = { "(&({usernameAttribute}={0})(objectClass={userObjectClass}))" })
-  public static final ConfigurationProperty<String> LDAP_USER_SEARCH_FILTER = new ConfigurationProperty<>(
-      "authentication.ldap.userSearchFilter",
-      "(&({usernameAttribute}={0})(objectClass={userObjectClass}))");
-
-  /**
-   * This configuration controls whether the use of alternate user search filter
-   * is enabled. If the default LDAP user search filter is not able to find the
-   * authenticating user in LDAP than Ambari can fall back an alternative user
-   * search filter if this functionality is enabled.
-   *
-   * If it is not set then the default
-   */
-  @Markdown(description = "Determines whether a secondary (alternate) LDAP user search filer is used if the primary filter fails to find a user.")
-  public static final ConfigurationProperty<String> LDAP_ALT_USER_SEARCH_ENABLED = new ConfigurationProperty<>(
-      "authentication.ldap.alternateUserSearchEnabled", "false");
-
-  /**
-   * When authentication through LDAP is enabled Ambari Server uses this filter
-   * by default to lookup the user in LDAP when the user provides beside user
-   * name additional information. There might be cases when
-   * {@link #LDAP_USER_SEARCH_FILTER} may match multiple users in LDAP. In such
-   * cases the user is prompted to provide additional info, e.g. the domain he
-   * or she wants ot log in upon login beside the username. This filter will be
-   * used by Ambari Server to lookup users in LDAP if the login name the user
-   * logs in contains additional information beside ambari user name.
-   * <p>
-   * Note: Currently the use of alternate user search filter is triggered only
-   * if the user login name is in the username@domain format (e.g.
-   * user1@x.y.com) which is the userPrincipalName format used in AD.
-   * </p>
-   */
-  @Markdown(description = "An alternate LDAP user search filter which can be used if `authentication.ldap.alternateUserSearchEnabled` is enabled and the primary filter fails to find a user.")
-  public static final ConfigurationProperty<String> LDAP_ALT_USER_SEARCH_FILTER = new ConfigurationProperty<>(
-      "authentication.ldap.alternateUserSearchFilter",
-      "(&(userPrincipalName={0})(objectClass={userObjectClass}))");
-
-  /**
-   * The DN to use when searching for LDAP groups.
-   */
-  @Markdown(description = "The DN to use when searching for LDAP groups.")
-  public static final ConfigurationProperty<String> LDAP_GROUP_SEARCH_FILTER = new ConfigurationProperty<>(
-      "authorization.ldap.groupSearchFilter", "");
-
-  /**
-   * Determines whether to follow LDAP referrals when the LDAP controller doesn't have the requested object.
-   */
-  @Markdown(description = "Determines whether to follow LDAP referrals to other URLs when the LDAP controller doesn't have the requested object.")
-  public static final ConfigurationProperty<String> LDAP_REFERRAL = new ConfigurationProperty<>(
-      "authentication.ldap.referral", "follow");
-
-  /**
-   * Determines whether results from LDAP are paginated when requested.
-   */
-  @Markdown(description = "Determines whether results from LDAP are paginated when requested.")
-  public static final ConfigurationProperty<String> LDAP_PAGINATION_ENABLED = new ConfigurationProperty<>(
-      "authentication.ldap.pagination.enabled", "true");
-
-  /**
-   * Regex pattern to use when replacing the user member attribute
-   * ID value with a placeholder. This is used in cases where a UID of an LDAP
-   * member is not a full CN or unique ID.
-   */
-  @Markdown(
-      description = "Regex pattern to use when replacing the user member attribute ID value with a placeholder. This is used in cases where a UID of an LDAP member is not a full CN or unique ID (e.g.: `member: <SID=123>;<GID=123>;cn=myCn,dc=org,dc=apache`)",
-      examples = { "(?<sid>.*);(?<guid>.*);(?<member>.*)" })
-  public static final ConfigurationProperty<String> LDAP_SYNC_USER_MEMBER_REPLACE_PATTERN = new ConfigurationProperty<>(
-      "authentication.ldap.sync.userMemberReplacePattern",
-      LDAP_SYNC_MEMBER_REPLACE_PATTERN_DEFAULT);
-
-  /**
-   * Regex pattern to use when replacing the group member attribute
-   * ID value with a placeholder. This is used in cases where a UID of an LDAP
-   * member is not a full CN or unique ID.
-   */
-  @Markdown(
-      description = "Regex pattern to use when replacing the group member attribute ID value with a placeholder. This is used in cases where a UID of an LDAP member is not a full CN or unique ID (e.g.: `member: <SID=123>;<GID=123>;cn=myCn,dc=org,dc=apache`)",
-      examples = { "(?<sid>.*);(?<guid>.*);(?<member>.*)" })
-  public static final ConfigurationProperty<String> LDAP_SYCN_GROUP_MEMBER_REPLACE_PATTERN = new ConfigurationProperty<>(
-      "authentication.ldap.sync.groupMemberReplacePattern",
-      LDAP_SYNC_MEMBER_REPLACE_PATTERN_DEFAULT);
-
-  /**
-   * Filter to use for syncing user members of group from LDAP. (by default it is not used)
-   */
-  @Markdown(
-    description = "Filter to use for syncing user members of a group from LDAP (by default it is not used).",
-    examples = {"(&(objectclass=posixaccount)(uid={member}))"})
-  public static final ConfigurationProperty<String> LDAP_SYNC_USER_MEMBER_FILTER = new ConfigurationProperty<>(
-      "authentication.ldap.sync.userMemberFilter",
-      LDAP_SYNC_MEMBER_FILTER_DEFAULT);
-
-  /**
-   * Filter to use for syncing group members of a group from LDAP. (by default it is not used)
-   */
-  @Markdown(
-    description = "Filter to use for syncing group members of a group from LDAP. (by default it is not used)",
-    examples = {"(&(objectclass=posixgroup)(cn={member}))"})
-  public static final ConfigurationProperty<String> LDAP_SYNC_GROUP_MEMBER_FILTER = new ConfigurationProperty<>(
-      "authentication.ldap.sync.groupMemberFilter",
-      LDAP_SYNC_MEMBER_FILTER_DEFAULT);
-
-
   /**
    * Enable the profiling of internal locks.
    */
@@ -2087,8 +1811,6 @@ public class Configuration {
   public static final ConfigurationProperty<String> LEGACY_OVERRIDE = new ConfigurationProperty<>(
     "repositories.legacy-override.enabled", "false");
 
-  private static final String LDAP_ADMIN_GROUP_MAPPING_MEMBER_ATTR_DEFAULT = "";
-
   /**
    * The time, in {@link TimeUnit#MILLISECONDS}, that agent connections can remain open and idle.
    */
@@ -2804,8 +2526,6 @@ public class Configuration {
   private JsonObject hostChangesJson;
   private Map<String, String> configsMap;
   private Map<String, String> agentConfigsMap;
-  private CredentialProvider credentialProvider = null;
-  private volatile boolean credentialProviderInitialized = false;
   private Properties customDbProperties = null;
   private Properties customPersistenceProperties = null;
   private Long configLastModifiedDateForCustomJDBC = 0L;
@@ -2829,16 +2549,6 @@ public class Configuration {
     }
   }
 
-  /**
-   * Ldap username collision handling behavior.
-   * CONVERT - convert existing local users to LDAP users.
-   * SKIP - skip existing local users.
-   */
-  public enum LdapUsernameCollisionHandlingBehavior {
-    CONVERT,
-    SKIP
-  }
-
   /**
    * The {@link DatabaseType} enum represents the database being used.
    */
@@ -3100,8 +2810,7 @@ public class Configuration {
       System.setProperty(JAVAX_SSL_TRUSTSTORE, getProperty(SSL_TRUSTSTORE_PATH));
     }
     if (getProperty(SSL_TRUSTSTORE_PASSWORD) != null) {
-      String ts_password = readPasswordFromStore(
-          getProperty(SSL_TRUSTSTORE_PASSWORD));
+      String ts_password = PasswordUtils.getInstance().readPasswordFromStore(getProperty(SSL_TRUSTSTORE_PASSWORD), getMasterKeyLocation(), isMasterKeyPersisted(), getMasterKeyStoreLocation());
       if (ts_password != null) {
         System.setProperty(JAVAX_SSL_TRUSTSTORE_PASSWORD, ts_password);
       } else {
@@ -3114,24 +2823,6 @@ public class Configuration {
     }
   }
 
-  private synchronized void loadCredentialProvider() {
-    if (!credentialProviderInitialized) {
-      try {
-        credentialProvider = new CredentialProvider(null,
-          getMasterKeyLocation(),
-          isMasterKeyPersisted(),
-          getMasterKeyStoreLocation());
-      } catch (Exception e) {
-        LOG.info("Credential provider creation failed. Reason: " + e.getMessage());
-        if (LOG.isDebugEnabled()) {
-          e.printStackTrace();
-        }
-        credentialProvider = null;
-      }
-      credentialProviderInitialized = true;
-    }
-  }
-
   /**
    * Find, read, and parse the configuration file.
    * @return the properties that were found or empty if no file was found
@@ -4034,7 +3725,7 @@ public class Configuration {
     String dbpasswd = null;
     boolean isPasswordAlias = false;
     if (CredentialProvider.isAliasString(passwdProp)) {
-      dbpasswd = readPasswordFromStore(passwdProp);
+      dbpasswd = PasswordUtils.getInstance().readPasswordFromStore(passwdProp, getMasterKeyLocation(), isMasterKeyPersisted(), getMasterKeyStoreLocation());
       isPasswordAlias =true;
     }
 
@@ -4044,7 +3735,7 @@ public class Configuration {
       LOG.error("Can't read db password from keystore. Please, check master key was set correctly.");
       throw new RuntimeException("Can't read db password from keystore. Please, check master key was set correctly.");
     } else {
-      return readPasswordFromFile(passwdProp, SERVER_JDBC_USER_PASSWD.getDefaultValue());
+      return PasswordUtils.getInstance().readPasswordFromFile(passwdProp, SERVER_JDBC_USER_PASSWD.getDefaultValue());
     }
   }
 
@@ -4062,117 +3753,7 @@ public class Configuration {
 
   public String getRcaDatabasePassword() {
     String passwdProp = properties.getProperty(SERVER_JDBC_RCA_USER_PASSWD.getKey());
-    if (passwdProp != null) {
-      String dbpasswd = readPasswordFromStore(passwdProp);
-      if (dbpasswd != null) {
-        return dbpasswd;
-      }
-    }
-    return readPasswordFromFile(passwdProp, SERVER_JDBC_RCA_USER_PASSWD.getDefaultValue());
-  }
-
-  private String readPasswordFromFile(String filePath, String defaultPassword) {
-    if (filePath == null) {
-      LOG.debug("DB password file not specified - using default");
-      return defaultPassword;
-    } else {
-      LOG.debug("Reading password from file {}", filePath);
-      String password;
-      try {
-        password = FileUtils.readFileToString(new File(filePath));
-        password = StringUtils.chomp(password);
-      } catch (IOException e) {
-        throw new RuntimeException("Unable to read database password", e);
-      }
-      return password;
-    }
-  }
-
-  String readPasswordFromStore(String aliasStr) {
-    String password = null;
-    loadCredentialProvider();
-    if (credentialProvider != null) {
-      char[] result = null;
-      try {
-        result = credentialProvider.getPasswordForAlias(aliasStr);
-      } catch (AmbariException e) {
-        LOG.error("Error reading from credential store.");
-        e.printStackTrace();
-      }
-      if (result != null) {
-        password = new String(result);
-      } else {
-        if (CredentialProvider.isAliasString(aliasStr)) {
-          LOG.error("Cannot read password for alias = " + aliasStr);
-        } else {
-          LOG.warn("Raw password provided, not an alias. It cannot be read from credential store.");
-        }
-      }
-    }
-    return password;
-  }
-
-  /**
-   * Gets parameters of LDAP server to connect to
-   * @return LdapServerProperties object representing connection parameters
-   */
-  public LdapServerProperties getLdapServerProperties() {
-    LdapServerProperties ldapServerProperties = new LdapServerProperties();
-
-    ldapServerProperties.setPrimaryUrl(getProperty(LDAP_PRIMARY_URL));
-    ldapServerProperties.setSecondaryUrl(getProperty(LDAP_SECONDARY_URL));
-    ldapServerProperties.setUseSsl(Boolean.parseBoolean(getProperty(LDAP_USE_SSL)));
-    ldapServerProperties.setAnonymousBind(Boolean.parseBoolean(getProperty(LDAP_BIND_ANONYMOUSLY)));
-    ldapServerProperties.setManagerDn(getProperty(LDAP_MANAGER_DN));
-    String ldapPasswordProperty = getProperty(LDAP_MANAGER_PASSWORD);
-    String ldapPassword = null;
-    if (CredentialProvider.isAliasString(ldapPasswordProperty)) {
-      ldapPassword = readPasswordFromStore(ldapPasswordProperty);
-    }
-    if (ldapPassword != null) {
-      ldapServerProperties.setManagerPassword(ldapPassword);
-    } else {
-      if (ldapPasswordProperty != null && new File(ldapPasswordProperty).exists()) {
-        ldapServerProperties.setManagerPassword(readPasswordFromFile(ldapPasswordProperty, ""));
-      }
-    }
-
-    ldapServerProperties.setBaseDN(getProperty(LDAP_BASE_DN));
-    ldapServerProperties.setUsernameAttribute(getProperty(LDAP_USERNAME_ATTRIBUTE));
-    ldapServerProperties.setForceUsernameToLowercase(Boolean.parseBoolean(getProperty(LDAP_USERNAME_FORCE_LOWERCASE)));
-    ldapServerProperties.setUserBase(getProperty(LDAP_USER_BASE));
-    ldapServerProperties.setUserObjectClass(getProperty(LDAP_USER_OBJECT_CLASS));
-    ldapServerProperties.setDnAttribute(getProperty(LDAP_DN_ATTRIBUTE));
-    ldapServerProperties.setGroupBase(getProperty(LDAP_GROUP_BASE));
-    ldapServerProperties.setGroupObjectClass(getProperty(LDAP_GROUP_OBJECT_CLASS));
-    ldapServerProperties.setGroupMembershipAttr(getProperty(LDAP_GROUP_MEMBERSHIP_ATTR));
-    ldapServerProperties.setGroupNamingAttr(getProperty(LDAP_GROUP_NAMING_ATTR));
-    ldapServerProperties.setAdminGroupMappingRules(getProperty(LDAP_ADMIN_GROUP_MAPPING_RULES));
-    ldapServerProperties.setAdminGroupMappingMemberAttr(getProperty(LDAP_ADMIN_GROUP_MAPPING_MEMBER_ATTR_DEFAULT));
-    ldapServerProperties.setUserSearchFilter(getProperty(LDAP_USER_SEARCH_FILTER));
-    ldapServerProperties.setAlternateUserSearchFilter(getProperty(LDAP_ALT_USER_SEARCH_FILTER));
-    ldapServerProperties.setGroupSearchFilter(getProperty(LDAP_GROUP_SEARCH_FILTER));
-    ldapServerProperties.setReferralMethod(getProperty(LDAP_REFERRAL));
-    ldapServerProperties.setSyncUserMemberReplacePattern(getProperty(LDAP_SYNC_USER_MEMBER_REPLACE_PATTERN));
-    ldapServerProperties.setSyncGroupMemberReplacePattern(getProperty(LDAP_SYCN_GROUP_MEMBER_REPLACE_PATTERN));
-    ldapServerProperties.setSyncUserMemberFilter(getProperty(LDAP_SYNC_USER_MEMBER_FILTER));
-    ldapServerProperties.setSyncGroupMemberFilter(getProperty(LDAP_SYNC_GROUP_MEMBER_FILTER));
-    ldapServerProperties.setPaginationEnabled(
-        Boolean.parseBoolean(getProperty(LDAP_PAGINATION_ENABLED)));
-
-    if (properties.containsKey(LDAP_GROUP_BASE) || properties.containsKey(LDAP_GROUP_OBJECT_CLASS)
-        || properties.containsKey(LDAP_GROUP_MEMBERSHIP_ATTR)
-        || properties.containsKey(LDAP_GROUP_NAMING_ATTR)
-        || properties.containsKey(LDAP_ADMIN_GROUP_MAPPING_RULES)
-        || properties.containsKey(LDAP_GROUP_SEARCH_FILTER)) {
-      ldapServerProperties.setGroupMappingEnabled(true);
-    }
-
-    return ldapServerProperties;
-  }
-
-  public boolean isLdapConfigured() {
-    return Boolean.parseBoolean(getProperty(IS_LDAP_CONFIGURED));
+    return PasswordUtils.getInstance().readPassword(passwdProp, SERVER_JDBC_RCA_USER_PASSWD.getDefaultValue());
   }
 
   public String getServerOsType() {
@@ -5056,17 +4637,6 @@ public class Configuration {
     return Boolean.parseBoolean(getProperty(KERBEROS_CHECK_JAAS_CONFIGURATION));
   }
 
-  /**
-   * Determines whether an existing local users will be skipped on updated during LDAP sync.
-   *
-   * @return true if ambari need to skip existing user during LDAP sync.
-   */
-  public LdapUsernameCollisionHandlingBehavior getLdapSyncCollisionHandlingBehavior() {
-    if (getProperty(LDAP_SYNC_USERNAME_COLLISIONS_BEHAVIOR).toLowerCase().equals("skip")) {
-      return LdapUsernameCollisionHandlingBehavior.SKIP;
-    }
-    return LdapUsernameCollisionHandlingBehavior.CONVERT;
-  }
 
   /**
    * Gets the type of database by examining the {@link #getDatabaseUrl()} JDBC
@@ -5510,10 +5080,6 @@ public class Configuration {
     return StringUtils.isEmpty(udpPort) ? null : Integer.parseInt(udpPort);
   }
 
-  public boolean isLdapAlternateUserSearchEnabled() {
-    return Boolean.parseBoolean(getProperty(LDAP_ALT_USER_SEARCH_ENABLED));
-  }
-
   /**
    * Gets the hosts/ports that proxy calls are allowed to be made to.
    *

+ 29 - 0
ambari-server/src/main/java/org/apache/ambari/server/configuration/LdapUsernameCollisionHandlingBehavior.java

@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.configuration;
+
+/**
+ * Ldap username collision handling behavior.
+ * CONVERT - convert existing local users to LDAP users.
+ * SKIP - skip existing local users.
+ */
+public enum LdapUsernameCollisionHandlingBehavior {
+  CONVERT,
+  SKIP
+}
+

+ 2 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java

@@ -154,6 +154,7 @@ import org.apache.ambari.server.topology.PersistedState;
 import org.apache.ambari.server.topology.PersistedStateImpl;
 import org.apache.ambari.server.topology.SecurityConfigurationFactory;
 import org.apache.ambari.server.topology.tasks.ConfigureClusterTaskFactory;
+import org.apache.ambari.server.utils.PasswordUtils;
 import org.apache.ambari.server.view.ViewInstanceHandlerList;
 import org.eclipse.jetty.server.SessionIdManager;
 import org.eclipse.jetty.server.SessionManager;
@@ -401,6 +402,7 @@ public class ControllerModule extends AbstractModule {
     requestStaticInjection(DatabaseConsistencyCheckHelper.class);
     requestStaticInjection(KerberosChecker.class);
     requestStaticInjection(AuthorizationHelper.class);
+    requestStaticInjection(PasswordUtils.class);
 
     bindByAnnotation(null);
     bindNotificationDispatchers(null);

+ 6 - 1
ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java

@@ -145,7 +145,12 @@ public abstract class AmbariEvent {
     /**
      * Ambari configuration changed event;
      */
-    AMBARI_CONFIGURATION_CHANGED;
+    AMBARI_CONFIGURATION_CHANGED,
+    
+    /**
+     * JPA initialized
+     */
+    JPA_INITIALIZED;
 
   }
 

+ 34 - 0
ambari-server/src/main/java/org/apache/ambari/server/events/JpaInitializedEvent.java

@@ -0,0 +1,34 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.events;
+
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+
+import com.google.inject.persist.PersistService;
+
+/**
+ * Event signaling that JPA has been initialized through Guice (so that anyone
+ * needs JPA context can work).
+ * 
+ * This events needs to be triggered by {@link GuiceJpaInitializer} to indicate
+ * that JPA is initialized so that any client requires {@link PersistService} to
+ * be started can start its work
+ */
+public class JpaInitializedEvent extends AmbariEvent {
+
+  public JpaInitializedEvent() {
+    super(AmbariEventType.JPA_INITIALIZED);
+  }
+}

+ 131 - 43
ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfiguration.java

@@ -12,20 +12,26 @@
  * limitations under the License.
  */
 
-
 package org.apache.ambari.server.ldap.domain;
 
+import static java.lang.Boolean.parseBoolean;
+
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.ambari.server.configuration.LdapUsernameCollisionHandlingBehavior;
+import org.apache.ambari.server.security.authorization.LdapServerProperties;
+import org.apache.ambari.server.utils.PasswordUtils;
 import org.apache.commons.lang.builder.EqualsBuilder;
 import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.codehaus.plexus.util.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * This class is an immutable representation of all the LDAP related configurationMap entries.
+ * This class is an immutable representation of all the LDAP related
+ * configurationMap entries.
  */
 public class AmbariLdapConfiguration {
 
@@ -33,12 +39,13 @@ public class AmbariLdapConfiguration {
 
   private final Map<String, String> configurationMap;
 
-  private Object configValue(AmbariLdapConfigurationKeys ambariLdapConfigurationKeys) {
-    Object value = null;
+  private String configValue(AmbariLdapConfigurationKeys ambariLdapConfigurationKeys) {
+    final String value;
     if (configurationMap.containsKey(ambariLdapConfigurationKeys.key())) {
       value = configurationMap.get(ambariLdapConfigurationKeys.key());
     } else {
-      LOGGER.warn("Ldap configuration property [{}] hasn't been set", ambariLdapConfigurationKeys.key());
+      LOGGER.warn("Ldap configuration property [{}] hasn't been set; using default value", ambariLdapConfigurationKeys.key());
+      value = ambariLdapConfigurationKeys.getDefaultValue();
     }
     return value;
   }
@@ -46,131 +53,154 @@ public class AmbariLdapConfiguration {
   public void setValueFor(AmbariLdapConfigurationKeys ambariLdapConfigurationKeys, String value) {
     configurationMap.put(ambariLdapConfigurationKeys.key(), value);
   }
+  
+  public AmbariLdapConfiguration() {
+    this(new HashMap<>());
+  }
 
   public AmbariLdapConfiguration(Map<String, String> configuration) {
     this.configurationMap = configuration;
   }
 
   public boolean ldapEnabled() {
-    return Boolean.valueOf((String) configValue(AmbariLdapConfigurationKeys.LDAP_ENABLED));
+    return Boolean.valueOf(configValue(AmbariLdapConfigurationKeys.LDAP_ENABLED));
   }
 
   public String serverHost() {
-    return (String) configValue(AmbariLdapConfigurationKeys.SERVER_HOST);
+    return configValue(AmbariLdapConfigurationKeys.SERVER_HOST);
   }
 
   public int serverPort() {
-    return Integer.valueOf((String) configValue(AmbariLdapConfigurationKeys.SERVER_PORT));
+    return Integer.valueOf(configValue(AmbariLdapConfigurationKeys.SERVER_PORT));
+  }
+
+  public String serverUrl() {
+    return serverHost() + ":" + serverPort();
+  }
+
+  public String secondaryServerHost() {
+    return configValue(AmbariLdapConfigurationKeys.SECONDARY_SERVER_HOST);
+  }
+
+  public int secondaryServerPort() {
+    final String secondaryServerPort = configValue(AmbariLdapConfigurationKeys.SECONDARY_SERVER_PORT);
+    return secondaryServerPort == null ? 0 : Integer.valueOf(secondaryServerPort);
+  }
+
+  public String secondaryServerUrl() {
+    return secondaryServerHost() + ":" + secondaryServerPort();
   }
 
   public boolean useSSL() {
-    return Boolean.valueOf((String) configValue(AmbariLdapConfigurationKeys.USE_SSL));
+    return Boolean.valueOf(configValue(AmbariLdapConfigurationKeys.USE_SSL));
   }
 
   public String trustStore() {
-    return (String) configValue(AmbariLdapConfigurationKeys.TRUST_STORE);
+    return configValue(AmbariLdapConfigurationKeys.TRUST_STORE);
   }
 
   public String trustStoreType() {
-    return (String) configValue(AmbariLdapConfigurationKeys.TRUST_STORE_TYPE);
+    return configValue(AmbariLdapConfigurationKeys.TRUST_STORE_TYPE);
   }
 
   public String trustStorePath() {
-    return (String) configValue(AmbariLdapConfigurationKeys.TRUST_STORE_PATH);
+    return configValue(AmbariLdapConfigurationKeys.TRUST_STORE_PATH);
   }
 
   public String trustStorePassword() {
-    return (String) configValue(AmbariLdapConfigurationKeys.TRUST_STORE_PASSWORD);
+    return configValue(AmbariLdapConfigurationKeys.TRUST_STORE_PASSWORD);
   }
 
   public boolean anonymousBind() {
-    return Boolean.valueOf((String) configValue(AmbariLdapConfigurationKeys.ANONYMOUS_BIND));
+    return Boolean.valueOf(configValue(AmbariLdapConfigurationKeys.ANONYMOUS_BIND));
   }
 
   public String bindDn() {
-    return (String) configValue(AmbariLdapConfigurationKeys.BIND_DN);
+    return configValue(AmbariLdapConfigurationKeys.BIND_DN);
   }
 
   public String bindPassword() {
-    return (String) configValue(AmbariLdapConfigurationKeys.BIND_PASSWORD);
+    return configValue(AmbariLdapConfigurationKeys.BIND_PASSWORD);
   }
 
   public String attributeDetection() {
-    return (String) configValue(AmbariLdapConfigurationKeys.ATTR_DETECTION);
+    return configValue(AmbariLdapConfigurationKeys.ATTR_DETECTION);
   }
 
   public String dnAttribute() {
-    return (String) configValue(AmbariLdapConfigurationKeys.DN_ATTRIBUTE);
+    return configValue(AmbariLdapConfigurationKeys.DN_ATTRIBUTE);
   }
 
   public String userObjectClass() {
-    return (String) configValue(AmbariLdapConfigurationKeys.USER_OBJECT_CLASS);
+    return configValue(AmbariLdapConfigurationKeys.USER_OBJECT_CLASS);
   }
 
   public String userNameAttribute() {
-    return (String) configValue(AmbariLdapConfigurationKeys.USER_NAME_ATTRIBUTE);
+    return configValue(AmbariLdapConfigurationKeys.USER_NAME_ATTRIBUTE);
   }
 
   public String userSearchBase() {
-    return (String) configValue(AmbariLdapConfigurationKeys.USER_SEARCH_BASE);
+    return configValue(AmbariLdapConfigurationKeys.USER_SEARCH_BASE);
   }
 
   public String groupObjectClass() {
-    return (String) configValue(AmbariLdapConfigurationKeys.GROUP_OBJECT_CLASS);
+    return configValue(AmbariLdapConfigurationKeys.GROUP_OBJECT_CLASS);
   }
 
   public String groupNameAttribute() {
-    return (String) configValue(AmbariLdapConfigurationKeys.GROUP_NAME_ATTRIBUTE);
+    return configValue(AmbariLdapConfigurationKeys.GROUP_NAME_ATTRIBUTE);
   }
 
   public String groupMemberAttribute() {
-    return (String) configValue(AmbariLdapConfigurationKeys.GROUP_MEMBER_ATTRIBUTE);
+    return configValue(AmbariLdapConfigurationKeys.GROUP_MEMBER_ATTRIBUTE);
   }
 
   public String groupSearchBase() {
-    return (String) configValue(AmbariLdapConfigurationKeys.GROUP_SEARCH_BASE);
+    return configValue(AmbariLdapConfigurationKeys.GROUP_SEARCH_BASE);
+  }
+
+  public String groupMappingRules() {
+    return configValue(AmbariLdapConfigurationKeys.GROUP_MAPPING_RULES);
   }
 
   public String userSearchFilter() {
-    return (String) configValue(AmbariLdapConfigurationKeys.USER_SEARCH_FILTER);
+    return configValue(AmbariLdapConfigurationKeys.USER_SEARCH_FILTER);
   }
 
   public String userMemberReplacePattern() {
-    return (String) configValue(AmbariLdapConfigurationKeys.USER_MEMBER_REPLACE_PATTERN);
+    return configValue(AmbariLdapConfigurationKeys.USER_MEMBER_REPLACE_PATTERN);
   }
 
   public String userMemberFilter() {
-    return (String) configValue(AmbariLdapConfigurationKeys.USER_MEMBER_FILTER);
+    return configValue(AmbariLdapConfigurationKeys.USER_MEMBER_FILTER);
   }
 
   public String groupSearchFilter() {
-    return (String) configValue(AmbariLdapConfigurationKeys.GROUP_SEARCH_FILTER);
+    return configValue(AmbariLdapConfigurationKeys.GROUP_SEARCH_FILTER);
   }
 
   public String groupMemberReplacePattern() {
-    return (String) configValue(AmbariLdapConfigurationKeys.GROUP_MEMBER_REPLACE_PATTERN);
+    return configValue(AmbariLdapConfigurationKeys.GROUP_MEMBER_REPLACE_PATTERN);
   }
 
   public String groupMemberFilter() {
-    return (String) configValue(AmbariLdapConfigurationKeys.GROUP_MEMBER_FILTER);
+    return configValue(AmbariLdapConfigurationKeys.GROUP_MEMBER_FILTER);
   }
 
   public boolean forceLowerCaseUserNames() {
-    return Boolean.valueOf((String) configValue(AmbariLdapConfigurationKeys.FORCE_LOWERCASE_USERNAMES));
+    return Boolean.valueOf(configValue(AmbariLdapConfigurationKeys.FORCE_LOWERCASE_USERNAMES));
   }
 
   public boolean paginationEnabled() {
-    return Boolean.valueOf((String) configValue(AmbariLdapConfigurationKeys.PAGINATION_ENABLED));
+    return Boolean.valueOf(configValue(AmbariLdapConfigurationKeys.PAGINATION_ENABLED));
   }
 
   public String referralHandling() {
-    return (String) configValue(AmbariLdapConfigurationKeys.REFERRAL_HANDLING);
+    return configValue(AmbariLdapConfigurationKeys.REFERRAL_HANDLING);
   }
 
   public Map<String, String> toMap() {
-    return (configurationMap == null)
-        ? Collections.emptyMap()
-        : new HashMap<>(configurationMap);
+    return (configurationMap == null) ? Collections.emptyMap() : new HashMap<>(configurationMap);
   }
 
   @Override
@@ -190,15 +220,73 @@ public class AmbariLdapConfiguration {
 
     AmbariLdapConfiguration that = (AmbariLdapConfiguration) o;
 
-    return new EqualsBuilder()
-        .append(configurationMap, that.configurationMap)
-        .isEquals();
+    return new EqualsBuilder().append(configurationMap, that.configurationMap).isEquals();
   }
 
   @Override
   public int hashCode() {
-    return new HashCodeBuilder(17, 37)
-        .append(configurationMap)
-        .toHashCode();
+    return new HashCodeBuilder(17, 37).append(configurationMap).toHashCode();
+  }
+
+  public boolean isLdapAlternateUserSearchEnabled() {
+    return Boolean.valueOf(configValue(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_ENABLED));
+  }
+
+  public LdapServerProperties getLdapServerProperties() {
+    final LdapServerProperties ldapServerProperties = new LdapServerProperties();
+
+    ldapServerProperties.setPrimaryUrl(serverUrl());
+    if (StringUtils.isNotBlank(secondaryServerHost())) {
+      ldapServerProperties.setSecondaryUrl(secondaryServerUrl());
+    }
+    ldapServerProperties.setUseSsl(parseBoolean(configValue(AmbariLdapConfigurationKeys.USE_SSL)));
+    ldapServerProperties.setAnonymousBind(parseBoolean(configValue(AmbariLdapConfigurationKeys.ANONYMOUS_BIND)));
+    ldapServerProperties.setManagerDn(configValue(AmbariLdapConfigurationKeys.BIND_DN));
+    ldapServerProperties.setManagerPassword(PasswordUtils.getInstance().readPassword(configValue(AmbariLdapConfigurationKeys.BIND_PASSWORD), AmbariLdapConfigurationKeys.BIND_PASSWORD.getDefaultValue()));
+    ldapServerProperties.setBaseDN(configValue(AmbariLdapConfigurationKeys.USER_SEARCH_BASE));
+    ldapServerProperties.setUsernameAttribute(configValue(AmbariLdapConfigurationKeys.USER_NAME_ATTRIBUTE));
+    ldapServerProperties.setForceUsernameToLowercase(parseBoolean(configValue(AmbariLdapConfigurationKeys.FORCE_LOWERCASE_USERNAMES)));
+    ldapServerProperties.setUserBase(configValue(AmbariLdapConfigurationKeys.USER_BASE));
+    ldapServerProperties.setUserObjectClass(configValue(AmbariLdapConfigurationKeys.USER_OBJECT_CLASS));
+    ldapServerProperties.setDnAttribute(configValue(AmbariLdapConfigurationKeys.DN_ATTRIBUTE));
+    ldapServerProperties.setGroupBase(configValue(AmbariLdapConfigurationKeys.GROUP_BASE));
+    ldapServerProperties.setGroupObjectClass(configValue(AmbariLdapConfigurationKeys.GROUP_OBJECT_CLASS));
+    ldapServerProperties.setGroupMembershipAttr(configValue(AmbariLdapConfigurationKeys.GROUP_MEMBER_ATTRIBUTE));
+    ldapServerProperties.setGroupNamingAttr(configValue(AmbariLdapConfigurationKeys.GROUP_NAME_ATTRIBUTE));
+    ldapServerProperties.setAdminGroupMappingRules(configValue(AmbariLdapConfigurationKeys.GROUP_MAPPING_RULES));
+    ldapServerProperties.setAdminGroupMappingMemberAttr("");
+    ldapServerProperties.setUserSearchFilter(configValue(AmbariLdapConfigurationKeys.USER_SEARCH_FILTER));
+    ldapServerProperties.setAlternateUserSearchFilter(configValue(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_FILTER));
+    ldapServerProperties.setGroupSearchFilter(configValue(AmbariLdapConfigurationKeys.GROUP_SEARCH_FILTER));
+    ldapServerProperties.setReferralMethod(configValue(AmbariLdapConfigurationKeys.REFERRAL_HANDLING));
+    ldapServerProperties.setSyncUserMemberReplacePattern(configValue(AmbariLdapConfigurationKeys.USER_MEMBER_REPLACE_PATTERN));
+    ldapServerProperties.setSyncGroupMemberReplacePattern(configValue(AmbariLdapConfigurationKeys.GROUP_MEMBER_REPLACE_PATTERN));
+    ldapServerProperties.setSyncUserMemberFilter(configValue(AmbariLdapConfigurationKeys.USER_MEMBER_FILTER));
+    ldapServerProperties.setSyncGroupMemberFilter(configValue(AmbariLdapConfigurationKeys.GROUP_MEMBER_FILTER));
+    ldapServerProperties.setPaginationEnabled(parseBoolean(configValue(AmbariLdapConfigurationKeys.PAGINATION_ENABLED)));
+
+    if (hasAnyValueWithKey(AmbariLdapConfigurationKeys.GROUP_BASE, AmbariLdapConfigurationKeys.GROUP_OBJECT_CLASS, AmbariLdapConfigurationKeys.GROUP_MEMBER_ATTRIBUTE,
+        AmbariLdapConfigurationKeys.GROUP_NAME_ATTRIBUTE, AmbariLdapConfigurationKeys.GROUP_MAPPING_RULES, AmbariLdapConfigurationKeys.GROUP_SEARCH_FILTER)) {
+      ldapServerProperties.setGroupMappingEnabled(true);
+    }
+
+    return ldapServerProperties;
   }
+
+  private boolean hasAnyValueWithKey(AmbariLdapConfigurationKeys... ambariLdapConfigurationKeys) {
+    for (AmbariLdapConfigurationKeys key : ambariLdapConfigurationKeys) {
+      if (configurationMap.containsKey(key.key())) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public LdapUsernameCollisionHandlingBehavior syncCollisionHandlingBehavior() {
+    if ("skip".equalsIgnoreCase(configValue(AmbariLdapConfigurationKeys.COLLISION_BEHAVIOR))) {
+      return LdapUsernameCollisionHandlingBehavior.SKIP;
+    }
+    return LdapUsernameCollisionHandlingBehavior.CONVERT;
+  }
+
 }

+ 65 - 45
ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationKeys.java

@@ -21,56 +21,68 @@ import org.apache.ambari.server.configuration.ConfigurationPropertyType;
 
 /**
  * Constants representing supported LDAP related property names
- * // TODO: extend this with validation information, description, defaults maybe
  */
 public enum AmbariLdapConfigurationKeys {
 
-  LDAP_ENABLED("ambari.ldap.authentication.enabled", PLAINTEXT),
-  SERVER_HOST("ambari.ldap.connectivity.server.host", PLAINTEXT),
-  SERVER_PORT("ambari.ldap.connectivity.server.port", PLAINTEXT),
-  USE_SSL("ambari.ldap.connectivity.use_ssl", PLAINTEXT),
-
-  TRUST_STORE("ambari.ldap.connectivity.trust_store", PLAINTEXT),
-  TRUST_STORE_TYPE("ambari.ldap.connectivity.trust_store.type", PLAINTEXT),
-  TRUST_STORE_PATH("ambari.ldap.connectivity.trust_store.path", PLAINTEXT),
-  TRUST_STORE_PASSWORD("ambari.ldap.connectivity.trust_store.password", PASSWORD),
-  ANONYMOUS_BIND("ambari.ldap.connectivity.anonymous_bind", PLAINTEXT),
-
-  BIND_DN("ambari.ldap.connectivity.bind_dn", PLAINTEXT),
-  BIND_PASSWORD("ambari.ldap.connectivity.bind_password", PASSWORD),
-
-  ATTR_DETECTION("ambari.ldap.attributes.detection", PLAINTEXT), // manual | auto
-
-  DN_ATTRIBUTE("ambari.ldap.attributes.dn_attr", PLAINTEXT),
-
-  USER_OBJECT_CLASS("ambari.ldap.attributes.user.object_class", PLAINTEXT),
-  USER_NAME_ATTRIBUTE("ambari.ldap.attributes.user.name_attr", PLAINTEXT),
-  USER_GROUP_MEMBER_ATTRIBUTE("ambari.ldap.attributes.user.group_member_attr", PLAINTEXT),
-  USER_SEARCH_BASE("ambari.ldap.attributes.user.search_base", PLAINTEXT),
-
-  GROUP_OBJECT_CLASS("ambari.ldap.attributes.group.object_class", PLAINTEXT),
-  GROUP_NAME_ATTRIBUTE("ambari.ldap.attributes.group.name_attr", PLAINTEXT),
-  GROUP_MEMBER_ATTRIBUTE("ambari.ldap.attributes.group.member_attr", PLAINTEXT),
-  GROUP_SEARCH_BASE("ambari.ldap.attributes.group.search_base", PLAINTEXT),
-
-  USER_SEARCH_FILTER("ambari.ldap.advanced.user_search_filter", PLAINTEXT),
-  USER_MEMBER_REPLACE_PATTERN("ambari.ldap.advanced.user_member_replace_pattern", PLAINTEXT),
-  USER_MEMBER_FILTER("ambari.ldap.advanced.user_member_filter", PLAINTEXT),
-
-  GROUP_SEARCH_FILTER("ambari.ldap.advanced.group_search_filter", PLAINTEXT),
-  GROUP_MEMBER_REPLACE_PATTERN("ambari.ldap.advanced.group_member_replace_pattern", PLAINTEXT),
-  GROUP_MEMBER_FILTER("ambari.ldap.advanced.group_member_filter", PLAINTEXT),
-
-  FORCE_LOWERCASE_USERNAMES("ambari.ldap.advanced.force_lowercase_usernames", PLAINTEXT),
-  REFERRAL_HANDLING("ambari.ldap.advanced.referrals", PLAINTEXT), // folow
-  PAGINATION_ENABLED("ambari.ldap.advanced.pagination_enabled", PLAINTEXT); // true | false
-
-  private String propertyName;
-  private ConfigurationPropertyType configurationPropertyType;
-
-  AmbariLdapConfigurationKeys(String propName, ConfigurationPropertyType configurationPropertyType) {
+  LDAP_ENABLED("ambari.ldap.authentication.enabled", PLAINTEXT, "false", "An internal property used for unit testing and development purposes."),
+  SERVER_HOST("ambari.ldap.connectivity.server.host", PLAINTEXT, "localhost", "The LDAP URL host used for connecting to an LDAP server when authenticating users."),
+  SERVER_PORT("ambari.ldap.connectivity.server.port", PLAINTEXT, "33389", "The LDAP URL port used for connecting to an LDAP server when authenticating users."),
+  SECONDARY_SERVER_HOST("ambari.ldap.connectivity.secondary.server.host", PLAINTEXT, null, "A second LDAP URL host to use as a backup when authenticating users."),
+  SECONDARY_SERVER_PORT("ambari.ldap.connectivity.secondary.server.port", PLAINTEXT, null, "A second LDAP URL port to use as a backup when authenticating users."),
+  USE_SSL("ambari.ldap.connectivity.use_ssl", PLAINTEXT, "false", "Determines whether to use LDAP over SSL (LDAPS)."),
+
+  TRUST_STORE("ambari.ldap.connectivity.trust_store", PLAINTEXT, "", ""), //TODO
+  TRUST_STORE_TYPE("ambari.ldap.connectivity.trust_store.type", PLAINTEXT, null, "The type of truststore used by the 'javax.net.ssl.trustStoreType' property."),
+  TRUST_STORE_PATH("ambari.ldap.connectivity.trust_store.path", PLAINTEXT, null, "The location of the truststore to use when setting the 'javax.net.ssl.trustStore' property."),
+  TRUST_STORE_PASSWORD("ambari.ldap.connectivity.trust_store.password", PASSWORD, null, "The password to use when setting the 'javax.net.ssl.trustStorePassword' property"),
+  ANONYMOUS_BIND("ambari.ldap.connectivity.anonymous_bind", PLAINTEXT, "true", "Determines whether LDAP requests can connect anonymously or if a managed user is required to connect."),
+
+  BIND_DN("ambari.ldap.connectivity.bind_dn", PLAINTEXT, null, "The DN of the manager account to use when binding to LDAP if anonymous binding is disabled."),
+  BIND_PASSWORD("ambari.ldap.connectivity.bind_password", PASSWORD, null, "The password for the manager account used to bind to LDAP if anonymous binding is disabled."),
+
+  ATTR_DETECTION("ambari.ldap.attributes.detection", PLAINTEXT, "", ""), //TODO
+
+  DN_ATTRIBUTE("ambari.ldap.attributes.dn_attr", PLAINTEXT, "dn", "The attribute used for determining what the distinguished name property is."),
+
+  USER_OBJECT_CLASS("ambari.ldap.attributes.user.object_class", PLAINTEXT, "person", "The class to which user objects in LDAP belong."),
+  USER_NAME_ATTRIBUTE("ambari.ldap.attributes.user.name_attr", PLAINTEXT, "uid", "The attribute used for determining the user name, such as 'uid'."),
+  USER_GROUP_MEMBER_ATTRIBUTE("ambari.ldap.attributes.user.group_member_attr", PLAINTEXT, "", ""), //TODO
+  USER_SEARCH_BASE("ambari.ldap.attributes.user.search_base", PLAINTEXT, "dc=ambari,dc=apache,dc=org", "The base DN to use when filtering LDAP users and groups. This is only used when LDAP authentication is enabled."),
+  USER_BASE("ambari.ldap.attributes.search_user.base", PLAINTEXT, "ou=people,dc=ambari,dc=apache,dc=org", "The filter used when searching for users in LDAP."),
+
+  GROUP_OBJECT_CLASS("ambari.ldap.attributes.group.object_class", PLAINTEXT, "ou=groups,dc=ambari,dc=apache,dc=org", "The filter used when searching for groups in LDAP."),
+  GROUP_NAME_ATTRIBUTE("ambari.ldap.attributes.group.name_attr", PLAINTEXT, "cn", "The attribute used to determine the group name in LDAP."),
+  GROUP_MEMBER_ATTRIBUTE("ambari.ldap.attributes.group.member_attr", PLAINTEXT, "member", "The LDAP attribute which identifies group membership."),
+  GROUP_SEARCH_BASE("ambari.ldap.attributes.group.search_base", PLAINTEXT, "dc=ambari,dc=apache,dc=org", "The base DN to use when filtering LDAP users and groups. This is only used when LDAP authentication is enabled."),
+  GROUP_BASE("ambari.ldap.attributes.group.search_group_base", PLAINTEXT, "ou=groups,dc=ambari,dc=apache,dc=org", "The filter used when searching for groups in LDAP."),
+
+  USER_SEARCH_FILTER("ambari.ldap.advanced.user_search_filter", PLAINTEXT, "(&({usernameAttribute}={0})(objectClass={userObjectClass}))", "A filter used to lookup a user in LDAP based on the Ambari user name."),
+  USER_MEMBER_REPLACE_PATTERN("ambari.ldap.advanced.user_member_replace_pattern", PLAINTEXT, "", "Regex pattern to use when replacing the user member attribute ID value with a placeholder. This is used in cases where a UID of an LDAP member is not a full CN or unique ID (e.g.: 'member: <SID=123>;<GID=123>;cn=myCn,dc=org,dc=apache')"),
+  USER_MEMBER_FILTER("ambari.ldap.advanced.user_member_filter", PLAINTEXT, "", "Filter to use for syncing user members of a group from LDAP (by default it is not used). For example: (&(objectclass=posixaccount)(uid={member}))"),
+ 
+  ALTERNATE_USER_SEARCH_ENABLED("ambari.ldap.advanced.alternate_user_search_enabled", PLAINTEXT, "false", "Determines whether a secondary (alternate) LDAP user search filer is used if the primary filter fails to find a user."),
+  ALTERNATE_USER_SEARCH_FILTER("ambari.ldap.advanced.alternate_user_search_filter", PLAINTEXT, "(&(userPrincipalName={0})(objectClass={userObjectClass}))", "An alternate LDAP user search filter which can be used if 'authentication.ldap.alternateUserSearchEnabled' is enabled and the primary filter fails to find a user."),
+
+  GROUP_SEARCH_FILTER("ambari.ldap.advanced.group_search_filter", PLAINTEXT, "", "The DN to use when searching for LDAP groups."),
+  GROUP_MEMBER_REPLACE_PATTERN("ambari.ldap.advanced.group_member_replace_pattern", PLAINTEXT, "", "Regex pattern to use when replacing the group member attribute ID value with a placeholder. This is used in cases where a UID of an LDAP member is not a full CN or unique ID (e.g.: 'member: <SID=123>;<GID=123>;cn=myCn,dc=org,dc=apache')"),
+  GROUP_MEMBER_FILTER("ambari.ldap.advanced.group_member_filter", PLAINTEXT, "", "Filter to use for syncing group members of a group from LDAP. (by default it is not used). For example: (&(objectclass=posixgroup)(cn={member}))"),
+  GROUP_MAPPING_RULES("ambari.ldap.advanced.group_mapping_rules", PLAINTEXT, "Ambari Administrators", "A comma-separate list of groups which would give a user administrative access to Ambari when syncing from LDAP. This is only used when 'authorization.ldap.groupSearchFilter' is blank. For instance: Hadoop Admins, Hadoop Admins.*, DC Admins, .*Hadoop Operators"),
+
+  FORCE_LOWERCASE_USERNAMES("ambari.ldap.advanced.force_lowercase_usernames", PLAINTEXT, "", "Declares whether to force the ldap user name to be lowercase or leave as-is.\nThis is useful when local user names are expected to be lowercase but the LDAP user names are not."),
+  REFERRAL_HANDLING("ambari.ldap.advanced.referrals", PLAINTEXT, "follow", "Determines whether to follow LDAP referrals to other URLs when the LDAP controller doesn't have the requested object."),
+  PAGINATION_ENABLED("ambari.ldap.advanced.pagination_enabled", PLAINTEXT, "true", "Determines whether results from LDAP are paginated when requested."),
+  COLLISION_BEHAVIOR("ambari.ldap.advance.collision_behavior", PLAINTEXT, "convert", "Determines how to handle username collision while updating from LDAP.");
+
+  private final String propertyName;
+  private final ConfigurationPropertyType configurationPropertyType;
+  private final String defaultValue;
+  private final String description;
+
+  AmbariLdapConfigurationKeys(String propName, ConfigurationPropertyType configurationPropertyType, String defaultValue, String description) {
     this.propertyName = propName;
     this.configurationPropertyType = configurationPropertyType;
+    this.defaultValue = defaultValue;
+    this.description = description;
   }
 
   public String key() {
@@ -81,6 +93,14 @@ public enum AmbariLdapConfigurationKeys {
     return configurationPropertyType;
   }
 
+  public String getDefaultValue() {
+    return defaultValue;
+  }
+
+  public String getDescription() {
+    return description;
+  }
+
   public static AmbariLdapConfigurationKeys fromKeyStr(String keyStr) {
     for (AmbariLdapConfigurationKeys key : values()) {
       if (key.key().equals(keyStr)) {

+ 23 - 6
ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java

@@ -21,14 +21,15 @@ package org.apache.ambari.server.ldap.service;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.ambari.server.controller.internal.AmbariServerConfigurationCategory;
 import org.apache.ambari.server.events.AmbariConfigurationChangedEvent;
+import org.apache.ambari.server.events.JpaInitializedEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
 import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO;
 import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
-import org.apache.ambari.server.security.authorization.AmbariLdapAuthenticationProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -50,7 +51,7 @@ import com.google.inject.Singleton;
 @Singleton
 public class AmbariLdapConfigurationProvider implements Provider<AmbariLdapConfiguration> {
 
-  private static final Logger LOGGER = LoggerFactory.getLogger(AmbariLdapAuthenticationProvider.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(AmbariLdapConfigurationProvider.class);
   private AmbariLdapConfiguration instance;
 
   @Inject
@@ -62,15 +63,18 @@ public class AmbariLdapConfigurationProvider implements Provider<AmbariLdapConfi
   @Inject
   public AmbariLdapConfigurationProvider() {
   }
+  
+  private AtomicBoolean jpaInitialized = new AtomicBoolean(false);
 
   @Inject
   void register() {
     publisher.register(this);
+    LOGGER.info("Registered AmbariLdapConfigurationProvider in event publisher");
   }
 
   @Override
   public AmbariLdapConfiguration get() {
-    return instance != null ? instance : loadInstance();
+    return instance == null || !instance.toMap().isEmpty() ? loadInstance() : instance;
   }
 
   /**
@@ -79,17 +83,22 @@ public class AmbariLdapConfigurationProvider implements Provider<AmbariLdapConfi
    * @return the AmbariLdapConfiguration instance
    */
   private AmbariLdapConfiguration loadInstance() {
-    List<AmbariConfigurationEntity> configEntities;
+    List<AmbariConfigurationEntity> configEntities = null;
 
     LOGGER.info("Loading LDAP configuration ...");
-    configEntities = ambariConfigurationDAOProvider.get().findByCategory(AmbariServerConfigurationCategory.LDAP_CONFIGURATION.getCategoryName());
+    if (jpaInitialized.get()) {
+      LOGGER.info("Actually loading LDAP configuration from DB ...");
+      configEntities = ambariConfigurationDAOProvider.get().findByCategory(AmbariServerConfigurationCategory.LDAP_CONFIGURATION.getCategoryName());
+    }
 
     if (configEntities != null) {
       Map<String, String> properties = toProperties(configEntities);
       instance = new AmbariLdapConfiguration(properties);
+    }else {
+      instance = new AmbariLdapConfiguration();
     }
 
-    LOGGER.info("Loaded LDAP configuration instance: [ {} ]", instance);
+    LOGGER.info("Loaded LDAP configuration instance: [ {} ]", instance.toMap());
 
     return instance;
   }
@@ -111,4 +120,12 @@ public class AmbariLdapConfigurationProvider implements Provider<AmbariLdapConfi
     loadInstance();
     LOGGER.info("Refreshed LDAP config instance.");
   }
+  
+  @Subscribe
+  public void jpaInitialized(JpaInitializedEvent event) {
+    LOGGER.info("JPA initialized event received: {}", event);
+    jpaInitialized.getAndSet(true);
+    loadInstance();
+    LOGGER.info("Refreshed LDAP config instance.");
+  }
 }

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/orm/AmbariLocalSessionInterceptor.java

@@ -30,7 +30,7 @@ import com.google.inject.persist.jpa.AmbariJpaPersistService;
 public class AmbariLocalSessionInterceptor implements MethodInterceptor {
 
   @Inject
-  private final AmbariJpaPersistService emProvider = null;
+  private AmbariJpaPersistService emProvider;
 
   private final ThreadLocal<Boolean> didWeStartWork = new ThreadLocal<>();
 

+ 6 - 2
ambari-server/src/main/java/org/apache/ambari/server/orm/GuiceJpaInitializer.java

@@ -18,6 +18,9 @@
 
 package org.apache.ambari.server.orm;
 
+import org.apache.ambari.server.events.JpaInitializedEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+
 import com.google.inject.Inject;
 import com.google.inject.persist.PersistService;
 
@@ -25,10 +28,11 @@ import com.google.inject.persist.PersistService;
  * This class needs to be instantiated with guice to initialize Guice-persist
  */
 public class GuiceJpaInitializer {
-
+  
   @Inject
-  public GuiceJpaInitializer(PersistService service) {
+  public GuiceJpaInitializer(PersistService service, AmbariEventPublisher publisher) {
     service.start();
+    publisher.publish(new JpaInitializedEvent());
   }
 
 }

+ 9 - 6
ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java

@@ -20,6 +20,7 @@ package org.apache.ambari.server.security.authorization;
 import java.util.List;
 
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
 import org.apache.ambari.server.orm.dao.UserDAO;
 import org.apache.ambari.server.orm.entities.UserEntity;
 import org.apache.ambari.server.security.ClientSecurityType;
@@ -44,7 +45,8 @@ import com.google.inject.Inject;
 public class AmbariLdapAuthenticationProvider implements AuthenticationProvider {
   static Logger LOG = LoggerFactory.getLogger(AmbariLdapAuthenticationProvider.class); // exposed and mutable for "test"
 
-  Configuration configuration;
+  final Configuration configuration;
+  final AmbariLdapConfiguration ldapConfiguration;
 
   private AmbariLdapAuthoritiesPopulator authoritiesPopulator;
   private UserDAO userDAO;
@@ -54,9 +56,10 @@ public class AmbariLdapAuthenticationProvider implements AuthenticationProvider
   private ThreadLocal<String> ldapUserSearchFilterThreadLocal = new ThreadLocal<>();
 
   @Inject
-  public AmbariLdapAuthenticationProvider(Configuration configuration,
+  public AmbariLdapAuthenticationProvider(Configuration configuration, AmbariLdapConfiguration ldapConfiguration,
                                           AmbariLdapAuthoritiesPopulator authoritiesPopulator, UserDAO userDAO) {
     this.configuration = configuration;
+    this.ldapConfiguration = ldapConfiguration;
     this.authoritiesPopulator = authoritiesPopulator;
     this.userDAO = userDAO;
   }
@@ -91,7 +94,7 @@ public class AmbariLdapAuthenticationProvider implements AuthenticationProvider
         }
         throw new InvalidUsernamePasswordCombinationException(e);
       } catch (IncorrectResultSizeDataAccessException multipleUsersFound) {
-        String message = configuration.isLdapAlternateUserSearchEnabled() ?
+        String message = ldapConfiguration.isLdapAlternateUserSearchEnabled() ?
           String.format("Login Failed: Please append your domain to your username and try again.  Example: %s@domain", username) :
           "Login Failed: More than one user with that username found, please work with your Ambari Administrator to adjust your LDAP configuration";
 
@@ -141,7 +144,7 @@ public class AmbariLdapAuthenticationProvider implements AuthenticationProvider
       String userSearchBase = ldapServerProperties.get().getUserSearchBase();
       FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch(userSearchBase, ldapUserSearchFilter, springSecurityContextSource);
 
-      AmbariLdapBindAuthenticator bindAuthenticator = new AmbariLdapBindAuthenticator(springSecurityContextSource, configuration);
+      AmbariLdapBindAuthenticator bindAuthenticator = new AmbariLdapBindAuthenticator(springSecurityContextSource, ldapConfiguration);
       bindAuthenticator.setUserSearch(userSearch);
 
       LdapAuthenticationProvider authenticationProvider = new LdapAuthenticationProvider(bindAuthenticator, authoritiesPopulator);
@@ -178,7 +181,7 @@ public class AmbariLdapAuthenticationProvider implements AuthenticationProvider
    * @return true if properties were reloaded
    */
   private boolean reloadLdapServerProperties() {
-    LdapServerProperties properties = configuration.getLdapServerProperties();
+    LdapServerProperties properties = ldapConfiguration.getLdapServerProperties();
     if (!properties.equals(ldapServerProperties.get())) {
       LOG.info("Reloading properties");
       ldapServerProperties.set(properties);
@@ -190,7 +193,7 @@ public class AmbariLdapAuthenticationProvider implements AuthenticationProvider
 
   private String getLdapUserSearchFilter(String userName) {
     return ldapServerProperties.get()
-      .getUserSearchFilter(configuration.isLdapAlternateUserSearchEnabled() && AmbariLdapUtils.isUserPrincipalNameFormat(userName));
+      .getUserSearchFilter(ldapConfiguration.isLdapAlternateUserSearchEnabled() && AmbariLdapUtils.isUserPrincipalNameFormat(userName));
   }
 
   private Integer getUserId(Authentication authentication) {

+ 6 - 7
ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java

@@ -26,7 +26,7 @@ import javax.naming.NamingException;
 import javax.naming.directory.Attributes;
 import javax.naming.directory.DirContext;
 
-import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -51,15 +51,14 @@ import org.springframework.security.ldap.search.LdapUserSearch;
  */
 public class AmbariLdapBindAuthenticator extends AbstractLdapAuthenticator {
   private static final Logger LOG = LoggerFactory.getLogger(AmbariLdapBindAuthenticator.class);
+  private static final String AMBARI_ADMIN_LDAP_ATTRIBUTE_KEY = "ambari_admin";
 
-  private Configuration configuration;
+  private final AmbariLdapConfiguration ldapConfiguration;
 
-  private static final String AMBARI_ADMIN_LDAP_ATTRIBUTE_KEY = "ambari_admin";
 
-  public AmbariLdapBindAuthenticator(BaseLdapPathContextSource contextSource,
-                                     Configuration configuration) {
+  public AmbariLdapBindAuthenticator(BaseLdapPathContextSource contextSource, AmbariLdapConfiguration ldapConfiguration) {
     super(contextSource);
-    this.configuration = configuration;
+    this.ldapConfiguration = ldapConfiguration;;
   }
 
   @Override
@@ -72,7 +71,7 @@ public class AmbariLdapBindAuthenticator extends AbstractLdapAuthenticator {
 
     DirContextOperations user = authenticate((UsernamePasswordAuthenticationToken) authentication);
 
-    LdapServerProperties ldapServerProperties = configuration.getLdapServerProperties();
+    LdapServerProperties ldapServerProperties = ldapConfiguration.getLdapServerProperties();
     if (StringUtils.isNotEmpty(ldapServerProperties.getAdminGroupMappingRules())) {
       setAmbariAdminAttr(user, ldapServerProperties);
     }

+ 6 - 84
ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java

@@ -22,6 +22,8 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
 
 /**
  * Describes LDAP Server connection parameters
@@ -334,93 +336,13 @@ public class LdapServerProperties {
   }
 
   @Override
-  public boolean equals(Object obj) {
-    if (this == obj) return true;
-    if (obj == null || getClass() != obj.getClass()) return false;
-
-    LdapServerProperties that = (LdapServerProperties) obj;
-
-    if (primaryUrl != null ? !primaryUrl.equals(that.primaryUrl) : that.primaryUrl != null) return false;
-    if (secondaryUrl != null ? !secondaryUrl.equals(that.secondaryUrl) : that.secondaryUrl != null) return false;
-    if (useSsl!=that.useSsl) return false;
-    if (anonymousBind!=that.anonymousBind) return false;
-    if (managerDn != null ? !managerDn.equals(that.managerDn) : that.managerDn != null) return false;
-    if (managerPassword != null ? !managerPassword.equals(that.managerPassword) : that.managerPassword != null)
-      return false;
-    if (baseDN != null ? !baseDN.equals(that.baseDN) : that.baseDN != null) return false;
-    if (userBase != null ? !userBase.equals(that.userBase) : that.userBase != null)
-      return false;
-    if (userObjectClass != null ? !userObjectClass.equals(that.userObjectClass) : that.userObjectClass != null)
-      return false;
-    if (usernameAttribute != null ? !usernameAttribute.equals(that.usernameAttribute) : that.usernameAttribute != null)
-      return false;
-    if (forceUsernameToLowercase != that.forceUsernameToLowercase)
-      return false;
-    if (groupBase != null ? !groupBase.equals(that.groupBase) :
-        that.groupBase != null) return false;
-    if (groupObjectClass != null ? !groupObjectClass.equals(that.groupObjectClass) :
-        that.groupObjectClass != null) return false;
-    if (groupMembershipAttr != null ? !groupMembershipAttr.equals(
-        that.groupMembershipAttr) : that.groupMembershipAttr != null) return false;
-    if (groupNamingAttr != null ? !groupNamingAttr.equals(that.groupNamingAttr) :
-        that.groupNamingAttr != null) return false;
-    if (adminGroupMappingRules != null ? !adminGroupMappingRules.equals(
-        that.adminGroupMappingRules) : that.adminGroupMappingRules != null) return false;
-    if (groupSearchFilter != null ? !groupSearchFilter.equals(
-        that.groupSearchFilter) : that.groupSearchFilter != null) return false;
-    if (dnAttribute != null ? !dnAttribute.equals(
-        that.dnAttribute) : that.dnAttribute != null) return false;
-    if (syncGroupMemberReplacePattern != null ? !syncGroupMemberReplacePattern.equals(
-      that.syncGroupMemberReplacePattern) : that.syncGroupMemberReplacePattern != null) return false;
-    if (syncUserMemberReplacePattern != null ? !syncUserMemberReplacePattern.equals(
-      that.syncUserMemberReplacePattern) : that.syncUserMemberReplacePattern != null) return false;
-    if (syncUserMemberFilter != null ? !syncUserMemberFilter.equals(
-      that.syncUserMemberFilter) : that.syncUserMemberFilter != null) return false;
-    if (syncGroupMemberFilter != null ? !syncGroupMemberFilter.equals(
-      that.syncGroupMemberFilter) : that.syncGroupMemberFilter != null) return false;
-    if (referralMethod != null ? !referralMethod.equals(that.referralMethod) : that.referralMethod != null) return false;
-
-    if (groupMappingEnabled != that.isGroupMappingEnabled()) return false;
-
-    if (paginationEnabled != that.isPaginationEnabled()) return false;
-
-    if (userSearchFilter != null ? !userSearchFilter.equals(that.userSearchFilter) : that.userSearchFilter != null) return false;
-    if (alternateUserSearchFilter != null ? !alternateUserSearchFilter.equals(that.alternateUserSearchFilter) : that.alternateUserSearchFilter != null) return false;
-    if (adminGroupMappingMemberAttr != null ? !adminGroupMappingMemberAttr.equals(that.adminGroupMappingMemberAttr) : that.adminGroupMappingMemberAttr != null) return false;
-
-
-    return true;
+  public final boolean equals(Object obj) {
+    return EqualsBuilder.reflectionEquals(this, obj, false);
   }
 
   @Override
-  public int hashCode() {
-    int result = primaryUrl != null ? primaryUrl.hashCode() : 0;
-    result = 31 * result + (secondaryUrl != null ? secondaryUrl.hashCode() : 0);
-    result = 31 * result + (useSsl ? 1 : 0);
-    result = 31 * result + (anonymousBind ? 1 : 0);
-    result = 31 * result + (managerDn != null ? managerDn.hashCode() : 0);
-    result = 31 * result + (managerPassword != null ? managerPassword.hashCode() : 0);
-    result = 31 * result + (baseDN != null ? baseDN.hashCode() : 0);
-    result = 31 * result + (userBase != null ? userBase.hashCode() : 0);
-    result = 31 * result + (userObjectClass != null ? userObjectClass.hashCode() : 0);
-    result = 31 * result + (usernameAttribute != null ? usernameAttribute.hashCode() : 0);
-    result = 31 * result + (forceUsernameToLowercase ? 1 : 0);
-    result = 31 * result + (groupBase != null ? groupBase.hashCode() : 0);
-    result = 31 * result + (groupObjectClass != null ? groupObjectClass.hashCode() : 0);
-    result = 31 * result + (groupMembershipAttr != null ? groupMembershipAttr.hashCode() : 0);
-    result = 31 * result + (groupNamingAttr != null ? groupNamingAttr.hashCode() : 0);
-    result = 31 * result + (adminGroupMappingRules != null ? adminGroupMappingRules.hashCode() : 0);
-    result = 31 * result + (groupSearchFilter != null ? groupSearchFilter.hashCode() : 0);
-    result = 31 * result + (dnAttribute != null ? dnAttribute.hashCode() : 0);
-    result = 31 * result + (syncUserMemberReplacePattern != null ? syncUserMemberReplacePattern.hashCode() : 0);
-    result = 31 * result + (syncGroupMemberReplacePattern != null ? syncGroupMemberReplacePattern.hashCode() : 0);
-    result = 31 * result + (syncUserMemberFilter != null ? syncUserMemberFilter.hashCode() : 0);
-    result = 31 * result + (syncGroupMemberFilter != null ? syncGroupMemberFilter.hashCode() : 0);
-    result = 31 * result + (referralMethod != null ? referralMethod.hashCode() : 0);
-    result = 31 * result + (userSearchFilter != null ? userSearchFilter.hashCode() : 0);
-    result = 31 * result + (alternateUserSearchFilter != null ? alternateUserSearchFilter.hashCode() : 0);
-    result = 31 * result + (adminGroupMappingMemberAttr != null ? adminGroupMappingMemberAttr.hashCode() : 0);
-    return result;
+  public final int hashCode() {
+    return HashCodeBuilder.reflectionHashCode(1, 31, this);
   }
 
   /**

+ 3 - 3
ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java

@@ -31,9 +31,9 @@ import javax.inject.Inject;
 import javax.persistence.EntityManager;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.hooks.HookContextFactory;
 import org.apache.ambari.server.hooks.HookService;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
 import org.apache.ambari.server.orm.dao.GroupDAO;
 import org.apache.ambari.server.orm.dao.MemberDAO;
 import org.apache.ambari.server.orm.dao.PermissionDAO;
@@ -98,7 +98,7 @@ public class Users {
   @Inject
   protected PasswordEncoder passwordEncoder;
   @Inject
-  protected Configuration configuration;
+  protected AmbariLdapConfiguration ldapConfiguration;
   @Inject
   private AmbariLdapAuthenticationProvider ldapAuthenticationProvider;
 
@@ -786,7 +786,7 @@ public class Users {
 
   private void processLdapAdminGroupMappingRules(Set<MemberEntity> membershipsToCreate) {
 
-    String adminGroupMappings = configuration.getProperty(Configuration.LDAP_ADMIN_GROUP_MAPPING_RULES);
+    String adminGroupMappings = ldapConfiguration.groupMappingRules();
     if (Strings.isNullOrEmpty(adminGroupMappings) || membershipsToCreate.isEmpty()) {
       LOG.info("Nothing to do. LDAP admin group mappings: {}, Memberships to handle: {}", adminGroupMappings, membershipsToCreate.size());
       return;

+ 8 - 7
ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java

@@ -33,7 +33,8 @@ import javax.naming.directory.Attributes;
 import javax.naming.directory.SearchControls;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.configuration.LdapUsernameCollisionHandlingBehavior;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
 import org.apache.ambari.server.security.authorization.AmbariLdapUtils;
 import org.apache.ambari.server.security.authorization.Group;
 import org.apache.ambari.server.security.authorization.LdapServerProperties;
@@ -72,7 +73,7 @@ public class AmbariLdapDataPopulator {
   /**
    * Ambari configuration.
    */
-  private Configuration configuration;
+  private AmbariLdapConfiguration configuration;
 
   /**
    * Highlevel facade for management of users and groups.
@@ -107,7 +108,7 @@ public class AmbariLdapDataPopulator {
    * @param users         utility that provides access to Users
    */
   @Inject
-  public AmbariLdapDataPopulator(Configuration configuration, Users users) {
+  public AmbariLdapDataPopulator(AmbariLdapConfiguration configuration, Users users) {
     this.configuration = configuration;
     this.users = users;
     this.ldapServerProperties = configuration.getLdapServerProperties();
@@ -119,7 +120,7 @@ public class AmbariLdapDataPopulator {
    * @return true if enabled
    */
   public boolean isLdapEnabled() {
-    if (!configuration.isLdapConfigured()) {
+    if (!configuration.ldapEnabled()) {
       return false;
     }
     try {
@@ -215,7 +216,7 @@ public class AmbariLdapDataPopulator {
       if (internalUsersMap.containsKey(userName)) {
         final User user = internalUsersMap.get(userName);
         if (user != null && !user.isLdapUser()) {
-          if (Configuration.LdapUsernameCollisionHandlingBehavior.SKIP == configuration.getLdapSyncCollisionHandlingBehavior()) {
+          if (LdapUsernameCollisionHandlingBehavior.SKIP == configuration.syncCollisionHandlingBehavior()) {
             LOG.info("User '{}' skipped because it is local user", userName);
             batchInfo.getUsersSkipped().add(userName);
           } else {
@@ -292,7 +293,7 @@ public class AmbariLdapDataPopulator {
       if (internalUsersMap.containsKey(userName)) {
         final User user = internalUsersMap.get(userName);
         if (user != null && !user.isLdapUser()) {
-          if (Configuration.LdapUsernameCollisionHandlingBehavior.SKIP == configuration.getLdapSyncCollisionHandlingBehavior()) {
+          if (LdapUsernameCollisionHandlingBehavior.SKIP == configuration.syncCollisionHandlingBehavior()) {
             LOG.info("User '{}' skipped because it is local user", userName);
             batchInfo.getUsersSkipped().add(userName);
           } else {
@@ -405,7 +406,7 @@ public class AmbariLdapDataPopulator {
           continue;
         }
         if (!user.isLdapUser()) {
-          if (Configuration.LdapUsernameCollisionHandlingBehavior.SKIP == configuration.getLdapSyncCollisionHandlingBehavior()) {
+          if (LdapUsernameCollisionHandlingBehavior.SKIP == configuration.syncCollisionHandlingBehavior()) {
             // existing user can not be converted to ldap user, so skip it
             LOG.info("User '{}' skipped because it is local user", externalMember);
             batchInfo.getUsersSkipped().add(externalMember);

+ 183 - 0
ambari-server/src/main/java/org/apache/ambari/server/utils/PasswordUtils.java

@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.security.encryption.CredentialProvider;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+
+/**
+ * Utility class to read passwords from files or the Credential Store
+ */
+public class PasswordUtils {
+
+  private static final Logger LOG = LoggerFactory.getLogger(PasswordUtils.class);
+  private static final Lock LOCK = new ReentrantLock();
+  private static final PasswordUtils INSTANCE = new PasswordUtils();
+
+  /**
+   * The constructor we need for creating a singleton instance
+   */
+  private PasswordUtils() {
+  }
+
+  @Inject
+  private static Configuration configuration;
+
+  private volatile CredentialProvider credentialProvider = null;
+
+  public static PasswordUtils getInstance() {
+    return INSTANCE;
+  }
+
+  /**
+   * Reading the password belong to the given password property
+   *
+   * @param passwordProperty
+   *          this is either the Credential Store alias or the password file name
+   *          you want to read the password for/from
+   * @param defaultPassword
+   *          the default password this function returns in case the given
+   *          <code>passwordProperty</code> is <blank> or the password file cannot
+   *          be read for any reason
+   * @return in case <code>passwordProperty</code> belongs to a Credential Store
+   *         alias this function returns the password of the given Credential
+   *         Store alias or <code>null</code> (if the given alias is
+   *         <code>blank</code> or there is no password found in CS); otherwise
+   *         either the password found in the given password file is returned or
+   *         <code>defaultPassword</code> if the given path is <code>blank</code>
+   *         or cannot be read for any reason
+   * @throws RuntimeException
+   *           if any error occurred while reading the password file
+   */
+  public String readPassword(String passwordProperty, String defaultPassword) {
+    if (StringUtils.isNotBlank(passwordProperty)) {
+      if (CredentialProvider.isAliasString(passwordProperty)) {
+        return readPasswordFromStore(passwordProperty);
+      } else {
+        return readPasswordFromFile(passwordProperty, defaultPassword);
+      }
+    }
+    return defaultPassword;
+  }
+
+  /**
+   * Reading password from the given password file
+   *
+   * @param filePath
+   *          the path of the file to read the password from
+   * @param defaultPassword
+   *          the default password this function returns in case the given
+   *          <code>filePath</code> is <code>blank</code> or the password file
+   *          cannot be read for any reason
+   * @return the password found in the given password file or
+   *         <code>defaultPassword</code> if the given path is <code>blank</code>
+   *         or cannot be read for any reason
+   * @throws RuntimeException
+   *           when any error occurred while reading the password file
+   */
+  public String readPasswordFromFile(String filePath, String defaultPassword) {
+    if (StringUtils.isBlank(filePath) || !fileExistsAndCanBeRead(filePath)) {
+      LOG.debug("DB password file not specified or does not exist/can not be read - using default");
+      return defaultPassword;
+    } else {
+      LOG.debug("Reading password from file {}", filePath);
+      String password = null;
+      try {
+        password = FileUtils.readFileToString(new File(filePath), Charset.defaultCharset());
+        return StringUtils.chomp(password);
+      } catch (IOException e) {
+        throw new RuntimeException("Unable to read password from file [" + filePath + "]", e);
+      }
+    }
+  }
+
+  private boolean fileExistsAndCanBeRead(String filePath) {
+    final File passwordFile = new File(filePath);
+    return passwordFile.exists() && passwordFile.canRead() && passwordFile.isFile();
+  }
+
+  private String readPasswordFromStore(String aliasStr) {
+    return readPasswordFromStore(aliasStr, configuration.getMasterKeyLocation(), configuration.isMasterKeyPersisted(), configuration.getMasterKeyStoreLocation());
+  }
+
+  /**
+   * Reading the password from Credential Store for the given alias
+   *
+   * @param aliasStr
+   *          the Credential Store alias you want to read the password for
+   * @param masterKeyLocation
+   *          the master key location file
+   * @param isMasterKeyPersisted
+   *          a flag indicating whether the master key is persisted
+   * @param masterKeyStoreLocation
+   *          the master key-store location file
+   * @return the password of the given alias if it is not <code>blank</code> and
+   *         there is password stored for this alias in Credential Store;
+   *         <code>null</code> otherwise
+   */
+  public String readPasswordFromStore(String aliasStr, File masterKeyLocation, boolean isMasterKeyPersisted, File masterKeyStoreLocation) {
+    String password = null;
+    loadCredentialProvider(masterKeyLocation, isMasterKeyPersisted, masterKeyStoreLocation);
+    if (credentialProvider != null) {
+      char[] result = null;
+      try {
+        result = credentialProvider.getPasswordForAlias(aliasStr);
+      } catch (AmbariException e) {
+        LOG.error("Error reading from credential store.", e);
+      }
+      if (result != null) {
+        password = new String(result);
+      } else {
+        if (CredentialProvider.isAliasString(aliasStr)) {
+          LOG.error("Cannot read password for alias = " + aliasStr);
+        } else {
+          LOG.warn("Raw password provided, not an alias. It cannot be read from credential store.");
+        }
+      }
+    }
+    return password;
+  }
+
+  private void loadCredentialProvider(File masterKeyLocation, boolean isMasterKeyPersisted, File masterKeyStoreLocation) {
+    if (credentialProvider == null) {
+      try {
+        LOCK.lock();
+        credentialProvider = new CredentialProvider(null, masterKeyLocation, isMasterKeyPersisted, masterKeyStoreLocation);
+      } catch (Exception e) {
+        LOG.info("Credential provider creation failed", e);
+        credentialProvider = null;
+      } finally {
+        LOCK.unlock();
+      }
+    }
+  }
+
+}

+ 5 - 0
ambari-server/src/main/python/ambari-server.py

@@ -964,6 +964,11 @@ def main(options, args, parser):
 def mainBody():
   parser = optparse.OptionParser(usage="usage: %prog action [options]",)
   action = sys.argv[1]
+
+  if action == "setup-ldap":
+    print "setup-ldap action is deprecated. Please configure LDAP integration from the Ambari UI"
+    sys.exit(0)
+
   init_action_parser(action, parser)
   (options, args) = parser.parse_args()
 

+ 0 - 2
ambari-server/src/main/windows/ambari-server.ps1

@@ -295,9 +295,7 @@ switch ($($args[0])){
   }
   "setup-ldap"
   {
-    echo "Setting up LDAP for Ambari Server"
     _pstart $args
-    echo "Ambari Server LDAP setup finished"
   }
   "setup-security"
   {

+ 8 - 167
ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java

@@ -18,8 +18,6 @@
 
 package org.apache.ambari.server.configuration;
 
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.powermock.api.easymock.PowerMock.mockStatic;
 import static org.powermock.api.easymock.PowerMock.replayAll;
@@ -43,9 +41,9 @@ import org.apache.ambari.server.configuration.Configuration.ConnectionPoolType;
 import org.apache.ambari.server.configuration.Configuration.DatabaseType;
 import org.apache.ambari.server.controller.metrics.ThreadPoolEnabledPropertyProvider;
 import org.apache.ambari.server.security.authentication.kerberos.AmbariKerberosAuthenticationProperties;
-import org.apache.ambari.server.security.authorization.LdapServerProperties;
 import org.apache.ambari.server.security.authorization.UserType;
 import org.apache.ambari.server.state.services.MetricsRetrievalService;
+import org.apache.ambari.server.utils.PasswordUtils;
 import org.apache.ambari.server.utils.StageUtils;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.RandomStringUtils;
@@ -66,7 +64,7 @@ import org.powermock.modules.junit4.PowerMockRunner;
 import junit.framework.Assert;
 
 @RunWith(PowerMockRunner.class)
-@PrepareForTest({ Configuration.class })
+@PrepareForTest({ Configuration.class, PasswordUtils.class })
 @PowerMockIgnore( {"javax.management.*", "javax.crypto.*"})
 public class ConfigurationTest {
   public TemporaryFolder temp = new TemporaryFolder();
@@ -221,9 +219,9 @@ public class ConfigurationTest {
     String encrypted = "fake-encrypted-password";
     ambariProperties.setProperty(Configuration.SSL_TRUSTSTORE_PASSWORD.getKey(), unencrypted);
     Configuration conf = spy(new Configuration(ambariProperties));
-    doReturn(null).when(conf).readPasswordFromStore(anyString());
+    PowerMock.stub(PowerMock.method(PasswordUtils.class, "readPasswordFromStore", String.class, File.class, boolean.class, File.class)).toReturn(null);    
     conf.loadSSLParams();
-    Assert.assertEquals(System.getProperty(conf.JAVAX_SSL_TRUSTSTORE_PASSWORD, "unknown"), unencrypted);
+    Assert.assertEquals(System.getProperty(Configuration.JAVAX_SSL_TRUSTSTORE_PASSWORD, "unknown"), unencrypted);
   }
 
   @Test
@@ -233,9 +231,9 @@ public class ConfigurationTest {
     String encrypted = "fake-encrypted-password";
     ambariProperties.setProperty(Configuration.SSL_TRUSTSTORE_PASSWORD.getKey(), unencrypted);
     Configuration conf = spy(new Configuration(ambariProperties));
-    doReturn(encrypted).when(conf).readPasswordFromStore(anyString());
+    PowerMock.stub(PowerMock.method(PasswordUtils.class, "readPasswordFromStore", String.class, File.class, boolean.class, File.class)).toReturn(encrypted);
     conf.loadSSLParams();
-    Assert.assertEquals(System.getProperty(conf.JAVAX_SSL_TRUSTSTORE_PASSWORD, "unknown"), encrypted);
+    Assert.assertEquals(System.getProperty(Configuration.JAVAX_SSL_TRUSTSTORE_PASSWORD, "unknown"), encrypted);
   }
 
   @Test
@@ -246,7 +244,7 @@ public class ConfigurationTest {
     Properties properties = new Properties();
     properties.setProperty(Configuration.SERVER_JDBC_RCA_USER_PASSWD.getKey(), serverJdbcRcaUserPasswdKey);
     Configuration conf = spy(new Configuration(properties));
-    doReturn(encrypted).when(conf).readPasswordFromStore(serverJdbcRcaUserPasswdKey);
+    PowerMock.stub(PowerMock.method(PasswordUtils.class, "readPassword")).toReturn(encrypted);
 
     Assert.assertEquals(encrypted, conf.getRcaDatabasePassword());
   }
@@ -279,8 +277,7 @@ public class ConfigurationTest {
       passwordFile);
 
     Configuration conf = new Configuration(ambariProperties);
-    PowerMock.stub(PowerMock.method(Configuration.class,
-      "readPasswordFromStore")).toReturn(null);
+    PowerMock.stub(PowerMock.method(PasswordUtils.class,"readPasswordFromStore", String.class, File.class, boolean.class, File.class)).toReturn(null);
 
     Assert.assertEquals("ambaritest", conf.getDatabasePassword());
   }
@@ -386,17 +383,6 @@ public class ConfigurationTest {
     Assert.assertEquals(Integer.valueOf(3600), conf.getDefaultServerTaskTimeout());
   }
 
-  @Test
-  public void testGetLdapServerProperties_WrongManagerPassword() throws Exception {
-    final Properties ambariProperties = new Properties();
-    ambariProperties.setProperty(Configuration.LDAP_MANAGER_PASSWORD.getKey(), "somePassword");
-    final Configuration configuration = new Configuration(ambariProperties);
-
-    final LdapServerProperties ldapProperties = configuration.getLdapServerProperties();
-    // if it's not a store alias and is not a file, it should be ignored
-    Assert.assertNull(ldapProperties.getManagerPassword());
-  }
-
   @Test
   public void testIsViewValidationEnabled() throws Exception {
     final Properties ambariProperties = new Properties();
@@ -433,54 +419,6 @@ public class ConfigurationTest {
     Assert.assertFalse(configuration.isViewRemoveUndeployedEnabled());
   }
 
-  @Test
-  public void testGetLdapServerProperties() throws Exception {
-    final Properties ambariProperties = new Properties();
-    final Configuration configuration = new Configuration(ambariProperties);
-
-    final File passwordFile = temp.newFile("ldap-password.dat");
-    final FileOutputStream fos = new FileOutputStream(passwordFile);
-    fos.write("ambaritest\r\n".getBytes());
-    fos.close();
-    final String passwordFilePath = temp.getRoot().getAbsolutePath() + File.separator + "ldap-password.dat";
-
-    ambariProperties.setProperty(Configuration.LDAP_PRIMARY_URL.getKey(), "1");
-    ambariProperties.setProperty(Configuration.LDAP_SECONDARY_URL.getKey(), "2");
-    ambariProperties.setProperty(Configuration.LDAP_USE_SSL.getKey(), "true");
-    ambariProperties.setProperty(Configuration.LDAP_BIND_ANONYMOUSLY.getKey(), "true");
-    ambariProperties.setProperty(Configuration.LDAP_MANAGER_DN.getKey(), "5");
-    ambariProperties.setProperty(Configuration.LDAP_MANAGER_PASSWORD.getKey(), passwordFilePath);
-    ambariProperties.setProperty(Configuration.LDAP_BASE_DN.getKey(), "7");
-    ambariProperties.setProperty(Configuration.LDAP_USERNAME_ATTRIBUTE.getKey(), "8");
-    ambariProperties.setProperty(Configuration.LDAP_USER_BASE.getKey(), "9");
-    ambariProperties.setProperty(Configuration.LDAP_USER_OBJECT_CLASS.getKey(), "10");
-    ambariProperties.setProperty(Configuration.LDAP_GROUP_BASE.getKey(), "11");
-    ambariProperties.setProperty(Configuration.LDAP_GROUP_OBJECT_CLASS.getKey(), "12");
-    ambariProperties.setProperty(Configuration.LDAP_GROUP_MEMBERSHIP_ATTR.getKey(), "13");
-    ambariProperties.setProperty(Configuration.LDAP_GROUP_NAMING_ATTR.getKey(), "14");
-    ambariProperties.setProperty(Configuration.LDAP_ADMIN_GROUP_MAPPING_RULES.getKey(), "15");
-    ambariProperties.setProperty(Configuration.LDAP_GROUP_SEARCH_FILTER.getKey(), "16");
-
-    final LdapServerProperties ldapProperties = configuration.getLdapServerProperties();
-
-    Assert.assertEquals("1", ldapProperties.getPrimaryUrl());
-    Assert.assertEquals("2", ldapProperties.getSecondaryUrl());
-    Assert.assertEquals(true, ldapProperties.isUseSsl());
-    Assert.assertEquals(true, ldapProperties.isAnonymousBind());
-    Assert.assertEquals("5", ldapProperties.getManagerDn());
-    Assert.assertEquals("ambaritest", ldapProperties.getManagerPassword());
-    Assert.assertEquals("7", ldapProperties.getBaseDN());
-    Assert.assertEquals("8", ldapProperties.getUsernameAttribute());
-    Assert.assertEquals("9", ldapProperties.getUserBase());
-    Assert.assertEquals("10", ldapProperties.getUserObjectClass());
-    Assert.assertEquals("11", ldapProperties.getGroupBase());
-    Assert.assertEquals("12", ldapProperties.getGroupObjectClass());
-    Assert.assertEquals("13", ldapProperties.getGroupMembershipAttr());
-    Assert.assertEquals("14", ldapProperties.getGroupNamingAttr());
-    Assert.assertEquals("15", ldapProperties.getAdminGroupMappingRules());
-    Assert.assertEquals("16", ldapProperties.getGroupSearchFilter());
-  }
-
   @Test
   public void testConnectionPoolingProperties() throws Exception {
     // test defaults
@@ -725,103 +663,6 @@ public class ConfigurationTest {
     Assert.assertEquals(actualCacheEnabledConfig, Configuration.SERVER_HRC_STATUS_SUMMARY_CACHE_ENABLED.getDefaultValue());
   }
 
-  @Test
-  public void testLdapUserSearchFilterDefault() throws Exception {
-    // Given
-    final Properties ambariProperties = new Properties();
-    final Configuration configuration = new Configuration(ambariProperties);
-
-    // When
-    String actualLdapUserSearchFilter = configuration.getLdapServerProperties().getUserSearchFilter(false);
-
-    // Then
-    Assert.assertEquals("(&(uid={0})(objectClass=person))", actualLdapUserSearchFilter);
-  }
-
-  @Test
-  public void testLdapUserSearchFilter() throws Exception {
-    // Given
-    final Properties ambariProperties = new Properties();
-    final Configuration configuration = new Configuration(ambariProperties);
-    ambariProperties.setProperty(Configuration.LDAP_USERNAME_ATTRIBUTE.getKey(), "test_uid");
-    ambariProperties.setProperty(Configuration.LDAP_USER_SEARCH_FILTER.getKey(), "{usernameAttribute}={0}");
-
-    // When
-    String actualLdapUserSearchFilter = configuration.getLdapServerProperties().getUserSearchFilter(false);
-
-    // Then
-    Assert.assertEquals("test_uid={0}", actualLdapUserSearchFilter);
-  }
-
-  @Test
-  public void testAlternateLdapUserSearchFilterDefault() throws Exception {
-    // Given
-    final Properties ambariProperties = new Properties();
-    final Configuration configuration = new Configuration(ambariProperties);
-
-    // When
-    String actualLdapUserSearchFilter = configuration.getLdapServerProperties().getUserSearchFilter(true);
-
-    // Then
-    Assert.assertEquals("(&(userPrincipalName={0})(objectClass=person))", actualLdapUserSearchFilter);
-  }
-
-  @Test
-  public void testAlternatLdapUserSearchFilter() throws Exception {
-    // Given
-    final Properties ambariProperties = new Properties();
-    final Configuration configuration = new Configuration(ambariProperties);
-    ambariProperties.setProperty(Configuration.LDAP_USERNAME_ATTRIBUTE.getKey(), "test_uid");
-    ambariProperties.setProperty(Configuration.LDAP_ALT_USER_SEARCH_FILTER.getKey(), "{usernameAttribute}={5}");
-
-    // When
-    String actualLdapUserSearchFilter = configuration.getLdapServerProperties().getUserSearchFilter(true);
-
-    // Then
-    Assert.assertEquals("test_uid={5}", actualLdapUserSearchFilter);
-  }
-
-  @Test
-  public void testAlternateUserSearchEnabledDefault() throws  Exception {
-    // Given
-    final Properties ambariProperties = new Properties();
-    final Configuration configuration = new Configuration(ambariProperties);
-
-    // When
-    boolean actual =  configuration.isLdapAlternateUserSearchEnabled();
-
-    // Then
-    Assert.assertEquals(false, actual);
-  }
-
-  @Test
-  public void testAlternateUserSearchEnabledTrue() throws  Exception {
-    // Given
-    final Properties ambariProperties = new Properties();
-    final Configuration configuration = new Configuration(ambariProperties);
-    ambariProperties.setProperty(Configuration.LDAP_ALT_USER_SEARCH_ENABLED.getKey(), "true");
-
-    // When
-    boolean actual =  configuration.isLdapAlternateUserSearchEnabled();
-
-    // Then
-    Assert.assertEquals(true, actual);
-  }
-
-  @Test
-  public void testAlternateUserSearchEnabledFalse() throws  Exception {
-    // Given
-    final Properties ambariProperties = new Properties();
-    final Configuration configuration = new Configuration(ambariProperties);
-    ambariProperties.setProperty(Configuration.LDAP_ALT_USER_SEARCH_ENABLED.getKey(), "false");
-
-    // When
-    boolean actual =  configuration.isLdapAlternateUserSearchEnabled();
-
-    // Then
-    Assert.assertEquals(false, actual);
-  }
-
   @Test
   public void testCustomDatabaseProperties() throws Exception {
     final Properties ambariProperties = new Properties();

+ 143 - 0
ambari-server/src/test/java/org/apache/ambari/server/ldap/AmbariLdapConfigurationTest.java

@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.ldap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.nio.charset.Charset;
+
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationKeys;
+import org.apache.ambari.server.security.authorization.LdapServerProperties;
+import org.apache.commons.io.FileUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class AmbariLdapConfigurationTest {
+
+  private AmbariLdapConfiguration configuration;
+
+  @Before
+  public void setup() {
+    configuration = new AmbariLdapConfiguration();
+  }
+
+  @Test
+  public void testLdapUserSearchFilterDefault() throws Exception {
+    assertEquals("(&(uid={0})(objectClass=person))", configuration.getLdapServerProperties().getUserSearchFilter(false));
+  }
+
+  @Test
+  public void testLdapUserSearchFilter() throws Exception {
+    configuration.setValueFor(AmbariLdapConfigurationKeys.USER_NAME_ATTRIBUTE, "test_uid");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.USER_SEARCH_FILTER, "{usernameAttribute}={0}");
+    assertEquals("test_uid={0}", configuration.getLdapServerProperties().getUserSearchFilter(false));
+  }
+
+  @Test
+  public void testAlternateLdapUserSearchFilterDefault() throws Exception {
+    assertEquals("(&(userPrincipalName={0})(objectClass=person))", configuration.getLdapServerProperties().getUserSearchFilter(true));
+  }
+
+  @Test
+  public void testAlternatLdapUserSearchFilter() throws Exception {
+    configuration.setValueFor(AmbariLdapConfigurationKeys.USER_NAME_ATTRIBUTE, "test_uid");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_FILTER, "{usernameAttribute}={5}");
+    assertEquals("test_uid={5}", configuration.getLdapServerProperties().getUserSearchFilter(true));
+  }
+
+  @Test
+  public void testAlternateUserSearchEnabledIsSetToFalseByDefault() throws Exception {
+    assertFalse(configuration.isLdapAlternateUserSearchEnabled());
+  }
+
+  @Test
+  public void testAlternateUserSearchEnabledTrue() throws Exception {
+    configuration.setValueFor(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_ENABLED, "true");
+    assertTrue(configuration.isLdapAlternateUserSearchEnabled());
+  }
+
+  @Test
+  public void testAlternateUserSearchEnabledFalse() throws Exception {
+    configuration.setValueFor(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_ENABLED, "false");
+    assertFalse(configuration.isLdapAlternateUserSearchEnabled());
+  }
+
+  @Test
+  public void testGetLdapServerProperties_WrongManagerPassword() throws Exception {
+    configuration.setValueFor(AmbariLdapConfigurationKeys.BIND_PASSWORD, "somePassword");
+    // if it's not a store alias and is not a file, the default manager PW should be returned (which is null)
+    assertNull(configuration.getLdapServerProperties().getManagerPassword());
+  }
+
+  @Test
+  public void testGetLdapServerProperties() throws Exception {
+    final String managerPw = "ambariTest";
+    final TemporaryFolder tempFolder = new TemporaryFolder();
+    tempFolder.create();
+    final File passwordFile = tempFolder.newFile();
+    passwordFile.deleteOnExit();
+    FileUtils.writeStringToFile(passwordFile, managerPw, Charset.defaultCharset());
+
+    configuration.setValueFor(AmbariLdapConfigurationKeys.SERVER_HOST, "host");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.SERVER_PORT, "1");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.SECONDARY_SERVER_HOST, "secHost");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.SECONDARY_SERVER_PORT, "2");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.USE_SSL, "true");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.ANONYMOUS_BIND, "true");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.BIND_DN, "5");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.BIND_PASSWORD, passwordFile.getAbsolutePath());
+    configuration.setValueFor(AmbariLdapConfigurationKeys.USER_SEARCH_BASE, "7");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.USER_NAME_ATTRIBUTE, "8");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.USER_BASE, "9");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.USER_OBJECT_CLASS, "10");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.GROUP_BASE, "11");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.GROUP_OBJECT_CLASS, "12");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.GROUP_MEMBER_ATTRIBUTE, "13");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.GROUP_NAME_ATTRIBUTE, "14");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.GROUP_MAPPING_RULES, "15");
+    configuration.setValueFor(AmbariLdapConfigurationKeys.GROUP_SEARCH_FILTER, "16");
+
+    final LdapServerProperties ldapProperties = configuration.getLdapServerProperties();
+
+    assertEquals("host:1", ldapProperties.getPrimaryUrl());
+    assertEquals("secHost:2", ldapProperties.getSecondaryUrl());
+    assertTrue(ldapProperties.isUseSsl());
+    assertTrue(ldapProperties.isAnonymousBind());
+    assertEquals("5", ldapProperties.getManagerDn());
+    assertEquals(managerPw, ldapProperties.getManagerPassword());
+    assertEquals("7", ldapProperties.getBaseDN());
+    assertEquals("8", ldapProperties.getUsernameAttribute());
+    assertEquals("9", ldapProperties.getUserBase());
+    assertEquals("10", ldapProperties.getUserObjectClass());
+    assertEquals("11", ldapProperties.getGroupBase());
+    assertEquals("12", ldapProperties.getGroupObjectClass());
+    assertEquals("13", ldapProperties.getGroupMembershipAttr());
+    assertEquals("14", ldapProperties.getGroupNamingAttr());
+    assertEquals("15", ldapProperties.getAdminGroupMappingRules());
+    assertEquals("16", ldapProperties.getGroupSearchFilter());
+    tempFolder.delete();
+  }
+
+}

+ 5 - 4
ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderForDNWithSpaceTest.java

@@ -27,6 +27,7 @@ import org.apache.ambari.server.audit.AuditLoggerModule;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.ControllerModule;
 import org.apache.ambari.server.ldap.LdapModule;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationKeys;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.dao.UserDAO;
 import org.apache.ambari.server.security.ClientSecurityType;
@@ -89,7 +90,10 @@ public class AmbariLdapAuthenticationProviderForDNWithSpaceTest extends AmbariLd
     injector.injectMembers(this);
 
     configuration.setClientSecurityType(ClientSecurityType.LDAP);
-    configuration.setProperty(Configuration.LDAP_PRIMARY_URL, "localhost:" + getLdapServer().getPort());
+    authenticationProvider.ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.SERVER_HOST, "localhost");
+    authenticationProvider.ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.SERVER_PORT, String.valueOf(getLdapServer().getPort()));
+    authenticationProvider.ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.USER_SEARCH_BASE, "dc=ambari,dc=the apache,dc=org");
+    authenticationProvider.ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.GROUP_BASE, "ou=the groups,dc=ambari,dc=the apache,dc=org");
   }
 
   @After
@@ -131,9 +135,6 @@ public class AmbariLdapAuthenticationProviderForDNWithSpaceTest extends AmbariLd
     properties.setProperty(Configuration.SERVER_VERSION_FILE.getKey(), "src/test/resources/version");
     properties.setProperty(Configuration.OS_VERSION.getKey(), "centos5");
     properties.setProperty(Configuration.SHARED_RESOURCES_DIR.getKey(), "src/test/resources/");
-    //make ambari detect active configuration
-    properties.setProperty(Configuration.LDAP_BASE_DN.getKey(), "dc=ambari,dc=the apache,dc=org");
-    properties.setProperty(Configuration.LDAP_GROUP_BASE.getKey(), "ou=the groups,dc=ambari,dc=the apache,dc=org");
     return properties;
   }
 }

+ 10 - 6
ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderForDuplicateUserTest.java

@@ -20,6 +20,8 @@ package org.apache.ambari.server.security.authorization;
 import java.util.Properties;
 
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationKeys;
 import org.apache.ambari.server.orm.dao.UserDAO;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
@@ -84,19 +86,21 @@ public class AmbariLdapAuthenticationProviderForDuplicateUserTest extends Ambari
     properties.setProperty(Configuration.SERVER_VERSION_FILE.getKey(),"src/test/resources/version");
     properties.setProperty(Configuration.OS_VERSION.getKey(),"centos5");
     properties.setProperty(Configuration.SHARED_RESOURCES_DIR.getKey(), "src/test/resources/");
-    properties.setProperty(Configuration.LDAP_BASE_DN.getKey(), "dc=apache,dc=org");
-    properties.setProperty(Configuration.LDAP_PRIMARY_URL.getKey(), "localhost:" + getLdapServer().getPort());
-
     Configuration configuration = new Configuration(properties);
+    
+    final AmbariLdapConfiguration ldapConfiguration = new AmbariLdapConfiguration();
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.USER_SEARCH_BASE, "dc=apache,dc=org");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.SERVER_HOST, "localhost");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.SERVER_PORT, String.valueOf(getLdapServer().getPort()));
 
-    authenticationProvider = new AmbariLdapAuthenticationProvider(configuration, authoritiesPopulator, userDAO);
+    authenticationProvider = new AmbariLdapAuthenticationProvider(configuration, ldapConfiguration, authoritiesPopulator, userDAO);
   }
 
   @Test
   public void testAuthenticateDuplicateUserAltUserSearchDisabled() throws Exception {
     // Given
     Authentication authentication = new UsernamePasswordAuthenticationToken("user_dup", "password");
-    authenticationProvider.configuration.setProperty(Configuration.LDAP_ALT_USER_SEARCH_ENABLED.getKey(), "false");
+    authenticationProvider.ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_ENABLED, "false");
 
     expectedException.expect(DuplicateLdapUserFoundAuthenticationException.class);
     expectedException.expectMessage("Login Failed: More than one user with that username found, please work with your Ambari Administrator to adjust your LDAP configuration");
@@ -114,7 +118,7 @@ public class AmbariLdapAuthenticationProviderForDuplicateUserTest extends Ambari
   public void testAuthenticateDuplicateUserAltUserSearchEnabled() throws Exception {
     // Given
     Authentication authentication = new UsernamePasswordAuthenticationToken("user_dup", "password");
-    authenticationProvider.configuration.setProperty(Configuration.LDAP_ALT_USER_SEARCH_ENABLED.getKey(), "true");
+    authenticationProvider.ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_ENABLED, "true");
 
     expectedException.expect(DuplicateLdapUserFoundAuthenticationException.class);
     expectedException.expectMessage("Login Failed: Please append your domain to your username and try again.  Example: user_dup@domain");

+ 17 - 11
ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderTest.java

@@ -30,6 +30,8 @@ import org.apache.ambari.server.H2DatabaseCleaner;
 import org.apache.ambari.server.audit.AuditLoggerModule;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.ldap.LdapModule;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationKeys;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.dao.UserDAO;
 import org.apache.ambari.server.orm.entities.UserEntity;
@@ -88,16 +90,19 @@ public class AmbariLdapAuthenticationProviderTest extends AmbariLdapAuthenticati
   private Users users;
   @Inject
   Configuration configuration;
+  @Inject
+  AmbariLdapConfiguration ldapConfiguration;
 
   @Before
-  public void setUp() {
-    injector = Guice.createInjector(new AuditLoggerModule(), new AuthorizationTestModule(), new LdapModule());
-    injector.injectMembers(this);
+  public void setUp() throws Exception {
+    injector = Guice.createInjector(new AuthorizationTestModule(), new AuditLoggerModule(), new LdapModule());
     injector.getInstance(GuiceJpaInitializer.class);
+    injector.injectMembers(this);
     configuration.setClientSecurityType(ClientSecurityType.LDAP);
-    configuration.setProperty(Configuration.LDAP_ALT_USER_SEARCH_FILTER.getKey(), "(&(mail={0})(objectClass={userObjectClass}))");
-    configuration.setProperty(Configuration.LDAP_ALT_USER_SEARCH_ENABLED.getKey(), "false");
-    configuration.setProperty(Configuration.LDAP_PRIMARY_URL, "localhost:" + getLdapServer().getPort());
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_ENABLED, "false");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_FILTER, "(&(mail={0})(objectClass={userObjectClass}))");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.SERVER_HOST, "localhost");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.SERVER_PORT, String.valueOf(getLdapServer().getPort()));
   }
 
   @After
@@ -117,7 +122,7 @@ public class AmbariLdapAuthenticationProviderTest extends AmbariLdapAuthenticati
     AmbariLdapAuthenticationProvider provider = createMockBuilder(AmbariLdapAuthenticationProvider.class)
             .addMockedMethod("loadLdapAuthenticationProvider")
             .addMockedMethod("isLdapEnabled")
-            .withConstructor(configuration, authoritiesPopulator, userDAO).createMock();
+            .withConstructor(configuration, ldapConfiguration, authoritiesPopulator, userDAO).createMock();
     // Create the last thrown exception
     org.springframework.security.core.AuthenticationException exception =
             createNiceMock(org.springframework.security.core.AuthenticationException.class);
@@ -153,7 +158,7 @@ public class AmbariLdapAuthenticationProviderTest extends AmbariLdapAuthenticati
     AmbariLdapAuthenticationProvider provider = createMockBuilder(AmbariLdapAuthenticationProvider.class)
             .addMockedMethod("loadLdapAuthenticationProvider")
             .addMockedMethod("isLdapEnabled")
-            .withConstructor(configuration, authoritiesPopulator, userDAO).createMock();
+            .withConstructor(configuration, ldapConfiguration, authoritiesPopulator, userDAO).createMock();
     // Create the cause
     org.springframework.ldap.AuthenticationException cause =
             createNiceMock(org.springframework.ldap.AuthenticationException.class);
@@ -210,7 +215,7 @@ public class AmbariLdapAuthenticationProviderTest extends AmbariLdapAuthenticati
     assertNull("User already exists in DB", userDAO.findLdapUserByName("allowedUser@ambari.apache.org"));
     users.createUser("allowedUser@ambari.apache.org", "password", UserType.LDAP, true, false);
     Authentication authentication = new UsernamePasswordAuthenticationToken("allowedUser@ambari.apache.org", "password");
-    configuration.setProperty(Configuration.LDAP_ALT_USER_SEARCH_ENABLED.getKey(), "true");
+    authenticationProvider.ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_ENABLED, "true");
 
     // When
     Authentication result = authenticationProvider.authenticate(authentication);
@@ -224,7 +229,7 @@ public class AmbariLdapAuthenticationProviderTest extends AmbariLdapAuthenticati
     // Given
     assertNull("User already exists in DB", userDAO.findLdapUserByName("allowedUser"));
     Authentication authentication = new UsernamePasswordAuthenticationToken("missingloginalias@ambari.apache.org", "password");
-    configuration.setProperty(Configuration.LDAP_ALT_USER_SEARCH_ENABLED.getKey(), "true");
+    authenticationProvider.ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_ENABLED, "true");
 
 
     // When
@@ -240,7 +245,7 @@ public class AmbariLdapAuthenticationProviderTest extends AmbariLdapAuthenticati
     // Given
     assertNull("User already exists in DB", userDAO.findLdapUserByName("allowedUser"));
     Authentication authentication = new UsernamePasswordAuthenticationToken("allowedUser@ambari.apache.org", "bad_password");
-    configuration.setProperty(Configuration.LDAP_ALT_USER_SEARCH_ENABLED.getKey(), "true");
+    authenticationProvider.ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_ENABLED, "true");
 
 
     // When
@@ -249,4 +254,5 @@ public class AmbariLdapAuthenticationProviderTest extends AmbariLdapAuthenticati
     // Then
     // InvalidUsernamePasswordCombinationException should be thrown due to wrong password
   }
+
 }

+ 76 - 15
ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticatorTest.java

@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.security.authorization;
 
+import static java.lang.Boolean.parseBoolean;
 import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.anyString;
 import static org.easymock.EasyMock.eq;
@@ -25,8 +26,6 @@ import static org.easymock.EasyMock.expectLastCall;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
-import java.util.Properties;
-
 import javax.naming.NamingEnumeration;
 import javax.naming.directory.Attributes;
 import javax.naming.directory.BasicAttributes;
@@ -34,9 +33,11 @@ import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 import javax.naming.ldap.LdapName;
 
-import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationKeys;
 import org.apache.commons.lang.StringUtils;
 import org.easymock.EasyMockSupport;
+import org.junit.Before;
 import org.junit.Test;
 import org.springframework.ldap.core.DirContextOperations;
 import org.springframework.ldap.core.support.LdapContextSource;
@@ -47,7 +48,20 @@ import org.springframework.web.context.request.RequestAttributes;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
 public class AmbariLdapBindAuthenticatorTest extends EasyMockSupport {
+  
+  private Injector injector;
+  private AmbariLdapConfiguration ldapConfiguration;
+  
+  @Before
+  public void init() throws Exception {
+    injector = createInjector();
+    ldapConfiguration = injector.getInstance(AmbariLdapConfiguration.class);
+  }
 
   @Test
   public void testAuthenticateWithoutLogin() throws Exception {
@@ -93,11 +107,12 @@ public class AmbariLdapBindAuthenticatorTest extends EasyMockSupport {
     FilterBasedLdapUserSearch userSearch = createMock(FilterBasedLdapUserSearch.class);
     expect(userSearch.searchForUser(anyString())).andReturn(searchedUserContext).once();
 
+    setupDatabaseConfigurationExpectations(false, false);
+
     replayAll();
 
-    Configuration configuration = new Configuration();
 
-    AmbariLdapBindAuthenticator bindAuthenticator = new AmbariLdapBindAuthenticator(ldapCtxSource, configuration);
+    AmbariLdapBindAuthenticator bindAuthenticator = new AmbariLdapBindAuthenticator(ldapCtxSource, ldapConfiguration);
     bindAuthenticator.setUserSearch(userSearch);
 
     try {
@@ -128,13 +143,13 @@ public class AmbariLdapBindAuthenticatorTest extends EasyMockSupport {
     expectLastCall().atLeastOnce();
 
     DirContextOperations boundUserContext = createMock(DirContextOperations.class);
+    System.out.println(ldapUserDNString);
     expect(boundUserContext.search(eq("ou=groups"), eq("(&(member=" + ldapUserDNString + ")(objectclass=group)(|(cn=Ambari Administrators)))"), anyObject(SearchControls.class)))
         .andReturn(adminGroups)
         .atLeastOnce();
     boundUserContext.close();
     expectLastCall().atLeastOnce();
-
-
+    
     LdapContextSource ldapCtxSource = createMock(LdapContextSource.class);
     expect(ldapCtxSource.getBaseLdapName())
         .andReturn(basePath)
@@ -166,23 +181,69 @@ public class AmbariLdapBindAuthenticatorTest extends EasyMockSupport {
       expectLastCall().once();
     }
 
+    setupDatabaseConfigurationExpectations(true, forceUsernameToLower);
+
     replayAll();
 
     RequestContextHolder.setRequestAttributes(servletRequestAttributes);
 
-    Properties properties = new Properties();
-    if (forceUsernameToLower) {
-      properties.setProperty(Configuration.LDAP_USERNAME_FORCE_LOWERCASE.getKey(), "true");
-    }
-    Configuration configuration = new Configuration(properties);
-
-    AmbariLdapBindAuthenticator bindAuthenticator = new AmbariLdapBindAuthenticator(ldapCtxSource, configuration);
+    AmbariLdapBindAuthenticator bindAuthenticator = new AmbariLdapBindAuthenticator(ldapCtxSource, ldapConfiguration);
     bindAuthenticator.setUserSearch(userSearch);
     DirContextOperations user = bindAuthenticator.authenticate(new UsernamePasswordAuthenticationToken(ambariUsername, "password"));
 
     verifyAll();
 
-    String ldapUserNameAttribute = configuration.getLdapServerProperties().getUsernameAttribute();
+    String ldapUserNameAttribute = ldapConfiguration.getLdapServerProperties().getUsernameAttribute();
     assertEquals(ldapUsername, user.getStringAttribute(ldapUserNameAttribute));
   }
+  
+  private Injector createInjector() throws Exception {
+    return Guice.createInjector(new AbstractModule() {
+
+      @Override
+      protected void configure() {
+        bind(AmbariLdapConfiguration.class).toInstance(createNiceMock(AmbariLdapConfiguration.class));
+      }
+    });
+  }
+  
+  private void setupDatabaseConfigurationExpectations(boolean expectedDatabaseConfigCall, boolean forceUsernameToLowerCase) {
+    final LdapServerProperties ldapServerProperties = getDefaultLdapServerProperties(forceUsernameToLowerCase);
+    ldapServerProperties.setGroupObjectClass("group");
+    if (expectedDatabaseConfigCall) {
+      expect(ldapConfiguration.getLdapServerProperties()).andReturn(ldapServerProperties).anyTimes();
+    }
+  }
+  
+  private static LdapServerProperties getDefaultLdapServerProperties(boolean forceUsernameToLowerCase) {
+    final LdapServerProperties ldapServerProperties = new LdapServerProperties();
+    ldapServerProperties.setPrimaryUrl(AmbariLdapConfigurationKeys.SERVER_HOST.getDefaultValue() + ":" + AmbariLdapConfigurationKeys.SERVER_PORT.getDefaultValue());
+    ldapServerProperties.setSecondaryUrl(AmbariLdapConfigurationKeys.SECONDARY_SERVER_HOST.getDefaultValue() + ":" + AmbariLdapConfigurationKeys.SECONDARY_SERVER_PORT.getDefaultValue());
+    ldapServerProperties.setUseSsl(parseBoolean(AmbariLdapConfigurationKeys.USE_SSL.getDefaultValue()));
+    ldapServerProperties.setAnonymousBind(parseBoolean(AmbariLdapConfigurationKeys.ANONYMOUS_BIND.getDefaultValue()));
+    ldapServerProperties.setManagerDn(AmbariLdapConfigurationKeys.BIND_DN.getDefaultValue());
+    ldapServerProperties.setManagerPassword(AmbariLdapConfigurationKeys.BIND_PASSWORD.getDefaultValue());
+    ldapServerProperties.setBaseDN(AmbariLdapConfigurationKeys.USER_SEARCH_BASE.getDefaultValue());
+    ldapServerProperties.setUsernameAttribute(AmbariLdapConfigurationKeys.USER_NAME_ATTRIBUTE.getDefaultValue());
+    ldapServerProperties.setForceUsernameToLowercase(forceUsernameToLowerCase);
+    ldapServerProperties.setUserBase(AmbariLdapConfigurationKeys.USER_BASE.getDefaultValue());
+    ldapServerProperties.setUserObjectClass(AmbariLdapConfigurationKeys.USER_OBJECT_CLASS.getDefaultValue());
+    ldapServerProperties.setDnAttribute(AmbariLdapConfigurationKeys.DN_ATTRIBUTE.getDefaultValue());
+    ldapServerProperties.setGroupBase(AmbariLdapConfigurationKeys.GROUP_BASE.getDefaultValue());
+    ldapServerProperties.setGroupObjectClass(AmbariLdapConfigurationKeys.GROUP_OBJECT_CLASS.getDefaultValue());
+    ldapServerProperties.setGroupMembershipAttr(AmbariLdapConfigurationKeys.GROUP_MEMBER_ATTRIBUTE.getDefaultValue());
+    ldapServerProperties.setGroupNamingAttr(AmbariLdapConfigurationKeys.GROUP_NAME_ATTRIBUTE.getDefaultValue());
+    ldapServerProperties.setAdminGroupMappingRules(AmbariLdapConfigurationKeys.GROUP_MAPPING_RULES.getDefaultValue());
+    ldapServerProperties.setAdminGroupMappingMemberAttr("");
+    ldapServerProperties.setUserSearchFilter(AmbariLdapConfigurationKeys.USER_SEARCH_FILTER.getDefaultValue());
+    ldapServerProperties.setAlternateUserSearchFilter(AmbariLdapConfigurationKeys.ALTERNATE_USER_SEARCH_FILTER.getDefaultValue());
+    ldapServerProperties.setGroupSearchFilter(AmbariLdapConfigurationKeys.GROUP_SEARCH_FILTER.getDefaultValue());
+    ldapServerProperties.setReferralMethod(AmbariLdapConfigurationKeys.REFERRAL_HANDLING.getDefaultValue());
+    ldapServerProperties.setSyncUserMemberReplacePattern(AmbariLdapConfigurationKeys.USER_MEMBER_REPLACE_PATTERN.getDefaultValue());
+    ldapServerProperties.setSyncGroupMemberReplacePattern(AmbariLdapConfigurationKeys.GROUP_MEMBER_REPLACE_PATTERN.getDefaultValue());
+    ldapServerProperties.setSyncUserMemberFilter(AmbariLdapConfigurationKeys.USER_MEMBER_FILTER.getDefaultValue());
+    ldapServerProperties.setSyncGroupMemberFilter(AmbariLdapConfigurationKeys.GROUP_MEMBER_FILTER.getDefaultValue());
+    ldapServerProperties.setPaginationEnabled(parseBoolean(AmbariLdapConfigurationKeys.PAGINATION_ENABLED.getDefaultValue()));
+    return ldapServerProperties;
+  }
 }

+ 2 - 1
ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AuthorizationTestModule.java

@@ -21,6 +21,7 @@ import java.util.Properties;
 
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.ControllerModule;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationKeys;
 
 import com.google.inject.AbstractModule;
 
@@ -35,7 +36,7 @@ public class AuthorizationTestModule extends AbstractModule {
     properties.setProperty(Configuration.OS_VERSION.getKey(),"centos5");
     properties.setProperty(Configuration.SHARED_RESOURCES_DIR.getKey(), "src/test/resources/");
     //make ambari detect active configuration
-    properties.setProperty(Configuration.LDAP_GROUP_BASE.getKey(), "ou=groups,dc=ambari,dc=apache,dc=org");
+    properties.setProperty(AmbariLdapConfigurationKeys.GROUP_BASE.key(), "ou=groups,dc=ambari,dc=apache,dc=org");
 
     try {
       install(new ControllerModule(properties));

+ 3 - 2
ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AuthorizationTestModuleForLdapDNWithSpace.java

@@ -21,6 +21,7 @@ import java.util.Properties;
 
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.ControllerModule;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationKeys;
 
 import com.google.inject.AbstractModule;
 
@@ -35,8 +36,8 @@ public class AuthorizationTestModuleForLdapDNWithSpace extends AbstractModule {
     properties.setProperty(Configuration.OS_VERSION.getKey(),"centos5");
     properties.setProperty(Configuration.SHARED_RESOURCES_DIR.getKey(), "src/test/resources/");
     //make ambari detect active configuration
-    properties.setProperty(Configuration.LDAP_BASE_DN.getKey(), "dc=ambari,dc=the apache,dc=org");
-    properties.setProperty(Configuration.LDAP_GROUP_BASE.getKey(), "ou=the groups,dc=ambari,dc=the apache,dc=org");
+    properties.setProperty(AmbariLdapConfigurationKeys.USER_SEARCH_BASE.key(), "dc=ambari,dc=the apache,dc=org");
+    properties.setProperty(AmbariLdapConfigurationKeys.GROUP_BASE.key(), "ou=the groups,dc=ambari,dc=the apache,dc=org");
 
     try {
       install(new ControllerModule(properties));

+ 6 - 14
ambari-server/src/test/java/org/apache/ambari/server/security/authorization/LdapServerPropertiesTest.java

@@ -18,21 +18,20 @@
 package org.apache.ambari.server.security.authorization;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 
 import java.util.List;
 
 import org.apache.ambari.server.audit.AuditLoggerModule;
-import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.ldap.LdapModule;
 import org.junit.Before;
 import org.junit.Test;
 
 import com.google.inject.Guice;
-import com.google.inject.Inject;
 import com.google.inject.Injector;
 
+import nl.jqno.equalsverifier.EqualsVerifier;
+import nl.jqno.equalsverifier.Warning;
+
 public class LdapServerPropertiesTest {
 
   private final Injector injector;
@@ -42,9 +41,6 @@ public class LdapServerPropertiesTest {
 
   protected LdapServerProperties ldapServerProperties;
 
-  @Inject
-  Configuration configuration;
-
   public LdapServerPropertiesTest() {
     injector = Guice.createInjector(new AuditLoggerModule(), new AuthorizationTestModule(), new LdapModule());
     injector.injectMembers(this);
@@ -98,13 +94,9 @@ public class LdapServerPropertiesTest {
 
   @Test
   public void testEquals() throws Exception {
-    LdapServerProperties properties1 = configuration.getLdapServerProperties();
-    LdapServerProperties properties2 = configuration.getLdapServerProperties();
-    assertTrue("Properties object is same", properties1 != properties2);
-    assertTrue("Objects are not equal", properties1.equals(properties2));
-    assertTrue("Hash codes are not equal", properties1.hashCode() == properties2.hashCode());
-    properties2.setSecondaryUrl("5.6.7.8:389");
-    assertFalse("Objects are equal", properties1.equals(properties2));
+    EqualsVerifier<LdapServerProperties> verifier = EqualsVerifier.forClass(LdapServerProperties.class);
+    verifier.suppress(Warning.NONFINAL_FIELDS);
+    verifier.verify();
   }
 
   @Test

+ 2 - 0
ambari-server/src/test/java/org/apache/ambari/server/security/authorization/UsersTest.java

@@ -35,6 +35,7 @@ import javax.annotation.Nullable;
 import javax.persistence.EntityManager;
 
 import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.hooks.HookContextFactory;
 import org.apache.ambari.server.hooks.HookService;
 import org.apache.ambari.server.orm.DBAccessor;
@@ -203,6 +204,7 @@ public class UsersTest extends EasyMockSupport {
         bind(HookService.class).toInstance(createMock(HookService.class));
         bind(HookContextFactory.class).toInstance(createMock(HookContextFactory.class));
         bind(PrincipalDAO.class).toInstance(createMock(PrincipalDAO.class));
+        bind(Configuration.class).toInstance(createNiceMock(Configuration.class));
       }
     });
   }

+ 47 - 46
ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java

@@ -48,7 +48,8 @@ import java.util.Set;
 import javax.naming.directory.SearchControls;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.configuration.LdapUsernameCollisionHandlingBehavior;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
 import org.apache.ambari.server.orm.entities.GroupEntity;
 import org.apache.ambari.server.orm.entities.MemberEntity;
 import org.apache.ambari.server.orm.entities.PrincipalEntity;
@@ -84,7 +85,7 @@ import com.google.common.collect.Sets;
 @PrepareForTest(AmbariLdapUtils.class)
 public class AmbariLdapDataPopulatorTest {
   public static class AmbariLdapDataPopulatorTestInstance extends TestAmbariLdapDataPopulator {
-    public AmbariLdapDataPopulatorTestInstance(Configuration configuration, Users users) {
+    public AmbariLdapDataPopulatorTestInstance(AmbariLdapConfiguration configuration, Users users) {
       super(configuration, users);
     }
 
@@ -100,7 +101,7 @@ public class AmbariLdapDataPopulatorTest {
     private LdapContextSource ldapContextSource;
     private PagedResultsDirContextProcessor processor;
 
-    public TestAmbariLdapDataPopulator(Configuration configuration, Users users) {
+    public TestAmbariLdapDataPopulator(AmbariLdapConfiguration configuration, Users users) {
       super(configuration, users);
     }
 
@@ -147,12 +148,12 @@ public class AmbariLdapDataPopulatorTest {
 
   @Test
   public void testIsLdapEnabled_badConfiguration() {
-    final Configuration configuration = createNiceMock(Configuration.class);
+    final AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     final Users users = createNiceMock(Users.class);
 
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
-    expect(configuration.isLdapConfigured()).andReturn(true);
+    expect(configuration.ldapEnabled()).andReturn(true);
     expect(ldapTemplate.search(EasyMock.<String>anyObject(), EasyMock.anyObject(), EasyMock.<AttributesMapper>anyObject())).andThrow(new NullPointerException()).once();
     replay(ldapTemplate, configuration, ldapServerProperties);
 
@@ -166,7 +167,7 @@ public class AmbariLdapDataPopulatorTest {
 
   @Test
   public void testReferralMethod() {
-    final Configuration configuration = createNiceMock(Configuration.class);
+    final AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     final Users users = createNiceMock(Users.class);
     LdapContextSource ldapContextSource = createNiceMock(LdapContextSource.class);
 
@@ -194,12 +195,12 @@ public class AmbariLdapDataPopulatorTest {
 
   @Test
   public void testIsLdapEnabled_reallyEnabled() {
-    final Configuration configuration = createNiceMock(Configuration.class);
+    final AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     final Users users = createNiceMock(Users.class);
 
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
-    expect(configuration.isLdapConfigured()).andReturn(true);
+    expect(configuration.ldapEnabled()).andReturn(true);
     expect(ldapTemplate.search(EasyMock.<String>anyObject(), EasyMock.anyObject(), EasyMock.<AttributesMapper>anyObject())).andReturn(Collections.emptyList()).once();
     replay(ldapTemplate, configuration);
 
@@ -213,12 +214,12 @@ public class AmbariLdapDataPopulatorTest {
 
   @Test
   public void testIsLdapEnabled_reallyDisabled() {
-    final Configuration configuration = createNiceMock(Configuration.class);
+    final AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     final Users users = createNiceMock(Users.class);
 
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
-    expect(configuration.isLdapConfigured()).andReturn(false);
+    expect(configuration.ldapEnabled()).andReturn(false);
     expect(configuration.getLdapServerProperties()).andReturn(ldapServerProperties);
     replay(ldapTemplate, ldapServerProperties, configuration);
 
@@ -255,7 +256,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<Group> groupList = Arrays.asList(group1, group2, group3, group4, group5);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -311,7 +312,7 @@ public class AmbariLdapDataPopulatorTest {
     expect(group2.getGroupName()).andReturn("group2").anyTimes();
     expect(group2.isLdapGroup()).andReturn(true).anyTimes();
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     expect(users.getAllGroups()).andReturn(Arrays.asList(group1, group2));
     expect(users.getAllUsers()).andReturn(Collections.emptyList());
@@ -369,7 +370,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<Group> groupList = Arrays.asList(group1, group2, group3, group4);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -454,7 +455,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<Group> groupList = Arrays.asList(group1, group2, group3, group4);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -531,7 +532,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<Group> groupList = Arrays.asList(group1, group2, group3, group4);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -603,7 +604,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<Group> groupList = Arrays.asList(group1, group2, group3, group4);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -663,7 +664,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<Group> groupList = Arrays.asList(group1, group2, group3, group4, group5);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -730,7 +731,7 @@ public class AmbariLdapDataPopulatorTest {
     expect(group1.isLdapGroup()).andReturn(false).anyTimes();
     expect(group2.isLdapGroup()).andReturn(false).anyTimes();
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -797,7 +798,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<Group> groupList = Arrays.asList(group1, group2, group3, group4);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -859,7 +860,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<Group> groupList = Arrays.asList(group1, group2, group3);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -926,7 +927,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<User> userList = Arrays.asList(user1, user2, user3, user4);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -989,8 +990,8 @@ public class AmbariLdapDataPopulatorTest {
 
     List<User> userList = Arrays.asList(user1, user2, user3);
 
-    Configuration configuration = createNiceMock(Configuration.class);
-    expect(configuration.getLdapSyncCollisionHandlingBehavior()).andReturn(Configuration.LdapUsernameCollisionHandlingBehavior.SKIP).anyTimes();
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
+    expect(configuration.syncCollisionHandlingBehavior()).andReturn(LdapUsernameCollisionHandlingBehavior.SKIP).anyTimes();
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1044,7 +1045,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<User> userList = Arrays.asList(user1, user2);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1101,7 +1102,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<User> userList = Arrays.asList(user1, user2, user3);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1152,7 +1153,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<User> userList = Arrays.asList(user1, user2, user3);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1213,7 +1214,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<User> userList = Arrays.asList(user1, user2, user3, user4);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1266,7 +1267,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<User> userList = Arrays.asList(user1, user2, user3, user4);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1333,7 +1334,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<User> userList = Arrays.asList(user1, user2, user3, user4);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1396,7 +1397,7 @@ public class AmbariLdapDataPopulatorTest {
 
     List<User> userList = Arrays.asList(user1, user2, user3, user4);
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1445,7 +1446,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test(expected = AmbariException.class)
   public void testSynchronizeLdapUsers_absent() throws Exception {
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1500,7 +1501,7 @@ public class AmbariLdapDataPopulatorTest {
     expect(group2.isLdapGroup()).andReturn(true).anyTimes();
     expect(group1.getGroupName()).andReturn("group1").anyTimes();
     expect(group2.getGroupName()).andReturn("group2").anyTimes();
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1584,7 +1585,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   @SuppressWarnings("serial")
   public void testCleanUpLdapUsersWithoutGroup() throws AmbariException {
-    final Configuration configuration = createNiceMock(Configuration.class);
+    final AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     final Users users = createNiceMock(Users.class);
 
     final GroupEntity ldapGroup = new GroupEntity();
@@ -1640,7 +1641,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testGetLdapUserByMemberAttr() throws Exception {
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1679,7 +1680,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testGetLdapUserByMemberAttrNoPagination() throws Exception {
 
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapTemplate ldapTemplate = createNiceMock(LdapTemplate.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
@@ -1783,7 +1784,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testIsMemberAttributeBaseDn() {
     // GIVEN
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
 
@@ -1803,7 +1804,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testIsMemberAttributeBaseDn_withUidMatch() {
     // GIVEN
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
 
@@ -1823,7 +1824,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testIsMemberAttributeBaseDn_withLowerAndUpperCaseValue() {
     // GIVEN
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
 
@@ -1843,7 +1844,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testIsMemberAttributeBaseDn_withWrongAttribute() {
     // GIVEN
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
 
@@ -1863,7 +1864,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testIsMemberAttributeBaseDn_withEmptyValues() {
     // GIVEN
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
 
@@ -1883,7 +1884,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testIsMemberAttributeBaseDn_withDifferentUserAndGroupNameAttribute() {
     // GIVEN
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
     expect(configuration.getLdapServerProperties()).andReturn(ldapServerProperties).anyTimes();
@@ -1902,7 +1903,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testGetUniqueIdMemberPattern() {
     // GIVEN
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     String  syncUserMemberPattern = "(?<sid>.*);(?<guid>.*);(?<member>.*)";
     String memberAttribute = "<SID=...>;<GUID=...>;cn=member,dc=apache,dc=org";
@@ -1916,7 +1917,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testGetUniqueIdByMemberPatternWhenPatternIsWrong() {
     // GIVEN
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     String  syncUserMemberPattern = "(?<sid>.*);(?<guid>.*);(?<mem>.*)";
     String memberAttribute = "<SID=...>;<GUID=...>;cn=member,dc=apache,dc=org";
@@ -1930,7 +1931,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testGetUniqueIdByMemberPatternWhenPatternIsEmpty() {
     // GIVEN
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     String memberAttribute = "<SID=...>;<GUID=...>;cn=member,dc=apache,dc=org";
     AmbariLdapDataPopulatorTestInstance populator = new AmbariLdapDataPopulatorTestInstance(configuration, users);
@@ -1943,7 +1944,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testGetUniqueIdByMemberPatternWhenMembershipAttributeIsNull() {
     // GIVEN
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     String  syncUserMemberPattern = "(?<sid>.*);(?<guid>.*);(?<member>.*)";
     AmbariLdapDataPopulatorTestInstance populator = new AmbariLdapDataPopulatorTestInstance(configuration, users);
@@ -1956,7 +1957,7 @@ public class AmbariLdapDataPopulatorTest {
   @Test
   public void testCreateCustomMemberFilter() {
     // GIVEN
-    Configuration configuration = createNiceMock(Configuration.class);
+    AmbariLdapConfiguration configuration = createNiceMock(AmbariLdapConfiguration.class);
     Users users = createNiceMock(Users.class);
     AmbariLdapDataPopulatorTestInstance populator = new AmbariLdapDataPopulatorTestInstance(configuration, users);
     // WHEN

+ 17 - 11
ambari-server/src/test/java/org/apache/ambari/server/security/ldap/LdapPerformanceTest.java

@@ -25,6 +25,8 @@ import java.util.Set;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.H2DatabaseCleaner;
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationKeys;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.security.ClientSecurityType;
 import org.apache.ambari.server.security.authorization.AuthorizationTestModule;
@@ -54,6 +56,9 @@ public class LdapPerformanceTest {
 
   @Inject
   Configuration configuration;
+  
+  @Inject
+  AmbariLdapConfiguration ldapConfiguration;
 
   final String SPRING_CONTEXT_LOCATION = "classpath:webapp/WEB-INF/spring-security.xml";
 
@@ -64,17 +69,18 @@ public class LdapPerformanceTest {
     injector.injectMembers(this);
     injector.getInstance(GuiceJpaInitializer.class);
     configuration.setClientSecurityType(ClientSecurityType.LDAP);
-
-    configuration.setProperty(Configuration.LDAP_PRIMARY_URL.getKey(), "c6402.ambari.apache.org:389");
-    configuration.setProperty(Configuration.LDAP_USER_OBJECT_CLASS.getKey(), "posixAccount");
-    configuration.setProperty(Configuration.LDAP_USERNAME_ATTRIBUTE.getKey(), "uid");
-    configuration.setProperty(Configuration.LDAP_GROUP_OBJECT_CLASS.getKey(), "posixGroup");
-    configuration.setProperty(Configuration.LDAP_GROUP_NAMING_ATTR.getKey(), "cn");
-    configuration.setProperty(Configuration.LDAP_GROUP_MEMBERSHIP_ATTR.getKey(), "memberUid");
-    configuration.setProperty(Configuration.LDAP_BASE_DN.getKey(), "dc=apache,dc=org");
-    configuration.setProperty(Configuration.LDAP_BIND_ANONYMOUSLY.getKey(), String.valueOf(false));
-    configuration.setProperty(Configuration.LDAP_MANAGER_DN.getKey(), "uid=hdfs,ou=people,ou=dev,dc=apache,dc=org");
-    configuration.setProperty(Configuration.LDAP_MANAGER_PASSWORD.getKey(), "hdfs");
+    
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.SERVER_HOST, "c6402.ambari.apache.org");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.SERVER_PORT, "389");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.USER_OBJECT_CLASS, "posixAccount");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.USER_NAME_ATTRIBUTE, "uid");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.GROUP_OBJECT_CLASS, "posixGroup");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.GROUP_NAME_ATTRIBUTE, "cn");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.GROUP_MEMBER_ATTRIBUTE, "memberUid");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.USER_SEARCH_BASE, "dc=apache,dc=org");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.ANONYMOUS_BIND, "false");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.BIND_DN, "uid=hdfs,ou=people,ou=dev,dc=apache,dc=org");
+    ldapConfiguration.setValueFor(AmbariLdapConfigurationKeys.BIND_PASSWORD, "hdfs");
   }
 
   @After

+ 126 - 0
ambari-server/src/test/java/org/apache/ambari/server/utils/PasswordUtilsTest.java

@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.utils;
+
+import static org.easymock.EasyMock.expect;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.security.encryption.CredentialProvider;
+import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.commons.io.FileUtils;
+import org.easymock.EasyMockSupport;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(PasswordUtils.class)
+public class PasswordUtilsTest extends EasyMockSupport {
+
+  private final static String CS_ALIAS = "${alias=testAlias}";
+
+  private PasswordUtils passwordUtils;
+  
+  private Injector injector;
+  private Configuration configuration;
+
+  @Before
+  public void setUp() {
+    injector = createInjector();
+    configuration = injector.getInstance(Configuration.class);
+    passwordUtils = PasswordUtils.getInstance();
+  }
+
+  @Test
+  public void shouldReadPasswordFromCredentialStoreOfAnAlias() throws Exception {
+    final CredentialProvider credentialProvider = PowerMock.createNiceMock(CredentialProvider.class);
+    setupBasicCredentialProviderExpectations(credentialProvider);
+    credentialProvider.getPasswordForAlias(CS_ALIAS);
+    PowerMock.expectLastCall().andReturn("testPassword".toCharArray()).once();
+    PowerMock.replay(credentialProvider, CredentialProvider.class);
+    replayAll();
+    assertEquals("testPassword", passwordUtils.readPassword(CS_ALIAS, "testPassword"));
+    verifyAll();
+  }
+  
+  @Test
+  public void shouldReadPasswordFromFileIfPasswordPropertyIsPasswordFilePath() throws Exception {
+    final String testPassword = "ambariTest";
+    final File passwordFile = writeTestPasswordFile(testPassword);
+    assertEquals("ambariTest", passwordUtils.readPassword(passwordFile.getAbsolutePath(), "testPasswordDefault"));
+  }
+  
+  @Test
+  public void shouldReadDefaultPasswordIfPasswordPropertyIsPasswordFilePathButItDoesNotExists() throws Exception {
+    final File passwordFile = new File("/my/test/password/file.dat");
+    assertEquals("testPasswordDefault", passwordUtils.readPassword(passwordFile.getAbsolutePath(), "testPasswordDefault"));
+  }
+  
+  @Test
+  public void shouldReadDefaultPasswordIfPasswordPropertyIsPasswordFilePathButItIsNotReadable() throws Exception {
+    final String testPassword = "ambariTest";
+    final File passwordFile = writeTestPasswordFile(testPassword);
+    passwordFile.setReadable(false);
+    assertEquals("testPasswordDefault", passwordUtils.readPassword(passwordFile.getAbsolutePath(), "testPasswordDefault"));
+  }
+
+  private File writeTestPasswordFile(final String testPassword) throws IOException {
+    final TemporaryFolder tempFolder = new TemporaryFolder();
+    tempFolder.create();
+    final File passwordFile = tempFolder.newFile();
+    passwordFile.deleteOnExit();
+    FileUtils.writeStringToFile(passwordFile, testPassword, Charset.defaultCharset());
+    return passwordFile;
+  }
+
+  private void setupBasicCredentialProviderExpectations(CredentialProvider credentialProvider) throws Exception {
+    final File masterKeyLocation = createNiceMock(File.class);
+    final File masterKeyStoreLocation = createNiceMock(File.class);
+    expect(configuration.getMasterKeyLocation()).andReturn(masterKeyLocation).once();
+    expect(configuration.isMasterKeyPersisted()).andReturn(false).once();
+    expect(configuration.getMasterKeyStoreLocation()).andReturn(masterKeyStoreLocation).once();
+    PowerMock.expectNew(CredentialProvider.class, null, (String) null, masterKeyLocation, false, masterKeyStoreLocation).andReturn(credentialProvider);
+  }
+
+  private Injector createInjector() {
+    return Guice.createInjector(new AbstractModule() {
+      @Override
+      protected void configure() {
+        bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+        bind(Configuration.class).toInstance(createNiceMock(Configuration.class));
+        
+        binder().requestStaticInjection(PasswordUtils.class);
+      }
+    });
+  }
+
+}