""" """ # Created on 2014.09.08 # # Author: Giovanni Cannata # # Copyright 2014 - 2018 Giovanni Cannata # # This file is part of ldap3. # # ldap3 is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # ldap3 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with ldap3 in the COPYING and COPYING.LESSER files. # If not, see . try: from urllib.parse import unquote # Python3 except ImportError: from urllib import unquote # Python 2 from .. import SUBTREE, BASE, LEVEL def parse_uri(uri): """ Decode LDAP URI as specified in RFC 4516 relaxing specifications permitting 'ldaps' as scheme for ssl-ldap """ # ldapurl = scheme COLON SLASH SLASH [host [COLON port]] # [SLASH dn [QUESTION [attributes] # [QUESTION [scope] [QUESTION [filter] # [QUESTION extensions]]]]] # ; and are defined # ; in Sections 3.2.2 and 3.2.3 # ; of [RFC3986]. # ; is from Section 3 of # ; [RFC4515], subject to the # ; provisions of the # ; "Percent-Encoding" section # ; below. # # scheme = "ldap" / "ldaps" <== not RFC4516 compliant (original is 'scheme = "ldap"') # dn = distinguishedName ; From Section 3 of [RFC4514], # ; subject to the provisions of # ; the "Percent-Encoding" # ; section below. # # attributes = attrdesc *(COMMA attrdesc) # attrdesc = selector *(COMMA selector) # selector = attributeSelector ; From Section 4.5.1 of # ; [RFC4511], subject to the # ; provisions of the # ; "Percent-Encoding" section # ; below. # # scope = "base" / "one" / "sub" # extensions = extension *(COMMA extension) # extension = [EXCLAMATION] extype [EQUALS exvalue] # extype = oid ; From section 1.4 of [RFC4512]. # # exvalue = LDAPString ; From section 4.1.2 of # ; [RFC4511], subject to the # ; provisions of the # ; "Percent-Encoding" section # ; below. # # EXCLAMATION = %x21 ; exclamation mark ("!") # SLASH = %x2F ; forward slash ("/") # COLON = %x3A ; colon (":") # QUESTION = %x3F ; question mark ("?") uri_components = dict() parts = unquote(uri).split('?') # encoding defaults to utf-8 in Python 3 scheme, sep, remain = parts[0].partition('://') if sep != '://' or scheme not in ['ldap', 'ldaps']: return None address, _, uri_components['base'] = remain.partition('/') uri_components['ssl'] = True if scheme == 'ldaps' else False uri_components['host'], sep, uri_components['port'] = address.partition(':') if sep != ':': if uri_components['ssl']: uri_components['port'] = 636 else: uri_components['port'] = None else: if not uri_components['port'].isdigit() or not (0 < int(uri_components['port']) < 65536): return None else: uri_components['port'] = int(uri_components['port']) uri_components['attributes'] = parts[1].split(',') if len(parts) > 1 else None uri_components['scope'] = parts[2] if len(parts) > 2 else None if uri_components['scope'] == 'base': uri_components['scope'] = BASE elif uri_components['scope'] == 'sub': uri_components['scope'] = SUBTREE elif uri_components['scope'] == 'one': uri_components['scope'] = LEVEL elif uri_components['scope']: return None uri_components['filter'] = parts[3] if len(parts) > 3 else None uri_components['extensions'] = parts[4].split(',') if len(parts) > 4 else None return uri_components