You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by lp...@apache.org on 2017/10/13 15:54:50 UTC

[22/33] ambari git commit: AMBARI-21307 implemented user attribute detection. Organized code

AMBARI-21307 implemented user attribute detection. Organized code


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d0e543cf
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d0e543cf
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d0e543cf

Branch: refs/heads/feature-branch-AMBARI-21307
Commit: d0e543cf7f244e89b2b220c23c21351d9d27f6c3
Parents: 3800adf
Author: lpuskas <lp...@apache.org>
Authored: Tue Sep 12 08:10:47 2017 +0200
Committer: lpuskas <lp...@apache.org>
Committed: Fri Oct 13 17:20:51 2017 +0200

----------------------------------------------------------------------
 .../services/ldap/LdapConfigurationService.java |   2 +-
 .../server/ldap/AmbariLdapConfiguration.java    |   9 ++
 .../server/ldap/service/AmbariLdapFacade.java   |   2 +-
 .../server/ldap/service/AttributeDetector.java  |  38 ++++++
 .../service/LdapAttributeDetectionService.java  |   7 +-
 .../ambari/server/ldap/service/LdapFacade.java  |   2 +-
 .../server/ldap/service/LdapSearchService.java  |  18 ---
 .../ads/DefaultAttributeDetectionService.java   | 132 ++++++++++++++++++-
 .../ads/DefaultLdapConfigurationService.java    |   2 +-
 .../ldap/service/ads/ObjectClassDetector.java   |  81 ++++++++++++
 .../ads/OccurranceAndWeightBasedDetector.java   |  81 ++++++++++++
 .../service/ads/UserNameAttributeDetector.java  |  75 +++++++++++
 .../DefaultAttributeDetectionServiceTest.java   |  35 ++---
 13 files changed, 440 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
index 1b8427b..66809c3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
@@ -107,7 +107,7 @@ public class LdapConfigurationService extends AmbariConfigurationService {
         case TEST_ATTRIBUTES:
 
           LOGGER.info("Testing LDAP attributes ....");
-          groups = ldapFacade.checkLdapAttibutes(ldapConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
+          groups = ldapFacade.checkLdapAttributes(ldapConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
           setResult(groups, result);
 
           break;

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
index 76faeed..e28c6ed 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
@@ -98,6 +98,10 @@ public class AmbariLdapConfiguration {
     return value;
   }
 
+  public void setValueFor(AmbariLdapConfig ambariLdapConfig, Object value) {
+    configurationMap.put(ambariLdapConfig.key(), value);
+  }
+
   @Inject
   public AmbariLdapConfiguration(@Assisted Map<String, Object> configuration) {
     this.configurationMap = configuration;
@@ -219,4 +223,9 @@ public class AmbariLdapConfiguration {
     return (String) configValue(AmbariLdapConfig.REFERRAL_HANDLING);
   }
 
+
+  @Override
+  public String toString() {
+    return configurationMap.toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
index 16bf6b7..f159418 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
@@ -90,7 +90,7 @@ public class AmbariLdapFacade implements LdapFacade {
   }
 
   @Override
-  public Set<String> checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ldapConfiguration) throws AmbariLdapException {
+  public Set<String> checkLdapAttributes(Map<String, Object> parameters, AmbariLdapConfiguration ldapConfiguration) throws AmbariLdapException {
     String userName = getTestUserNameFromParameters(parameters);
     String testUserPass = getTestUserPasswordFromParameters(parameters);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
new file mode 100644
index 0000000..3e20a6a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
@@ -0,0 +1,38 @@
+/*
+ * 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.ldap.service;
+
+/**
+ * Operations for detecting LDAP related settings.
+ * Attributes and values are detected based on a sample set of results returned from a search
+ */
+public interface AttributeDetector<T> {
+
+  /**
+   * Collects potential attribute names or values from a set of result entries.
+   *
+   * @param entry a result entry returned by a search operation
+   */
+  void collect(T entry);
+
+  /**
+   * Implements the decision based on whiche the "best" possible attribute or value is selected.
+   *
+   * @return the most probable attribute name or value (based on the logic in the implementer)
+   */
+  String detect();
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
index 70a8977..4cfa81e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
@@ -15,12 +15,11 @@
 package org.apache.ambari.server.ldap.service;
 
 import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.directory.ldap.client.api.LdapConnection;
 
 /**
  * Contract defining operations to detect user and group attributes.
  */
-public interface LdapAttributeDetectionService {
+public interface LdapAttributeDetectionService<T> {
 
   /**
    * Decorates the passed in configuration with the detected ldap user attribute values
@@ -29,7 +28,7 @@ public interface LdapAttributeDetectionService {
    * @param ambariLdapConfiguration configuration instance holding connection details
    * @return the configuration decorated with user related attributes
    */
-  AmbariLdapConfiguration detectLdapUserAttributes(LdapConnection ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
+  AmbariLdapConfiguration detectLdapUserAttributes(T ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
 
   /**
    * Decorates the passed in configuration with the detected ldap group attribute values
@@ -38,6 +37,6 @@ public interface LdapAttributeDetectionService {
    * @param ambariLdapConfiguration configuration instance holding connection details
    * @return the configuration decorated with group related attributes
    */
-  AmbariLdapConfiguration detectLdapGroupAttributes(LdapConnection ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
+  AmbariLdapConfiguration detectLdapGroupAttributes(T ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
 }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
index 76b16c4..7cd25da 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
@@ -48,5 +48,5 @@ public interface LdapFacade {
    * @param ambariLdapConfiguration configutration instance with available attributes
    * @throws AmbariLdapException if the attribute checking fails
    */
-  Set<String> checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
+  Set<String> checkLdapAttributes(Map<String, Object> parameters, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
deleted file mode 100644
index f1abc8b..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * 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.ldap.service;
-
-public interface LdapSearchService {
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
index 55d0765..710adf1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
@@ -14,19 +14,47 @@
 
 package org.apache.ambari.server.ldap.service.ads;
 
+import java.util.Set;
+
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
 import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.service.AmbariLdapException;
+import org.apache.ambari.server.ldap.service.AttributeDetector;
 import org.apache.ambari.server.ldap.service.LdapAttributeDetectionService;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.message.Response;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchResultEntry;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.util.Strings;
 import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.search.FilterBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.Sets;
+
 @Singleton
-public class DefaultAttributeDetectionService implements LdapAttributeDetectionService {
+public class DefaultAttributeDetectionService implements LdapAttributeDetectionService<LdapConnection> {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(DefaultAttributeDetectionService.class);
+  private static final int SAMPLE_RESULT_SIZE = 50;
+
+  // ordered list of possible username attribute values (the most significant valus should be first)
+
+  private static final Set<String> USER_OBJECT_CLASS_VALUES = Sets.newHashSet("person", "posixAccount");
+  private static final Set<String> USER_GROUP_MEMBER_ATTR_VALUES = Sets.newHashSet("memberOf", "ismemberOf");
+
+  @Inject
+  private UserNameAttributeDetector userNameAttrDetector = new UserNameAttributeDetector(); // todo remove instantition
+
+  @Inject
+  private ObjectClassDetector objectClassDetector = new ObjectClassDetector(); // todo remove instantition
 
   @Inject
   public DefaultAttributeDetectionService() {
@@ -36,7 +64,72 @@ public class DefaultAttributeDetectionService implements LdapAttributeDetectionS
   public AmbariLdapConfiguration detectLdapUserAttributes(LdapConnection connection, AmbariLdapConfiguration ambariLdapConfiguration) {
     LOGGER.info("Detecting LDAP user attributes ...");
 
-    return null;
+    // perform a search using the user search base
+    if (Strings.isEmpty(ambariLdapConfiguration.userSearchBase())) {
+      LOGGER.warn("No user search base provided");
+      return ambariLdapConfiguration;
+    }
+
+    SearchCursor searchCursor = null;
+
+    try {
+      // todo should the bind operation be done in the facade?
+      connection.bind(ambariLdapConfiguration.bindDn(), ambariLdapConfiguration.bindPassword());
+
+      SearchRequest searchRequest = assembleSearchRequest(ambariLdapConfiguration);
+
+      // do the search
+      searchCursor = connection.search(searchRequest);
+
+      int processedUserCnt = 0;
+
+      while (searchCursor.next()) {
+
+        if (processedUserCnt >= SAMPLE_RESULT_SIZE) {
+          LOGGER.debug("The maximum count of results for attribute detection has exceeded. Quit user attribute detection.");
+          break;
+        }
+
+        Response response = searchCursor.get();
+        // process the SearchResultEntry
+
+        if (response instanceof SearchResultEntry) {
+          Entry resultEntry = ((SearchResultEntry) response).getEntry();
+          LOGGER.info("Processing sample entry: [{}]", resultEntry.getDn());
+          userNameAttrDetector.collect(resultEntry);
+          objectClassDetector.collect(resultEntry);
+          processedUserCnt++;
+        }
+      }
+
+      ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_NAME_ATTRIBUTE, userNameAttrDetector.detect());
+      ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS, objectClassDetector.detect());
+
+      LOGGER.info("Decorated ambari ldap config : [{}]", ambariLdapConfiguration);
+
+    } catch (Exception e) {
+
+      LOGGER.error("Ldap operation failed", e);
+    } finally {
+      // housekeeping
+      if (null != searchCursor) {
+        searchCursor.close();
+      }
+    }
+
+    return ambariLdapConfiguration;
+  }
+
+  private void detectUserAttributes(Entry resultEntry, AttributeDetector attributeDetector) {
+
+    attributeDetector.collect(resultEntry);
+
+//    Set<String> objectClasses = detectUserObjectClass(resultEntry);
+//    if (!objectClasses.isEmpty()) {
+//      ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS, StringUtils.join(objectClasses, ","));
+//    }
+
+
   }
 
   @Override
@@ -44,4 +137,39 @@ public class DefaultAttributeDetectionService implements LdapAttributeDetectionS
     LOGGER.info("Detecting LDAP group attributes ...");
     return null;
   }
+
+  private SearchRequest assembleSearchRequest(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+    try {
+
+      SearchRequest req = new SearchRequestImpl();
+      req.setScope(SearchScope.SUBTREE);
+      req.addAttributes("*");
+      req.setTimeLimit(0);
+      req.setBase(new Dn(ambariLdapConfiguration.userSearchBase()));
+      // the filter must be set!
+      req.setFilter(FilterBuilder.present(ambariLdapConfiguration.dnAttribute()).toString());
+
+      return req;
+
+    } catch (Exception e) {
+      LOGGER.error("Could not assemble ldap search request", e);
+      throw new AmbariLdapException(e);
+    }
+  }
+
+
+  private Set<String> detectUserObjectClass(Entry entry) {
+    LOGGER.info("Detecting user object class. Attributes: {}", entry.getAttributes());
+    throw new UnsupportedOperationException("Not yet implemented");
+  }
+
+  private String detectGroupNameAttribute(Entry entry) {
+    throw new UnsupportedOperationException("Not yet implemented");
+  }
+
+  private Set<String> detectGroupObjectClass(Entry entry) {
+    throw new UnsupportedOperationException("Not yet implemented");
+  }
+
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
index db8c77f..fa2e44b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
@@ -190,7 +190,7 @@ public class DefaultLdapConfigurationService implements LdapConfigurationService
       LOGGER.debug("Anonimous binding not supported, binding with the manager detailas...");
       connection.bind(ambariLdapConfiguration.bindDn(), ambariLdapConfiguration.bindPassword());
     } else {
-      LOGGER.debug("Binding anonimously ...");
+      LOGGER.debug("Binding anonymously ...");
       connection.bind();
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
new file mode 100644
index 0000000..2613517
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
@@ -0,0 +1,81 @@
+/*
+ * 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.ldap.service.ads;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public class ObjectClassDetector extends OccurranceAndWeightBasedDetector {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(ObjectClassDetector.class);
+  private Map<String, Integer> occurranceMap = Maps.newHashMap();
+  private Map<String, Integer> weightsMap = Maps.newHashMap();
+
+
+  private enum ObjectClassValue {
+    PERSON("person", 1),
+    POSIX_ACCOUNT("posixAccount", 1);
+
+    private String ocVal;
+    private Integer weight;
+
+    ObjectClassValue(String attr, Integer weght) {
+      this.ocVal = attr;
+      this.weight = weght;
+    }
+
+    Integer weight() {
+      return this.weight;
+    }
+
+    String ocVal() {
+      return this.ocVal;
+    }
+
+  }
+
+  @Inject
+  public ObjectClassDetector() {
+    for (ObjectClassValue ocVal : ObjectClassValue.values()) {
+      occurranceMap.put(ocVal.ocVal(), 0);
+      weightsMap.put(ocVal.ocVal(), ocVal.weight());
+    }
+
+  }
+
+  @Override
+  protected Map<String, Integer> occurranceMap() {
+    return occurranceMap;
+  }
+
+  @Override
+  protected Map<String, Integer> weightsMap() {
+    return weightsMap;
+  }
+
+  @Override
+  protected boolean applies(Entry entry, String value) {
+    LOGGER.info("Checking for object class [{}] in entry [{}]", value, entry.getDn());
+    return entry.hasObjectClass(value);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
new file mode 100644
index 0000000..32dc238
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
@@ -0,0 +1,81 @@
+/*
+ * 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.ldap.service.ads;
+
+import java.util.Map;
+
+import org.apache.ambari.server.ldap.service.AttributeDetector;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class OccurranceAndWeightBasedDetector implements AttributeDetector<Entry> {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(OccurranceAndWeightBasedDetector.class);
+
+  protected abstract Map<String, Integer> occurranceMap();
+
+  protected abstract Map<String, Integer> weightsMap();
+
+  protected abstract boolean applies(Entry entry, String value);
+
+  @Override
+  public String detect() {
+    Map.Entry<String, Integer> selectedEntry = null;
+
+    for (Map.Entry<String, Integer> entry : occurranceMap().entrySet()) {
+      if (selectedEntry == null) {
+
+        selectedEntry = entry;
+        LOGGER.info("Initial name attribute: {}", selectedEntry);
+        continue;
+
+      }
+
+      if (selectedEntry.getValue() < entry.getValue()) {
+
+        LOGGER.info("Changing potential name attribute from : [{}] to: [{}]", selectedEntry, entry);
+        selectedEntry = entry;
+
+      }
+    }
+    return selectedEntry.getKey();
+  }
+
+  @Override
+  public void collect(Entry entry) {
+    LOGGER.info("Detecting ldap attributes/values ...");
+
+    for (String attributeValue : occurranceMap().keySet()) {
+      if (applies(entry, attributeValue)) {
+
+        Integer cnt = occurranceMap().get(attributeValue).intValue();
+        if (weightsMap().containsKey(attributeValue)) {
+          cnt = cnt + weightsMap().get(attributeValue);
+        } else {
+          cnt = cnt + 1;
+        }
+        occurranceMap().put(attributeValue, cnt);
+
+        LOGGER.info("Collected potential name attr: {}, count: {}", attributeValue, cnt);
+
+      } else {
+        LOGGER.info("The result entry doesn't contain the attribute: [{}]", attributeValue);
+      }
+    }
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
new file mode 100644
index 0000000..bbb4b43
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
@@ -0,0 +1,75 @@
+/*
+ * 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.ldap.service.ads;
+
+import java.util.Map;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public class UserNameAttributeDetector extends OccurranceAndWeightBasedDetector {
+  private static final Logger LOGGER = LoggerFactory.getLogger(UserNameAttributeDetector.class);
+
+  private Map<String, Integer> occurranceMap = Maps.newHashMap();
+  private Map<String, Integer> weightsMap = Maps.newHashMap();
+
+  private enum NameAttrs {
+    SAM_ACCOUNT_NAME("sAMAccountName", 5),
+    UID("uid", 3),
+    CN("cn", 1);
+
+    private String attrName;
+    private Integer weight;
+
+    NameAttrs(String attr, Integer weght) {
+      this.attrName = attr;
+      this.weight = weght;
+    }
+
+    Integer weight() {
+      return this.weight;
+    }
+
+    String attrName() {
+      return this.attrName;
+    }
+
+  }
+
+  public UserNameAttributeDetector() {
+    for (NameAttrs nameAttr : NameAttrs.values()) {
+      occurranceMap.put(nameAttr.attrName(), 0);
+      weightsMap.put(nameAttr.attrName(), nameAttr.weight());
+    }
+  }
+
+  protected Map<String, Integer> occurranceMap() {
+    return occurranceMap;
+  }
+
+  protected Map<String, Integer> weightsMap() {
+    return weightsMap;
+  }
+
+  @Override
+  protected boolean applies(Entry entry, String value) {
+    LOGGER.info("Checking for attribute  [{}] in entry [{}]", value, entry.getDn());
+    return entry.containsAttribute(value);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e543cf/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
index 5b3ac20..5cddf1a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
@@ -69,13 +69,31 @@ public class DefaultAttributeDetectionServiceTest {
   }
 
 
+  @Test
+  public void functionalTest() throws Exception {
+    // GIVEN
+    AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(getTestPropertiesMap());
+    LdapConnectionService connectionService = new DefaultLdapConnectionService();
+    LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
+
+    // WHEN
+    AmbariLdapConfiguration config = attributeDetectionService.detectLdapUserAttributes(ldapConnection, ambariLdapConfiguration);
+
+    // THEN
+
+    ldapConnection.close();
+
+  }
+
   private Map<String, Object> getTestPropertiesMap() {
     Map<String, Object> ldapPropsMap = Maps.newHashMap();
 
     ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.ANONYMOUS_BIND.key(), "true");
     ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_HOST.key(), "ldap.forumsys.com");
     ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_PORT.key(), "389");
-    ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_DN.key(), "dc=example,dc=com");
+    ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_DN.key(), "cn=read-only-admin,dc=example,dc=com");
+    ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_PASSWORD.key(), "password");
+    ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.DN_ATTRIBUTE.key(), SchemaConstants.CN_AT);
 
     ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS.key(), SchemaConstants.PERSON_OC);
     ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_NAME_ATTRIBUTE.key(), SchemaConstants.UID_AT);
@@ -84,19 +102,4 @@ public class DefaultAttributeDetectionServiceTest {
     return ldapPropsMap;
 
   }
-
-  @Test
-  public void functionalTest() throws Exception {
-    // GIVEN
-    AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(getTestPropertiesMap());
-    LdapConnectionService connectionService = new DefaultLdapConnectionService();
-    LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
-
-
-    // WHEN
-    AmbariLdapConfiguration config = attributeDetectionService.detectLdapUserAttributes(ldapConnection, ambariLdapConfiguration);
-
-    // THEN
-
-  }
 }
\ No newline at end of file