Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

bug 566468 - ldap_lookup management command, r=Pike

  • Loading branch information...
commit 9bf4552c7d5479f4eb6c8ffd31d0d985f52afcec 1 parent 1731024
@peterbe authored
View
0  apps/elmo_commons/management/__init__.py
No changes.
View
0  apps/elmo_commons/management/commands/__init__.py
No changes.
View
118 apps/elmo_commons/management/commands/ldap_lookup.py
@@ -0,0 +1,118 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+'''Tool for doing local LDAP lookups
+'''
+
+
+from optparse import make_option
+
+from django.contrib.auth.models import User
+from django.core.management.base import BaseCommand
+from lib.auth.backends import MozLdapBackend, GROUP_MAPPINGS
+import ldap
+
+LDAP_IGNORE_ATTRIBUTES = (
+ 'uidNumber',
+ 'rid',
+ 'fakeHome',
+ 'svnShell',
+ 'loginShell',
+ 'hgShell',
+ 'gidNumber',
+ 'homeDirectory'
+)
+
+
+class Command(BaseCommand):
+ option_list = BaseCommand.option_list + (
+ make_option('-q', '--quiet', dest='quiet', action='store_true',
+ help='Run quietly'),
+ )
+ help = 'Look up users in LDAP'
+ args = 'mailaddress'
+
+ def handle(self, *args, **options):
+ mail = args[0]
+
+ def show(key, value):
+ if (isinstance(value, list) and value
+ and isinstance(value[0], basestring)):
+ value = ', '.join(value)
+ print key.ljust(20), value
+
+ print "\nLOCAL USER ".ljust(79, '-')
+ try:
+ user = User.objects.get(email=mail)
+ show("Username", user.username)
+ show("Email", user.email)
+ show("First name", user.first_name)
+ show("Last name", user.last_name)
+ show("Active", user.is_active)
+ show("Superuser", user.is_superuser)
+ show("Staff", user.is_staff)
+ print "Groups:".ljust(20),
+ if user.groups.all():
+ print ', '.join([x.name for x in user.groups.all()])
+ else:
+ print "none"
+
+ except User.DoesNotExist:
+ print "Does NOT exist locally"
+
+ backend = MozLdapBackend()
+ backend.connect()
+ try:
+ search_filter = backend.make_search_filter(dict(mail=mail))
+
+ results = backend.ldo.search_s(
+ "dc=mozilla",
+ ldap.SCOPE_SUBTREE,
+ search_filter,
+ )
+
+ print "\nIN LDAP ".ljust(79, '-')
+ uid = None
+ for uid, data in results:
+ for key, value in data.iteritems():
+ if key in LDAP_IGNORE_ATTRIBUTES:
+ continue
+ show(key, value)
+
+ if uid:
+ group_names = GROUP_MAPPINGS.values()
+ search_filter1 = backend.make_search_filter(
+ dict(cn=group_names),
+ any_parameter=True
+ )
+ search_filter2 = backend.make_search_filter({
+ 'memberUID': [uid, mail],
+ 'member': ['mail=%s,o=com,dc=mozilla' % mail,
+ 'mail=%s,o=org,dc=mozilla' % mail,
+ 'mail=%s,o=net,dc=mozillacom' % mail],
+ }, any_parameter=True)
+ # combine the group part with the mail part
+ search_filter = '(&%s%s)' % (search_filter1, search_filter2)
+
+ group_results = backend.ldo.search_s(
+ "ou=groups,dc=mozilla",
+ ldap.SCOPE_SUBTREE,
+ search_filter,
+ ['cn']
+ )
+ print "\nLDAP GROUPS ".ljust(79, '-')
+ _group_mappings_reverse = dict(
+ (b, a) for (a, b) in
+ GROUP_MAPPINGS.items()
+ )
+ groups = [x[1]['cn'][0] for x in group_results]
+ for group in groups:
+ print group.ljust(16), '-> ',
+ print _group_mappings_reverse.get(
+ group,
+ '*not a Django group*'
+ )
+
+ finally:
+ backend.disconnect()
View
25 lib/auth/backends.py
@@ -40,6 +40,8 @@ def __init__(self):
self.password = settings.LDAP_PASSWORD
self.localizers = None
+ self.ldo = None
+
#
# This is the path we take here:
# *) Try to find the user locally
@@ -85,17 +87,27 @@ def make_search_filter(data, any_parameter=False):
search_filter = '(&%s)' % search_filter
return search_filter
- def _authenticate_ldap(self, mail, password, user=None):
+ def initialize(self):
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self.certfile)
self.ldo = ldap.initialize(self.host)
self.ldo.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
- # first, figure out the uid
- search_filter = self.make_search_filter(dict(mail=mail))
+ def connect(self):
+ self.initialize()
# open a connection using the bind user
self.ldo.simple_bind_s(self.dn, self.password)
+
+ def disconnect(self):
+ self.ldo.unbind_s()
+
+ def _authenticate_ldap(self, mail, password, user=None):
+ self.connect()
+
+ # first, figure out the uid
+ search_filter = self.make_search_filter(dict(mail=mail))
+
try:
# get the uid (first and foremost) but also pick up the other
# essential attributes which we'll need later on.
@@ -141,18 +153,19 @@ def _authenticate_ldap(self, mail, password, user=None):
for names in each.values():
groups.extend(names)
finally:
- self.ldo.unbind_s()
+ self.disconnect()
# Now we know everything we need to know about the user but lastly we
# need to check if their password is correct
- self.ldo = ldap.initialize(self.host)
- self.ldo.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
+ self.initialize()
try:
self.ldo.simple_bind_s(uid, password)
except ldap.INVALID_CREDENTIALS: # Bad password, credentials are bad.
return
except ldap.UNWILLING_TO_PERFORM: # Bad password, credentials are bad.
return
+ else:
+ self.ldo.unbind_s()
first_name = result['givenName'][0]
last_name = result['sn'][0]
Please sign in to comment.
Something went wrong with that request. Please try again.