Advertisement
Krakozaber

Untitled

Jan 20th, 2016
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.57 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. ##----------------------------------------------------------------------
  3. ## LDAP Authentication backend
  4. ##----------------------------------------------------------------------
  5. ## Copyright (C) 2007-2011 The NOC Project
  6. ## See LICENSE for details
  7. ##----------------------------------------------------------------------
  8.  
  9. ## Python modules
  10. import settings
  11. import logging
  12. import types
  13. ## Django modules
  14. from django.template import Context, Template
  15. ## Third-party modules
  16. try:
  17. import ldap
  18. except ImportError:
  19. pass
  20. ## NOC modules
  21. from base import NOCAuthBackend
  22. from noc.settings import config
  23.  
  24.  
  25. class NOCLDAPBackend(NOCAuthBackend):
  26. """
  27. LDAP Authentication backend
  28. """
  29. def __init__(self):
  30. super(NOCLDAPBackend, self).__init__()
  31. self.server = config.get("authentication", "ldap_server")
  32. self.bind_method = config.get("authentication", "ldap_bind_method")
  33. self.bind_dn = config.get("authentication", "ldap_bind_dn")
  34. self.bind_password = config.get("authentication", "ldap_bind_password")
  35. self.users_base = config.get("authentication", "ldap_users_base")
  36. self.users_filter = config.get("authentication", "ldap_users_filter")
  37. self.required_group = config.get("authentication",
  38. "ldap_required_group")
  39. self.requred_filter = config.get("authentication",
  40. "ldap_required_filter")
  41. self.superuser_group = config.get("authentication",
  42. "ldap_superuser_group")
  43. self.superuser_filter = config.get("authentication",
  44. "ldap_superuser_filter")
  45. self.start_tls = config.getboolean("authentication",
  46. "ldap_start_tls")
  47.  
  48. def q(self, s):
  49. """
  50. LDAP quoting according to RFC2254
  51. """
  52. for c in "\*()\x00":
  53. s = s.replace(c, r"\%02x" % ord(c))
  54. return s
  55.  
  56. def search_to_unicode(self, attrs):
  57. """
  58. Convert search attributes to unicode
  59. """
  60. a = {}
  61. for k, v in attrs.items():
  62. if type(v) == types.ListType:
  63. v = v[0]
  64. a[k] = unicode(v, "utf-8")
  65. return a
  66.  
  67. def expand_template(self, template, context):
  68. """
  69. Expand template with context
  70. """
  71. r = Template(template).render(Context(context))
  72. logging.debug("LDAP: Expanding template: '%s' -> '%s'" % (template, r))
  73. return r
  74.  
  75. def ldap_bind(self, client, username=None, password=None):
  76. """
  77. Bind client (simple mode)
  78. """
  79. if username is None and password is None:
  80. # Anonymous bind
  81. logging.debug("LDAP anonymous bind")
  82. client.simple_bind_s()
  83. else:
  84. # Bind according to bind methods
  85. if self.bind_method == "simple":
  86. logging.debug("LDAP simple bind to %s" % username)
  87. client.simple_bind_s(username, password)
  88. else:
  89. logging.error("Invalid ldap bind method: '%s'" % self.bind_method)
  90. raise ValueError("Invalid ldap bind method: '%s'" % self.bind_method)
  91.  
  92. def authenticate(self, username=None, password=None, **kwargs):
  93. """
  94. Authenticate user against user and password
  95. """
  96. logging.debug("LDAP authenticatation: username=%s" % username)
  97. is_active = True # User activity flag
  98. is_superuser = False # Superuser flag
  99. # Prepare template context
  100. context = {
  101. "username": self.q(username),
  102. "user": self.q(username)
  103. }
  104. if "@" in username:
  105. u, d = username.split("@", 1)
  106. context["user"] = self.q(u)
  107. context["domain"] = self.q(d)
  108. context["domain_parts"] = [self.q(p) for p in d.split(".")]
  109. try:
  110. # Prepare LDAP client
  111. client = ldap.initialize(self.server)
  112. if self.start_tls:
  113. client.start_tls_s()
  114. # Bind anonymously or with technical user to resolve username
  115. self.ldap_bind(client,
  116. self.bind_dn if self.bind_dn else None,
  117. self.bind_password if self.bind_password else None
  118. )
  119. # Search for user
  120. base = self.expand_template(self.users_base, context)
  121. filter = self.expand_template(self.users_filter, context)
  122. logging.debug("LDAP Search: filter: %s, base: %s" % (filter, base))
  123. ul = client.search_s(base, ldap.SCOPE_SUBTREE, filter,
  124. ["sn", "givenname", "mail"])
  125. if len(ul) == 0:
  126. # No user found
  127. try:
  128. user = self.User.objects.get(username=username)
  129. if user.check_password(password):
  130. return user
  131. except self.User.DoesNotExist:
  132. pass
  133. logging.error("LDAP user lookup error. User '%s' is not found" % username)
  134. return None
  135. if len(ul) > 1:
  136. # Mistake in LDAP schema
  137. logging.error("LDAP schema error. More than one user returned for '%s'" % username)
  138. return None
  139. dn, attrs = ul[0]
  140. logging.debug("LDAP search returned: %s, %s" % (str(dn), str(attrs)))
  141. # Populate context with DN
  142. context["dn"] = dn
  143. # Try to authenticate
  144. client = ldap.initialize(self.server)
  145. if self.start_tls:
  146. client.start_tls_s()
  147. self.ldap_bind(client, dn, password)
  148. # Check user is in required group
  149. if self.required_group:
  150. base = self.expand_template(self.required_group, context)
  151. filter = self.expand_template(self.requred_filter, context)
  152. logging.debug("LDAP checking user '%s' in group '%s'. filter: %s" % (dn, base, filter))
  153. ug = client.search_s(base, ldap.SCOPE_BASE, filter, [])
  154. is_active = len(ug) > 0
  155. if not is_active:
  156. logging.debug("Disabling user '%s'" % username)
  157. # Check user is superuser
  158. if self.superuser_group:
  159. base = self.expand_template(self.superuser_group, context)
  160. filter = self.expand_template(self.superuser_filter, context)
  161. logging.debug("LDAP checking user '%s' in group '%s'. filter: %s" % (dn, base, filter))
  162. ug = client.search_s(base, ldap.SCOPE_BASE, filter, [])
  163. is_superuser = len(ug) > 0
  164. if is_superuser:
  165. logging.debug("Granting superuser access to '%s'" % username)
  166. except ldap.LDAPError, why:
  167. logging.error("LDAP Error: %s" % str(why))
  168. return None
  169. logging.debug("LDAP user '%s' authenticated. User is %s" % (username,
  170. {True: "active", False: "disabled"}[is_active]))
  171. attrs = self.search_to_unicode(attrs)
  172. # Successfull bind
  173. user = self.get_or_create_db_user(username=username,
  174. is_active=is_active,
  175. is_superuser=is_superuser,
  176. first_name=attrs.get("givenName"),
  177. last_name=attrs.get("sn"),
  178. email=attrs.get("mail"))
  179. # Authentication passed
  180. return user
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement