f64ddf9540a291deade2848ad98194b07cd49dad
[plcapi.git] / PLC / LDAP.py
1 #
2 # LDAP interface. 
3 # Tony Mack  <tmack@cs.princeton.edu>
4 # Copyright (C) 2006 The Trustees of Princeton University
5 #
6 # $Id: LDAP.py 
7 # $URL: svn+ssh://svn.planet-lab.org/svn/PLCAPI/trunk/PLC/LDAP.py $
8 #
9 #
10
11 import ldap
12 import traceback
13 from PLC.Debug import profile, log
14 from PLC.Faults import *
15
16
17 class LDAP:
18     def __init__(self, api):
19         self.api = api
20         self.debug = False
21 #        self.debug = True
22         self.connection = None
23         self.async = False
24
25     def bind(self, async=False):
26         self.async = async
27         if self.connection is None:
28             try:
29                 if self.api.config.PLC_LDAP_SECURE:
30                     url = 'ldaps://%s' % \
31                           (self.api.config.PLC_LDAP_HOST, self.api.config.PLC_LDAP_PORT)
32                 else:
33                     url = 'ldap://%s' % \
34                            (self.api.config.PLC_LDAP_HOST, self.api.config.PLC_LDAP_PORT)
35                 self.connection = ldap.open(url)
36                 dn = self.api.config.PLC_LDAP_ROOT_DN
37                 pw = self.api.config.PLC_LDAP_ROOT_PASSWORD
38                 if async:
39                    self.connection.bind(dn, pw, ldap.AUTH_SIMPLE)
40                 else:
41                    self.connection.bind_s(dn, pw, ldap.AUTH_SIMPLE)
42             except ldap.LDAPError, e:
43                 raise PLCLDAPError, "Unable to bind to server: %s" % e
44         return connection 
45
46     def close(self):
47         """
48         Close the connection
49         """
50         if self.connection is not None:
51             self.connection.unbind()
52             self.connection = None
53
54     def pl_to_ldap(self, filter):
55         """
56         Convert pl fields to ldap fields     
57         """
58         ldap_filter = {'objectClass': '*'}
59         if 'first_name' in filter and 'last_name' in filter:
60             ldap_filter['cn'] = "%s %s" % \
61                     (filter['first_name'], filter['last_name'])
62         for key in filter:
63             if key == 'email':
64                 ldap_filter['mail'] = filter['email']
65             if key ==  'objectClass':
66                 ldap_filter['objectClass'] = filter['objectClass']     
67              
68         return ldap_filter
69
70     def to_ldap_filter(search_filter):
71         search_filter = pl_to_ldap(search_filter) 
72         values = []
73         for (key,value) in search_filter.items():
74             values.append("(%s=%s)" % (key,value))
75         
76         return "(&%s)" % "".join(values)        
77
78     def to_list_of_dicts(results_list):
79         """
80         Convert ldap search results to a list of dicts
81         """
82         results = []
83         for (dn, result_dict) in result_list:
84             result_dict['dn'] = dn
85             results.append(result_dict)
86         return results            
87             
88     def search(self, search_filter):
89         """
90         Search the ldap directory
91         """
92         self.bind()
93         dn = self.api.config.PLC_LDAP_SUFFIX
94         scope = ldap.SCOPE_SUBTREE
95         filter = to_ldap_filter(search_filter)
96         # always do synchronous searchers
97         search = self.connection.search_s
98         results = to_list_of_dicts(search(dn, scope, filter))
99         self.close()
100         return results
101
102     def add(self, record, type):
103         """
104         Add to the ldap directory  
105         """
106         self.bind()
107         self.close()
108         
109     def update(self, record):
110         """
111         Update a record in the ldap directory        
112         """
113         self.bind()
114         self.close()
115     
116     def remove(self, record):
117         """
118         Remove a record from the ldap directory
119         """       
120         self.bind()
121         self.close()