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 |
|
223 | Plain unencrypted LDAP connection. | |
|
224 | This will by default use `Port`_ 389. | |||
224 |
|
225 | |||
225 |
LDAPS |
|
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= |
|
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' |
|
152 | log.debug("LDAP rejected password for user '%s': %s", | |
164 |
|
|
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' |
|
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' |
|
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 |
|
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": |
|
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