##// END OF EJS Templates
auth: refactor ldap parameter handling - make it clear that port is optional
Mads Kiilerich -
r6294:949c843b default
parent child Browse files
Show More
@@ -161,7 +161,6 b" Here's a typical LDAP setup::"
161 Connection settings
161 Connection settings
162 Enable LDAP = checked
162 Enable LDAP = checked
163 Host = host.example.com
163 Host = host.example.com
164 Port = 389
165 Account = <account>
164 Account = <account>
166 Password = <password>
165 Password = <password>
167 Connection Security = LDAPS connection
166 Connection Security = LDAPS connection
@@ -198,8 +197,9 b' Host : required'
198
197
199 .. _Port:
198 .. _Port:
200
199
201 Port : required
200 Port : optional
202 389 for un-encrypted LDAP, 636 for SSL-encrypted LDAP.
201 Defaults to 389 for PLAIN un-encrypted LDAP and START_TLS.
202 Defaults to 636 for LDAPS.
203
203
204 .. _ldap_account:
204 .. _ldap_account:
205
205
@@ -219,16 +219,19 b' Password : optional'
219 Connection Security : required
219 Connection Security : required
220 Defines the connection to LDAP server
220 Defines the connection to LDAP server
221
221
222 No encryption
222 PLAIN
223 Plain non encrypted connection
223 Plain unencrypted LDAP connection.
224 This will by default use `Port`_ 389.
224
225
225 LDAPS connection
226 LDAPS
226 Enable LDAPS connections. It will likely require `Port`_ to be set to
227 Use secure LDAPS connections according to `Certificate
227 a different value (standard LDAPS port is 636). When LDAPS is enabled
228 Checks`_ configuration.
228 then `Certificate Checks`_ is required.
229 This will by default use `Port`_ 636.
229
230
230 START_TLS on LDAP connection
231 START_TLS
231 START TLS connection
232 Use START TLS according to `Certificate Checks`_ configuration on an
233 apparently "plain" LDAP connection.
234 This will by default use `Port`_ 389.
232
235
233 .. _Certificate Checks:
236 .. _Certificate Checks:
234
237
@@ -48,7 +48,7 b' except ImportError:'
48
48
49 class AuthLdap(object):
49 class AuthLdap(object):
50
50
51 def __init__(self, server, base_dn, port=389, bind_dn='', bind_pass='',
51 def __init__(self, server, base_dn, port=None, bind_dn='', bind_pass='',
52 tls_kind='PLAIN', tls_reqcert='DEMAND', cacertdir=None, ldap_version=3,
52 tls_kind='PLAIN', tls_reqcert='DEMAND', cacertdir=None, ldap_version=3,
53 ldap_filter='(&(objectClass=user)(!(objectClass=computer)))',
53 ldap_filter='(&(objectClass=user)(!(objectClass=computer)))',
54 search_scope='SUBTREE', attr_login='uid'):
54 search_scope='SUBTREE', attr_login='uid'):
@@ -56,32 +56,25 b' class AuthLdap(object):'
56 raise LdapImportError
56 raise LdapImportError
57
57
58 self.ldap_version = ldap_version
58 self.ldap_version = ldap_version
59 ldap_server_type = 'ldap'
60
59
61 self.TLS_KIND = tls_kind
60 self.TLS_KIND = tls_kind
62
63 if self.TLS_KIND == 'LDAPS':
64 port = port or 689
65 ldap_server_type = ldap_server_type + 's'
66
67 OPT_X_TLS_DEMAND = 2
61 OPT_X_TLS_DEMAND = 2
68 self.TLS_REQCERT = getattr(ldap, 'OPT_X_TLS_%s' % tls_reqcert,
62 self.TLS_REQCERT = getattr(ldap, 'OPT_X_TLS_%s' % tls_reqcert,
69 OPT_X_TLS_DEMAND)
63 OPT_X_TLS_DEMAND)
70 self.cacertdir = cacertdir
64 self.cacertdir = cacertdir
71
65
72 # split server into list
66 protocol = 'ldaps' if self.TLS_KIND == 'LDAPS' else 'ldap'
73 self.LDAP_SERVER_ADDRESS = server.split(',')
67 if not port:
74 self.LDAP_SERVER_PORT = port
68 port = 636 if self.TLS_KIND == 'LDAPS' else 389
69 self.LDAP_SERVER = str(', '.join(
70 "%s://%s:%s" % (protocol,
71 host.strip(),
72 port)
73 for host in server.split(',')))
75
74
76 # USE FOR READ ONLY BIND TO LDAP SERVER
77 self.LDAP_BIND_DN = safe_str(bind_dn)
75 self.LDAP_BIND_DN = safe_str(bind_dn)
78 self.LDAP_BIND_PASS = safe_str(bind_pass)
76 self.LDAP_BIND_PASS = safe_str(bind_pass)
79 _LDAP_SERVERS = []
77
80 for host in self.LDAP_SERVER_ADDRESS:
81 _LDAP_SERVERS.append("%s://%s:%s" % (ldap_server_type,
82 host.replace(' ', ''),
83 self.LDAP_SERVER_PORT))
84 self.LDAP_SERVER = str(', '.join(s for s in _LDAP_SERVERS))
85 self.BASE_DN = safe_str(base_dn)
78 self.BASE_DN = safe_str(base_dn)
86 self.LDAP_FILTER = safe_str(ldap_filter)
79 self.LDAP_FILTER = safe_str(ldap_filter)
87 self.SEARCH_SCOPE = getattr(ldap, 'SCOPE_%s' % search_scope)
80 self.SEARCH_SCOPE = getattr(ldap, 'SCOPE_%s' % search_scope)
@@ -98,10 +91,6 b' class AuthLdap(object):'
98 :param password: password
91 :param password: password
99 """
92 """
100
93
101 from kallithea.lib.helpers import chop_at
102
103 uid = chop_at(username, "@%s" % self.LDAP_SERVER_ADDRESS)
104
105 if not password:
94 if not password:
106 log.debug("Attempt to authenticate LDAP user "
95 log.debug("Attempt to authenticate LDAP user "
107 "with blank password rejected.")
96 "with blank password rejected.")
@@ -160,16 +149,16 b' class AuthLdap(object):'
160 return dn, attrs
149 return dn, attrs
161
150
162 except ldap.INVALID_CREDENTIALS:
151 except ldap.INVALID_CREDENTIALS:
163 log.debug("LDAP rejected password for user '%s' (%s): %s",
152 log.debug("LDAP rejected password for user '%s': %s",
164 uid, username, dn)
153 username, dn)
165 continue # accept authentication as another ldap user with same username
154 continue # accept authentication as another ldap user with same username
166
155
167 log.debug("No matching LDAP objects for authentication "
156 log.debug("No matching LDAP objects for authentication "
168 "of '%s' (%s)", uid, username)
157 "of '%s'", username)
169 raise LdapPasswordError()
158 raise LdapPasswordError()
170
159
171 except ldap.NO_SUCH_OBJECT:
160 except ldap.NO_SUCH_OBJECT:
172 log.debug("LDAP says no such user '%s' (%s)", uid, username)
161 log.debug("LDAP says no such user '%s'", username)
173 raise LdapUsernameError()
162 raise LdapUsernameError()
174 except ldap.SERVER_DOWN:
163 except ldap.SERVER_DOWN:
175 # [0] might be {'info': "TLS error -8179:Peer's Certificate issuer is not recognized.", 'desc': "Can't contact LDAP server"}
164 # [0] might be {'info': "TLS error -8179:Peer's Certificate issuer is not recognized.", 'desc': "Can't contact LDAP server"}
@@ -198,11 +187,11 b' class KallitheaAuthPlugin(auth_modules.K'
198 },
187 },
199 {
188 {
200 "name": "port",
189 "name": "port",
201 "validator": self.validators.Number(strip=True, not_empty=True),
190 "validator": self.validators.Number(strip=True),
202 "type": "string",
191 "type": "string",
203 "description": "Port that the LDAP server is listening on",
192 "description": "Port that the LDAP server is listening on. Defaults to 389 for PLAIN/START_TLS and 636 for LDAPS.",
204 "default": 389,
193 "default": "",
205 "formname": "Port"
194 "formname": "Custom LDAP Port"
206 },
195 },
207 {
196 {
208 "name": "dn_user",
197 "name": "dn_user",
General Comments 0
You need to be logged in to leave comments. Login now