This patch adds support for:
-LDAP referrals, or the disabling thereof
-Multiple baseDNs
To support this an option needs to be added to /etc/cobbler/settings:
ldap_referrals: 0 (or 1)
So for instance if you have an Active Directory environment with multiple
domains or forests, you might want:
ldap_referrals: 0
I chased this down because I kept getting the following error, even though I
knew my bindDN was correct:
OPERATIONS_ERROR: {'info': '00000000: LdapErr: DSID-0C090627, comment:
In order to perform this operation a successful bind must be completed
on the connection., data 0, vece', 'desc': 'Operations error'}
>From some googling I believe this is only really relevant for Active
Directory environments.
I also added support for multiple baseDNs, in case you have inherited an
insane LDAP hierarchy. These can be separated by semicolons:
ldap_base_dn:
'ou=London,ou=UK,dc=example,dc=com;ou=Austin,ou=US,dc=example,dc=com;'
As an aside this is the first time I've ever written anything in Python so I
apologize if the code is crap. :)
--PG
diff -u authn_ldap.py authn_ldap2.py
--- authn_ldap.py 2009-12-21 15:59:33.000000000 -0600
+++ authn_ldap2.py 2009-12-22 08:59:04.000000000 -0600
@@ -57,6 +57,7 @@
tls = api_handle.settings().ldap_tls
anon_bind = api_handle.settings().ldap_anonymous_bind
prefix = api_handle.settings().ldap_search_prefix
+ referrals = api_handle.settings().ldap_referrals
# allow multiple servers split by a space
if server.find(" "):
@@ -80,6 +81,15 @@
# connect to LDAP host
dir = ldap.initialize(uri)
+ # turn off LDAP referrals if referrals is 'off', 'false', or 'no'
+ referrals = str(referrals).lower()
+ if referrals in ["off", "false", "no", "0" ]:
+ try:
+ dir.set_option(ldap.OPT_REFERRALS, 0)
+ except:
+ traceback.print_exc()
+ return False
+
# start_tls if tls is 'on', 'true' or 'yes'
# and we're not already using old-SSL
tls = str(tls).lower()
@@ -110,27 +120,33 @@
# perform a subtree search in basedn to find the full dn of the user
# TODO: what if username is a CN? maybe it goes into the config file
as well?
filter = prefix + username
- result = dir.search_s(basedn, ldap.SCOPE_SUBTREE, filter, [])
- if result:
- for dn,entry in result:
- # username _should_ be unique so we should only have one result
- # ignore entry; we don't need it
- pass
- else:
- return False
- try:
- # attempt to bind as the user
- dir.simple_bind_s(dn,password)
- dir.unbind()
- return True
- except:
- # traceback.print_exc()
- return False
+ # allow multiple base DNs for more complex LDAP environments
+ # this splits on a semicolon
+ if basedn.find(";"):
+ basedns = basedn.split(";")
+ else:
+ basedns = [basedn]
+
+ result = None
+ for basedn in basedns:
+ result = dir.search_s(basedn, ldap.SCOPE_SUBTREE, filter, [])
+ if result:
+ for dn,entry in result:
+ # username _should_ be unique so we should only have one
result
+ # ignore entry; we don't need it
+ pass
+ try:
+ # attempt to bind as the user
+ dir.simple_bind_s(dn,password)
+ dir.unbind()
+ return True
+ except:
+ # traceback.print_exc()
+ return False
# catch-all
return False
if __name__ == "__main__":
api_handle = cobbler_api.BootAPI()
print authenticate(api_handle, "guest", "guest")
-