Ticket #1147: ldap_store.py

File ldap_store.py, 3.0 kB (added by naan, 2 years ago)

LdapAuthStore? module

Line 
1 from trac.core import *
2 from trac.config import Option
3 import crypt, md5, sha, base64
4
5 from api import IPasswordStore
6
7 from ldapplugin.api import *
8
9 class LdapAuthStore(Component):
10     implements(IPasswordStore)
11
12     def __init__(self, ldap=None):
13         # looks for groups only if LDAP support is enabled
14         self.enabled = self.config.getbool('ldap', 'enable')
15         if not self.enabled:
16             return
17         self.util = LdapUtil(self.config)
18         # LDAP connection
19         self._ldap = ldap
20         # LDAP connection config
21         self._ldapcfg = {}
22         for name,value in self.config.options('ldap'):
23             if name in LDAP_DIRECTORY_PARAMS:
24                 self._ldapcfg[name] = value
25         # user entry local cache
26         self._cache = {}
27         # max time to live for a cache entry
28         self._cache_ttl = int(self.config.get('ldap', 'cache_ttl', str(15*60)))
29         # max cache entries
30         self._cache_size = min(25, int(self.config.get('ldap', 'cache_size', '100')))
31
32     def has_user(self, user):
33         return user in self.get_users()
34
35     def get_users(self):
36         self._openldap()
37         ldap_users = self._ldap.get_dn(self._ldap.basedn, '(objectclass=simpleSecurityObject)')
38         users = []
39         for user in ldap_users:
40             m = re.match('uid=([^,]+)', user)
41             if m:
42                 users.append(m.group(1))
43         return users
44
45     def set_password(self, user, password):
46         user = user.encode('utf-8')
47         password = password.encode('utf-8')
48         md5_password = "{MD5}" + base64.encodestring(md5.new(password).digest()).rstrip()
49
50         userdn = self._get_userdn(user)
51         p = self._ldap.get_attribute(userdn, 'userPassword')
52
53         self._ldap.add_attribute(userdn, 'userPassword', md5_password)
54         self._ldap.delete_attribute(userdn, 'userPassword', p[0])
55
56     def check_password(self, user, password):
57         userdn = self._get_userdn(user)
58         if userdn is False:
59             return False
60
61         password = password.encode('utf-8')
62         p = self._ldap.get_attribute(userdn, 'userPassword')
63
64         stored = p[0]
65         m = re.match('^({[^}]+})', stored)
66         if m:
67             mech = m.group(0)
68             if mech == '{MD5}':
69                 password = "{MD5}" + base64.encodestring(md5.new(password).digest()).rstrip()
70             elif mech == '{CRYPT}':
71                 password = '{CRYPT}' + crypt.crypt(password, stored[7:9])
72
73         return (stored == password)
74
75     def _openldap(self):
76         """Open a new connection to the LDAP directory"""
77         if self._ldap is None:
78             bind = self.config.getbool('ldap', 'store_bind')
79             self._ldap = LdapConnection(self.env.log, bind, **self._ldapcfg)
80
81     def _get_userdn(self, user):
82         self._openldap()
83
84         ldap_users = self._ldap.get_dn(self._ldap.basedn, '(objectclass=simpleSecurityObject)')
85         for u in ldap_users:
86             m = re.match('uid=([^,]+)', u)
87             if m:
88                 if user == m.group(1):
89                     return u
90         return False