aboutsummaryrefslogtreecommitdiffstats
path: root/RepSys/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'RepSys/plugins')
-rw-r--r--RepSys/plugins/ldapusers.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py
new file mode 100644
index 0000000..aa3438e
--- /dev/null
+++ b/RepSys/plugins/ldapusers.py
@@ -0,0 +1,118 @@
+"""
+A Repsys plugin for obtaining users from a LDAP server.
+
+In order to enable the plugin, the user must define the following
+options in repsys.conf:
+
+ ldap-server [required]
+ the host name of the LDAP server
+ ldap-port [optional] [default: 389]
+ the port of the LDAP server
+ ldap-base [required]
+ the base DN where the search will be performed
+ ldap-binddn [optional] [default: empty]
+ the DN used to bind
+ ldap-bindpw [optional] [default: empty]
+ the password used to bind
+ ldap-filterformat [optional]
+ [default: (&(objectClass=inetOrgPerson)(uid=%s))]
+ RFC-2254 filter string used in the search of the user entry.
+ Note that this is a python format string and will have the user
+ name as parameter. For example:
+
+ ldap-filterformat = (&(objectClass=inetOrgPerson)(uid=%s))
+
+ Will result in the search filter:
+
+ (&(objectClass=inetOrgPerson)(uid=john))
+
+ ldap-format [optional] [default: %(cn)s <%(mail)s>]
+ This is a python format string. This string will be
+ formatted using one dict object containing the fields
+ returned in the LDAP search, for example:
+
+ >>> format = "%(cn)s <%(mail)s>"
+ >>> d = search(basedn, filter)
+ >>> d = {"cn": "John Doe", "mail": "john@mandriva.org",
+ "uidNumber": "1290", "loginShell": "/bin/bash",
+ ... many other attributes ... }
+ >>> value = format % d
+ >>> print value
+ John Doe <john@mandriva.org>
+
+ Note that only the first value of the attributes will be
+ used.
+
+When the searched option is not found, it will try in repsys.conf. All
+the values found. (including from repsys.conf) will be cached between
+each configuration acess.
+
+This plugin requires the package python-ldap.
+
+For more information, look http://qa.mandriva.com/show_bug.cgi?id=30549
+"""
+from RepSys import Error, config
+
+users_cache = {}
+
+def strip_entry(entry):
+ "Leave only the first value in all keys in the entry"
+ new = dict((key, value[0]) for key, value in entry.iteritems())
+ return new
+
+
+def make_handler():
+ server = config.get("global", "ldap-server")
+ port = config.get("global", "ldap-port")
+ basedn = config.get("global", "ldap-base")
+ binddn = config.get("global", "ldap-binddn")
+ bindpw = config.get("global", "ldap-bindpw", "")
+ filterformat = config.get("global", "ldap-filterformat",
+ "(&(objectClass=inetOrgPerson)(uid=%s))", raw=1)
+ format = config.get("global", "ldap-format", "%(cn)s <%(mail)s>", raw=1)
+
+ if server is None:
+ def dummy_wrapper(section, option=None, default=None, walk=False):
+ return config.get(section, option, default, wrap=False)
+ return dummy_wrapper
+
+ # only load ldap if it is enabled in configuration, this way we don't
+ # require everyone to have python-ldap installed
+ import ldap
+
+ def users_wrapper(section, option=None, default=None, walk=False):
+ global users_cache
+ if walk:
+ raise Error, "ldapusers plugin does not support user listing"
+ assert option is not None, \
+ "When not section walking, option is required"
+
+ value = users_cache.get(option)
+ if value is not None:
+ return value
+
+ l = ldap.open(server)
+ if binddn:
+ l.bind(binddn, bindpw)
+ filter = filterformat % option
+ found = l.search_s(basedn, ldap.SCOPE_SUBTREE, filter)
+ if found:
+ dn, entry = found[0]
+ entry = strip_entry(entry)
+ try:
+ value = format % entry
+ except KeyError, e:
+ raise Error, "the key %s was not found in LDAP search, " \
+ "check your ldap-format configuration" % e
+ except (TypeError, ValueError), e:
+ raise Error, "LDAP response formatting error: %s. Check " \
+ "your ldap-format configuration" % e
+ else:
+ # issue a warning?
+ value = config.get(section, option, default, wrap=False)
+ users_cache[option] = value
+ return value
+
+ return users_wrapper
+
+config.wrap("users", handler=make_handler())