diff --git a/ldapacctmngrplugin/trunk/ldapacctmngrplugin/security/ldapstore.py b/ldapacctmngrplugin/trunk/ldapacctmngrplugin/security/ldapstore.py
index 2ee361972..1603d8578 100644
--- a/ldapacctmngrplugin/trunk/ldapacctmngrplugin/security/ldapstore.py
+++ b/ldapacctmngrplugin/trunk/ldapacctmngrplugin/security/ldapstore.py
@@ -1,9 +1,14 @@
+# -*- coding: utf-8 -*-
+
 import ldap
+from ldap.filter import filter_format
+
+from trac.core import Component, implements
+from trac.config import Option
 
-from trac.core import *
-from trac.config import *
 from acct_mgr.api import IPasswordStore
 
+
 class LDAPStore (Component):
     bind_server = Option('ldap', 'bind_server', 'ldap://localhost:389', doc='LDAP server for authentication. The format is "ldap[s]://host[:port]", e.g., "ldap://localhost:389".')
     bind_anonymous = Option('ldap', 'bind_anonymous', 'yes', doc='If server accepts anonymous bind (yes or no)')
@@ -11,31 +16,39 @@ class LDAPStore (Component):
     bind_passwd = Option('ldap', 'bind_passwd', '', doc='For server not accepting anonymous bind, specify a bind_dn and password.')
     user_searchbase = Option('ldap', 'user_searchbase', 'dc=company,dc=com', doc='Where to look for users. It is usually "dc=your_company_name,dc=com". Please consult the structure of your LDAP tree.')
     user_searchfilter = Option('ldap', 'user_searchfilter', 'objectClass=inetOrgPerson', doc='Filter for listing valid users. The default ("objectClass=inetOrgPerson") should work for most of the cases.')
-    user_matchfilter = Option('ldap', 'user_matchfilter', 'uid=%s', doc='The LDAP field for matching username when authenticating. The query is almost always "uid=%s".')
+    user_field = Option('ldap', 'user_field', 'uid',
+        doc="""The LDAP field to match the username and authenticate.""")
 
     implements(IPasswordStore)
 
     def check_password(self, user, password):
+        if not user or not password:
+            return None
+
         # Authenticate a user by checking password
         con = None
         base = self.user_searchbase
-        filter = self.user_matchfilter % user
-        
+        user_field = self.user_field
+        filter_ = '(&%s%s)' % (filter_format('(%s=%s)', [user_field, user]),
+                               self._get_searchfilter())
+
         # nested "try:" for python2.4
         try:
+            con = self.init_connection()
+            resp = con.search_s(base, ldap.SCOPE_SUBTREE, filter_,
+                                ['dn', user_field])
+            for dn, attrs in resp:
+                if dn and attrs.get(user_field):
+                    break
+            else:
+                return None  # No available user
             try:
-                con = self.init_connection()
-                resp = con.search_s(base, ldap.SCOPE_SUBTREE, filter, ['dn'])
-                
-                # Added to prevent empty password authentication (some server allows that)
-                if not len(resp) :
-                    return None
-
-                resp = con.simple_bind_s(resp[0][0], password)
-                return True
+                resp = con.simple_bind_s(dn, password)
             except ldap.INVALID_CREDENTIALS:
                 self.log.debug('Invalid credentials: user %s not authenticated', user)
                 return False
+            else:
+                return True
         finally:
             if con != None:
                 con.unbind()
@@ -44,24 +57,29 @@ class LDAPStore (Component):
         # Get list of users from LDAP server
         con = None
         base = self.user_searchbase
-        filter = self.user_searchfilter
+        filter_ = self._get_searchfilter()
+        user_field = self.user_field
         resp = None
-        
+
         try:
             con = self.init_connection()
-            resp = con.search_s(base, ldap.SCOPE_SUBTREE, filter, ['dn','uid'])
+            resp = con.search_s(base, ldap.SCOPE_SUBTREE, filter_,
+                                ['dn', user_field])
         finally:
             if con != None:
                 con.unbind()
-        
-        self.log.debug('List users: get %d users' % (len(resp)))
-        for entry in resp:
-            if entry[1]['uid'][0]:
-                yield entry[1]['uid'][0]
+
+        for dn, attrs in resp:
+            if not dn:
+                continue
+            usernames = attrs.get(user_field)
+            if usernames:
+                yield usernames[0]
 
     def init_connection(self):
         # Initialize LDAP connection
         connection = ldap.initialize(self.bind_server)
+        connection.set_option(ldap.OPT_REFERRALS, 0)
 
         if self.bind_server.startswith('ldaps'):
             # Not verifying the certificate for TLS
@@ -69,6 +87,12 @@ class LDAPStore (Component):
             #connection.start_tls_s()
 
         if self.bind_anonymous.lower() != 'yes':
-            resp = connection.simple_bind_s(self.bind_dn, self.bind_passwd)
+            connection.simple_bind_s(self.bind_dn, self.bind_passwd)
 
         return connection
+
+    def _get_searchfilter(self):
+        filter_ = self.user_searchfilter
+        if not filter_.startswith('(') or not filter_.endswith(')'):
+            filter_ = '(%s)' % filter_
+        return filter_
