You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sm...@apache.org on 2013/03/29 18:03:36 UTC

svn commit: r1462536 - in /incubator/ambari/trunk: ./ ambari-server/src/main/java/org/apache/ambari/server/configuration/ ambari-server/src/main/java/org/apache/ambari/server/security/authorization/ ambari-server/src/test/java/org/apache/ambari/server/...

Author: smohanty
Date: Fri Mar 29 17:03:35 2013
New Revision: 1462536

URL: http://svn.apache.org/r1462536
Log:
AMBARI-1746. Backend support for LDAP Group to Ambari Role Mapping. (smohanty)

Added:
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java
Modified:
    incubator/ambari/trunk/CHANGES.txt
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthoritiesPopulator.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java
    incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderTest.java
    incubator/ambari/trunk/ambari-server/src/test/resources/users.ldif

Modified: incubator/ambari/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1462536&r1=1462535&r2=1462536&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Fri Mar 29 17:03:35 2013
@@ -534,6 +534,9 @@ Trunk (unreleased changes):
 
  BUG FIXES
 
+ AMBARI-1746. Backend support for LDAP Group to Ambari Role Mapping. 
+ (smohanty)
+
  AMBARI-1506. Installs HBase ganglia configs when HBase not installed.
  (smohanty)
 

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java?rev=1462536&r1=1462535&r2=1462536&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java Fri Mar 29 17:03:35 2013
@@ -86,6 +86,18 @@ public class Configuration {
       "authentication.ldap.managerPassword";
   public static final String LDAP_USERNAME_ATTRIBUTE_KEY =
       "authentication.ldap.usernameAttribute";
+  public static final String LDAP_GROUP_BASE_KEY =
+      "authorization.ldap.groupBase";
+  public static final String LDAP_GROUP_OBJECT_CLASS_KEY =
+      "authorization.ldap.groupObjectClass";
+  public static final String LDAP_GROUP_NAMING_ATTR_KEY =
+      "authorization.ldap.groupNamingAttr";
+  public static final String LDAP_GROUP_MEMEBERSHIP_ATTR_KEY =
+      "authorization.ldap.groupMembershipAttr";
+  public static final String LDAP_ADMIN_GROUP_MAPPING_RULES_KEY =
+      "authorization.ldap.adminGroupMappingRules";
+  public static final String LDAP_GROUP_SEARCH_FILTER_KEY =
+      "authorization.ldap.groupSearchFilter";
 
   public static final String USER_ROLE_NAME_KEY =
       "authorization.userRoleName";
@@ -138,6 +150,14 @@ public class Configuration {
   private static final String LDAP_PRIMARY_URL_DEFAULT = "localhost:33389";
   private static final String LDAP_BASE_DN_DEFAULT = "dc=ambari,dc=apache,dc=org";
   private static final String LDAP_USERNAME_ATTRIBUTE_DEFAULT = "uid";
+  private static final String LDAP_GROUP_BASE_DEFAULT =
+      "ou=groups,dc=ambari,dc=apache,dc=org";
+  private static final String LDAP_GROUP_OBJECT_CLASS_DEFAULT = "group";
+  private static final String LDAP_GROUP_NAMING_ATTR_DEFAULT = "cn";
+  private static final String LDAP_GROUP_MEMBERSHIP_ATTR_DEFAULT = "member";
+  private static final String LDAP_ADMIN_GROUP_MAPPING_RULES_DEFAULT =
+      "Ambari Administrators";
+  private static final String LDAP_GROUP_SEARCH_FILTER_DEFAULT = "";
 
   //TODO for development purposes only, should be changed to 'false'
   private static final String PERSISTENCE_IN_MEMORY_DEFAULT = "true";
@@ -409,6 +429,18 @@ public class Configuration {
         (LDAP_BASE_DN_KEY, LDAP_BASE_DN_DEFAULT));
     ldapServerProperties.setUsernameAttribute(properties.
         getProperty(LDAP_USERNAME_ATTRIBUTE_KEY, LDAP_USERNAME_ATTRIBUTE_DEFAULT));
+    ldapServerProperties.setGroupBase(properties.
+        getProperty(LDAP_GROUP_BASE_KEY, LDAP_GROUP_BASE_DEFAULT));
+    ldapServerProperties.setGroupObjectClass(properties.
+        getProperty(LDAP_GROUP_OBJECT_CLASS_KEY, LDAP_GROUP_OBJECT_CLASS_DEFAULT));
+    ldapServerProperties.setGroupMembershipAttr(properties.getProperty(
+        LDAP_GROUP_MEMEBERSHIP_ATTR_KEY, LDAP_GROUP_MEMBERSHIP_ATTR_DEFAULT));
+    ldapServerProperties.setGroupNamingAttr(properties.
+        getProperty(LDAP_GROUP_NAMING_ATTR_KEY, LDAP_GROUP_NAMING_ATTR_DEFAULT));
+    ldapServerProperties.setAdminGroupMappingRules(properties.getProperty(
+        LDAP_ADMIN_GROUP_MAPPING_RULES_KEY, LDAP_ADMIN_GROUP_MAPPING_RULES_DEFAULT));
+    ldapServerProperties.setGroupSearchFilter(properties.getProperty(
+        LDAP_GROUP_SEARCH_FILTER_KEY, LDAP_GROUP_SEARCH_FILTER_DEFAULT));
 
     return ldapServerProperties;
   }

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java?rev=1462536&r1=1462535&r2=1462536&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java Fri Mar 29 17:03:35 2013
@@ -28,7 +28,6 @@ import org.springframework.security.core
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
 import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
-import org.springframework.security.ldap.authentication.BindAuthenticator;
 import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
 import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
 
@@ -98,7 +97,7 @@ public class AmbariLdapAuthenticationPro
 
       FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch(userSearchBase, userSearchFilter, springSecurityContextSource);
 
-      BindAuthenticator bindAuthenticator = new BindAuthenticator(springSecurityContextSource);
+      AmbariLdapBindAuthenticator bindAuthenticator = new AmbariLdapBindAuthenticator(springSecurityContextSource, configuration);
       bindAuthenticator.setUserSearch(userSearch);
 
       LdapAuthenticationProvider authenticationProvider = new LdapAuthenticationProvider(bindAuthenticator, authoritiesPopulator);

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthoritiesPopulator.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthoritiesPopulator.java?rev=1462536&r1=1462535&r2=1462536&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthoritiesPopulator.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthoritiesPopulator.java Fri Mar 29 17:03:35 2013
@@ -33,7 +33,7 @@ import org.springframework.security.ldap
 import java.util.Collection;
 
 /**
- * Provides authorities population for LDAP user from local DB
+ * Provides authorities population for LDAP user from LDAP catalog
  */
 public class AmbariLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {
   private static final Logger log = LoggerFactory.getLogger(AmbariLdapAuthoritiesPopulator.class);
@@ -43,6 +43,8 @@ public class AmbariLdapAuthoritiesPopula
   UserDAO userDAO;
   RoleDAO roleDAO;
 
+  private static final String AMBARI_ADMIN_LDAP_ATTRIBUTE_KEY = "ambari_admin";
+
   @Inject
   public AmbariLdapAuthoritiesPopulator(Configuration configuration, AuthorizationHelper authorizationHelper,
                                         UserDAO userDAO, RoleDAO roleDAO) {
@@ -68,29 +70,80 @@ public class AmbariLdapAuthoritiesPopula
       newUser.setLdapUser(true);
       newUser.setUserName(username);
 
-      String roleName = (configuration.getConfigsMap().get(Configuration.USER_ROLE_NAME_KEY));
-      log.info("Using default role name " + roleName);
+      //Adding a default "user" role
+      addRole(newUser, configuration.getConfigsMap().
+          get(Configuration.USER_ROLE_NAME_KEY));
+    }
 
-      RoleEntity role = roleDAO.findByName(roleName);
+    user = userDAO.findLdapUserByName(username);
 
-      if (role == null) {
-        log.info("Role " + roleName + " not present in local DB - creating");
-        role = new RoleEntity();
-        role.setRoleName(roleName);
-        roleDAO.create(role);
-        role = roleDAO.findByName(role.getRoleName());
-      }
-
-      userDAO.create(newUser);
-
-      user = userDAO.findLdapUserByName(newUser.getUserName());
-
-      user.getRoleEntities().add(role);
-      role.getUserEntities().add(user);
-      roleDAO.merge(role);
-      userDAO.merge(user);
+    //Adding an "admin" user role if user is a member of ambari administrators
+    // LDAP group
+    Boolean isAdmin =
+        (Boolean) userData.getObjectAttribute(AMBARI_ADMIN_LDAP_ATTRIBUTE_KEY);
+    if ((isAdmin != null) && isAdmin) {
+      log.info("Adding admin role to LDAP user " + username);
+      addRole(user, configuration.getConfigsMap().
+          get(Configuration.ADMIN_ROLE_NAME_KEY));
+    } else {
+      removeRole(user, configuration.getConfigsMap().
+          get(Configuration.ADMIN_ROLE_NAME_KEY));
     }
 
+    user = userDAO.findLdapUserByName(username);
     return authorizationHelper.convertRolesToAuthorities(user.getRoleEntities());
   }
+
+  /**
+   * Adds role to user's role entities
+   * Adds user to roleName's user entities
+   *
+   * @param user - the user entity to be modified
+   * @param roleName - the role to add to user's roleEntities
+   */
+  private void addRole(UserEntity user, String roleName) {
+    log.info("Using default role name " + roleName);
+
+    RoleEntity roleEntity = roleDAO.findByName(roleName);
+
+    if (roleEntity == null) {
+      log.info("Role " + roleName + " not present in local DB - creating");
+      roleEntity = new RoleEntity();
+      roleEntity.setRoleName(roleName);
+      roleDAO.create(roleEntity);
+      roleEntity = roleDAO.findByName(roleEntity.getRoleName());
+    }
+
+    UserEntity userEntity = userDAO.findLdapUserByName(user.getUserName());
+    if (userEntity == null) {
+      userDAO.create(user);
+      userEntity = userDAO.findLdapUserByName(user.getUserName());
+    }
+
+    if (!userEntity.getRoleEntities().contains(roleEntity)) {
+      userEntity.getRoleEntities().add(roleEntity);
+      roleEntity.getUserEntities().add(userEntity);
+      roleDAO.merge(roleEntity);
+      userDAO.merge(userEntity);
+    }
+  }
+
+  /**
+   * Remove role "roleName" from user "user"
+   * @param user
+   * @param roleName
+   */
+  private void removeRole(UserEntity user, String roleName) {
+    UserEntity userEntity = userDAO.findByPK(user.getUserId());
+    RoleEntity roleEntity = roleDAO.findByName(roleName);
+
+    if (userEntity.getRoleEntities().contains(roleEntity)) {
+      log.info("Removing admin role from LDAP user " + user.getUserName());
+      userEntity.getRoleEntities().remove(roleEntity);
+      roleEntity.getUserEntities().remove(userEntity);
+      userDAO.merge(userEntity);
+      roleDAO.merge(roleEntity);
+    }
+
+  }
 }

Added: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java?rev=1462536&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java (added)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java Fri Mar 29 17:03:35 2013
@@ -0,0 +1,133 @@
+/**
+ * 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.security.authorization;
+
+
+import org.apache.ambari.server.configuration.Configuration;
+import org.springframework.ldap.core.AttributesMapper;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.core.support.BaseLdapPathContextSource;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.ldap.authentication.BindAuthenticator;
+
+import java.util.*;
+import javax.naming.*;
+import javax.naming.directory.Attributes;
+
+
+/**
+ * An authenticator which binds as a user and checks if user should get ambari
+ * admin authorities according to LDAP group membership
+ */
+public class AmbariLdapBindAuthenticator extends BindAuthenticator {
+
+  private Configuration configuration;
+
+  private static final String AMBARI_ADMIN_LDAP_ATTRIBUTE_KEY = "ambari_admin";
+
+  public AmbariLdapBindAuthenticator(BaseLdapPathContextSource contextSource,
+                                     Configuration configuration) {
+    super(contextSource);
+    this.configuration = configuration;
+  }
+
+  @Override
+  public DirContextOperations authenticate(Authentication authentication) {
+
+    DirContextOperations user = super.authenticate(authentication);
+
+    return setAmbariAdminAttr(user);
+  }
+
+  /**
+   *  Checks weather user is a member of ambari administrators group in LDAP. If
+   *  yes, sets user's ambari_admin attribute to true
+   * @param user
+   * @return
+   */
+  private DirContextOperations setAmbariAdminAttr(DirContextOperations user) {
+    LdapServerProperties ldapServerProperties =
+        configuration.getLdapServerProperties();
+
+    String baseDn = ldapServerProperties.getBaseDN().toLowerCase();
+    String groupBase = ldapServerProperties.getGroupBase().toLowerCase();
+    String groupObjectClass = ldapServerProperties.getGroupObjectClass();
+    String groupMembershipAttr = ldapServerProperties.getGroupMembershipAttr();
+    String adminGroupMappingRules =
+        ldapServerProperties.getAdminGroupMappingRules();
+    final String groupNamingAttribute =
+        ldapServerProperties.getGroupNamingAttr();
+    String groupSearchFilter = ldapServerProperties.getGroupSearchFilter();
+
+    //If groupBase is set incorrectly or isn't set - search in BaseDn
+    int indexOfBaseDn = groupBase.indexOf(baseDn);
+    groupBase = indexOfBaseDn <= 0 ? "" : groupBase.substring(0,indexOfBaseDn - 1);
+
+    StringBuilder filterBuilder = new StringBuilder();
+
+    filterBuilder.append("(&(");
+    filterBuilder.append(groupMembershipAttr);
+    filterBuilder.append("=");
+    filterBuilder.append(user.getNameInNamespace());//DN
+
+    if ((groupSearchFilter == null) || groupSearchFilter.equals("") ) {
+      //If groupSearchFilter is not specified, build it from other authorization
+      // group properties
+      filterBuilder.append(")(objectclass=");
+      filterBuilder.append(groupObjectClass);
+      filterBuilder.append(")(|");
+      String[] adminGroupMappingRegexs = adminGroupMappingRules.split(",");
+      for (String adminGroupMappingRegex : adminGroupMappingRegexs) {
+        filterBuilder.append("(");
+        filterBuilder.append(groupNamingAttribute);
+        filterBuilder.append("=");
+        filterBuilder.append(adminGroupMappingRegex);
+        filterBuilder.append(")");
+      }
+      filterBuilder.append(")");
+    } else {
+      filterBuilder.append(")");
+      filterBuilder.append(groupSearchFilter);
+    }
+    filterBuilder.append(")");
+
+    AttributesMapper attributesMapper = new AttributesMapper() {
+      public Object mapFromAttributes(Attributes attrs)
+          throws NamingException {
+        return attrs.get(groupNamingAttribute).get();
+      }
+    };
+
+    LdapTemplate ldapTemplate = new LdapTemplate((getContextSource()));
+    ldapTemplate.setIgnorePartialResultException(true);
+    ldapTemplate.setIgnoreNameNotFoundException(true);
+
+    List<String> ambariAdminGroups = ldapTemplate.search(
+        groupBase,filterBuilder.toString(),attributesMapper);
+
+    //user has admin role granted, if user is a member of at least 1 group,
+    // which matches the rules in configuration
+    if (ambariAdminGroups.size() > 0) {
+      user.setAttributeValue(AMBARI_ADMIN_LDAP_ATTRIBUTE_KEY, true);
+    }
+
+    return user;
+  }
+
+}

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java?rev=1462536&r1=1462535&r2=1462536&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java Fri Mar 29 17:03:35 2013
@@ -38,6 +38,14 @@ public class LdapServerProperties {
   private String userSearchBase = "";
   private String usernameAttribute;
 
+  //LDAP group properties
+  private String groupBase;
+  private String groupObjectClass;
+  private String groupMembershipAttr;
+  private String groupNamingAttr;
+  private String adminGroupMappingRules;
+  private String groupSearchFilter;
+
   private static final String userSearchFilter = "({attribute}={0})";
 
   public List<String> getLdapUrls() {
@@ -131,6 +139,54 @@ public class LdapServerProperties {
     this.usernameAttribute = usernameAttribute;
   }
 
+  public String getGroupBase() {
+    return groupBase;
+  }
+
+  public void setGroupBase(String groupBase) {
+    this.groupBase = groupBase;
+  }
+
+  public String getGroupObjectClass() {
+    return groupObjectClass;
+  }
+
+  public void setGroupObjectClass(String groupObjectClass) {
+    this.groupObjectClass = groupObjectClass;
+  }
+
+  public String getGroupMembershipAttr() {
+    return groupMembershipAttr;
+  }
+
+  public void setGroupMembershipAttr(String groupMembershipAttr) {
+    this.groupMembershipAttr = groupMembershipAttr;
+  }
+
+  public String getGroupNamingAttr() {
+    return groupNamingAttr;
+  }
+
+  public void setGroupNamingAttr(String groupNamingAttr) {
+    this.groupNamingAttr = groupNamingAttr;
+  }
+
+  public String getAdminGroupMappingRules() {
+    return adminGroupMappingRules;
+  }
+
+  public void setAdminGroupMappingRules(String adminGroupMappingRules) {
+    this.adminGroupMappingRules = adminGroupMappingRules;
+  }
+
+  public String getGroupSearchFilter() {
+    return groupSearchFilter;
+  }
+
+  public void setGroupSearchFilter(String groupSearchFilter) {
+    this.groupSearchFilter = groupSearchFilter;
+  }
+
   @Override
   public boolean equals(Object obj) {
     if (this == obj) return true;
@@ -150,6 +206,18 @@ public class LdapServerProperties {
       return false;
     if (usernameAttribute != null ? !usernameAttribute.equals(that.usernameAttribute) : that.usernameAttribute != null)
       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;
 
     return true;
   }
@@ -165,6 +233,12 @@ public class LdapServerProperties {
     result = 31 * result + (baseDN != null ? baseDN.hashCode() : 0);
     result = 31 * result + (userSearchBase != null ? userSearchBase.hashCode() : 0);
     result = 31 * result + (usernameAttribute != null ? usernameAttribute.hashCode() : 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);
     return result;
   }
 

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java?rev=1462536&r1=1462535&r2=1462536&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java Fri Mar 29 17:03:35 2013
@@ -29,6 +29,8 @@ import org.apache.ambari.server.orm.enti
 import org.apache.ambari.server.orm.entities.UserEntity;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.crypto.password.PasswordEncoder;
@@ -53,6 +55,8 @@ public class Users {
   protected PasswordEncoder passwordEncoder;
   @Inject
   protected Configuration configuration;
+  @Inject
+  private  AmbariLdapAuthenticationProvider ldapAuthenticationProvider;
 
 
   public List<User> getAllUsers() {
@@ -113,10 +117,25 @@ public class Users {
     }
 
     UserEntity currentUserEntity = userDAO.findLocalUserByName(currentUserName);
+
+    //Authenticate LDAP admin user
+    boolean isLdapAdmin = false;
+    if (currentUserEntity == null) {
+      currentUserEntity = userDAO.findLdapUserByName(currentUserName);
+      try {
+        ldapAuthenticationProvider.authenticate(
+            new UsernamePasswordAuthenticationToken(currentUserName, currentUserPassword));
+      isLdapAdmin = true;
+      } catch (BadCredentialsException ex) {
+        throw new AmbariException("Incorrect password provided for LDAP user " +
+            currentUserName);
+      }
+    }
+
     UserEntity userEntity = userDAO.findLocalUserByName(userName);
 
     if ((userEntity != null) && (currentUserEntity != null)) {
-      if (passwordEncoder.matches(currentUserPassword, currentUserEntity.getUserPassword())) {
+      if (isLdapAdmin || passwordEncoder.matches(currentUserPassword, currentUserEntity.getUserPassword())) {
         userEntity.setUserPassword(passwordEncoder.encode(newPassword));
         userDAO.merge(userEntity);
       } else {
@@ -186,6 +205,12 @@ public class Users {
   public synchronized void addRoleToUser(User user, String role)
       throws AmbariException {
 
+    if (userDAO.findLdapUserByName(user.getUserName()) != null) {
+      LOG.warn("Trying to add a role to the LDAP user"
+          + ", user=" + user.getUserName());
+      throw new AmbariException("Roles are not editable for LDAP users");
+    }
+
     UserEntity userEntity = userDAO.findByPK(user.getUserId());
     if (userEntity == null) {
       throw new AmbariException("User " + user + " doesn't exist");
@@ -213,6 +238,13 @@ public class Users {
   @Transactional
   public synchronized void removeRoleFromUser(User user, String role)
       throws AmbariException {
+
+    if (userDAO.findLdapUserByName(user.getUserName()) != null) {
+      LOG.warn("Trying to add a role to the LDAP user"
+          + ", user=" + user.getUserName());
+      throw new AmbariException("Roles are not editable for LDAP users");
+    }
+
     UserEntity userEntity = userDAO.findByPK(user.getUserId());
     if (userEntity == null) {
       throw new AmbariException("User " + user + " doesn't exist");

Modified: incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderTest.java?rev=1462536&r1=1462535&r2=1462536&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderTest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderTest.java Fri Mar 29 17:03:35 2013
@@ -25,7 +25,10 @@ import com.google.inject.Injector;
 import com.google.inject.persist.jpa.JpaPersistModule;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.dao.RoleDAO;
 import org.apache.ambari.server.orm.dao.UserDAO;
+import org.apache.ambari.server.orm.entities.RoleEntity;
+import org.apache.ambari.server.orm.entities.UserEntity;
 import org.apache.ambari.server.security.ClientSecurityType;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -34,7 +37,6 @@ import org.junit.Test;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
 import org.springframework.security.ldap.server.ApacheDSContainer;
 
 import static org.junit.Assert.*;
@@ -49,6 +51,8 @@ public class AmbariLdapAuthenticationPro
   @Inject
   private UserDAO userDAO;
   @Inject
+  private RoleDAO roleDAO;
+  @Inject
   Configuration configuration;
 
   @BeforeClass
@@ -92,6 +96,39 @@ public class AmbariLdapAuthenticationPro
     Assert.assertTrue(auth == null);
   }
 
+  @Test
+  public void testLdapAdminGroupToRolesMapping() throws Exception {
+
+    Authentication authentication;
+
+    authentication =
+        new UsernamePasswordAuthenticationToken("allowedAdmin", "password");
+    Authentication result = authenticationProvider.authenticate(authentication);
+    assertTrue(result.isAuthenticated());
+
+    UserEntity allowedAdminEntity = userDAO.findLdapUserByName("allowedAdmin");
+
+    authentication =
+        new UsernamePasswordAuthenticationToken("allowedUser", "password");
+    authenticationProvider.authenticate(authentication);
+    UserEntity allowedUserEntity = userDAO.findLdapUserByName("allowedUser");
+
+
+    RoleEntity adminRole = roleDAO.findByName(
+        configuration.getConfigsMap().get(Configuration.ADMIN_ROLE_NAME_KEY));
+    RoleEntity userRole = roleDAO.findByName(
+        configuration.getConfigsMap().get(Configuration.USER_ROLE_NAME_KEY));
+
+
+    assertTrue(allowedAdminEntity.getRoleEntities().contains(userRole));
+    assertTrue(allowedAdminEntity.getRoleEntities().contains(adminRole));
+
+    assertTrue(allowedUserEntity.getRoleEntities().contains(userRole));
+    assertFalse(allowedUserEntity.getRoleEntities().contains(adminRole));
+
+
+  }
+
   @AfterClass
   public static void afterClass() {
     apacheDSContainer.stop();

Modified: incubator/ambari/trunk/ambari-server/src/test/resources/users.ldif
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/resources/users.ldif?rev=1462536&r1=1462535&r2=1462536&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/resources/users.ldif (original)
+++ incubator/ambari/trunk/ambari-server/src/test/resources/users.ldif Fri Mar 29 17:03:35 2013
@@ -33,3 +33,19 @@ objectclass:top
 objectclass:groupOfNames
 cn: admin
 member: uid=allowedUser,ou=people,dc=ambari,dc=apache,dc=org
+
+dn: uid=allowedAdmin,ou=people,dc=ambari,dc=apache,dc=org
+objectclass:top
+objectclass:person
+objectclass:organizationalPerson
+objectclass:inetOrgPerson
+cn: CraigWalls
+sn: Walls
+uid: allowedAdmin
+userPassword:password
+
+dn: cn=Ambari Administrators,ou=groups,dc=ambari,dc=apache,dc=org
+objectclass:top
+objectclass:group
+cn: Ambari Administrators
+member: uid=allowedAdmin,ou=people,dc=ambari,dc=apache,dc=org