diff --git a/README.md b/README.md index fe7fd39..1b25465 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ These are the options that can be specified in your .ini config file. | `ckanext.ldap.debug_level` | [python-ldap debug level](https://www.python-ldap.org/en/python-ldap-3.0.0b1/reference/ldap.html?highlight=debug_level#ldap.OPT_DEBUG_LEVEL). **Security warning**: it is strongly recommended to keep this parameter set to 0 (zero) on production systems, otherwise [plaintext passwords will be logged by `python-ldap`](https://github.com/python-ldap/python-ldap/issues/384) | 0-9 | 0 | | `ckanext.ldap.trace_level` | [python-ldap trace level](https://www.python-ldap.org/en/python-ldap-3.0.0b1/reference/ldap.html?highlight=trace_level#ldap.initialize). **Security warning**: it is strongly recommended to keep this parameter set to 0 (zero) on production systems, otherwise [plaintext passwords will be logged by `python-ldap`](https://github.com/python-ldap/python-ldap/issues/384) | 0-9 | 0 | | `ckanext.ldap.allow_password_reset` | If true, allows LDAP users to reset their passwords, if false, disallows this functionality. Note that if this is true, the password that is reset is the CKAN user password, not the LDAP one. If set to false, the request to reset will be denied only if the user is an LDAP user, if not they will be allowed to reset regardless of the value of this option. | True/False | true | - +| `ckanext.ldap.ignore_referrals` | If true, The plugin will ignore referral query results sent by the LDAP server. This might be necessary if your base_dn is at the domain level, but the LDAP server searches in multiple paths for the user, resulting in queries containing more than one result. | True/False | false | # Usage diff --git a/ckanext/ldap/lib/search.py b/ckanext/ldap/lib/search.py index 9968048..a6bffa6 100644 --- a/ckanext/ldap/lib/search.py +++ b/ckanext/ldap/lib/search.py @@ -25,6 +25,9 @@ def find_ldap_user(login): cnx = ldap.initialize(toolkit.config['ckanext.ldap.uri'], bytes_mode=False, trace_level=toolkit.config['ckanext.ldap.trace_level']) cnx.set_option(ldap.OPT_NETWORK_TIMEOUT, 10) + if toolkit.config['ckanext.ldap.ignore_referrals']: + cnx.set_option(ldap.OPT_REFERRALS, 0) + if toolkit.config.get('ckanext.ldap.auth.dn'): try: if toolkit.config['ckanext.ldap.auth.method'] == 'SIMPLE': @@ -92,6 +95,8 @@ def ldap_search(cnx, filter_str, attributes, non_unique='raise'): try: res = cnx.search_s(toolkit.config['ckanext.ldap.base_dn'], ldap.SCOPE_SUBTREE, filterstr=filter_str, attrlist=attributes) + if toolkit.config['ckanext.ldap.ignore_referrals']: + res = [ x for x in res if x[0] is not None ] except ldap.SERVER_DOWN: log.error('LDAP server is not reachable') return None diff --git a/ckanext/ldap/plugin.py b/ckanext/ldap/plugin.py index 561a116..b2c8558 100644 --- a/ckanext/ldap/plugin.py +++ b/ckanext/ldap/plugin.py @@ -104,6 +104,7 @@ def configure(self, config): 'ckanext.ldap.migrate': {'default': False, 'parse': toolkit.asbool}, 'ckanext.ldap.debug_level': {'default': 0, 'parse': toolkit.asint}, 'ckanext.ldap.trace_level': {'default': 0, 'parse': toolkit.asint}, + 'ckanext.ldap.ignore_referrals': {'default': False, 'parse': toolkit.asbool}, } errors = [] for key, options in schema.items():