codekingpro/portable-devtools
114k
1"""2"""3 4# Created on 2014.09.085#6# Author: Giovanni Cannata7#8# Copyright 2014 - 2020 Giovanni Cannata9#10# This file is part of ldap3.11#12# ldap3 is free software: you can redistribute it and/or modify13# it under the terms of the GNU Lesser General Public License as published14# by the Free Software Foundation, either version 3 of the License, or15# (at your option) any later version.16#17# ldap3 is distributed in the hope that it will be useful,18# but WITHOUT ANY WARRANTY; without even the implied warranty of19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the20# GNU Lesser General Public License for more details.21#22# You should have received a copy of the GNU Lesser General Public License23# along with ldap3 in the COPYING and COPYING.LESSER files.24# If not, see <http://www.gnu.org/licenses/>.25 26try:27 from urllib.parse import unquote # Python328except ImportError:29 from urllib import unquote # Python 230 31from .. import SUBTREE, BASE, LEVEL32 33 34def parse_uri(uri):35 """36 Decode LDAP URI as specified in RFC 4516 relaxing specifications37 permitting 'ldaps' as scheme for ssl-ldap38 """39 40 # ldapurl = scheme COLON SLASH SLASH [host [COLON port]]41 # [SLASH dn [QUESTION [attributes]42 # [QUESTION [scope] [QUESTION [filter]43 # [QUESTION extensions]]]]]44 # ; <host> and <port> are defined45 # ; in Sections 3.2.2 and 3.2.346 # ; of [RFC3986].47 # ; <filter> is from Section 3 of48 # ; [RFC4515], subject to the49 # ; provisions of the50 # ; "Percent-Encoding" section51 # ; below.52 #53 # scheme = "ldap" / "ldaps" <== not RFC4516 compliant (original is 'scheme = "ldap"')54 # dn = distinguishedName ; From Section 3 of [RFC4514],55 # ; subject to the provisions of56 # ; the "Percent-Encoding"57 # ; section below.58 #59 # attributes = attrdesc *(COMMA attrdesc)60 # attrdesc = selector *(COMMA selector)61 # selector = attributeSelector ; From Section 4.5.1 of62 # ; [RFC4511], subject to the63 # ; provisions of the64 # ; "Percent-Encoding" section65 # ; below.66 #67 # scope = "base" / "one" / "sub"68 # extensions = extension *(COMMA extension)69 # extension = [EXCLAMATION] extype [EQUALS exvalue]70 # extype = oid ; From section 1.4 of [RFC4512].71 #72 # exvalue = LDAPString ; From section 4.1.2 of73 # ; [RFC4511], subject to the74 # ; provisions of the75 # ; "Percent-Encoding" section76 # ; below.77 #78 # EXCLAMATION = %x21 ; exclamation mark ("!")79 # SLASH = %x2F ; forward slash ("/")80 # COLON = %x3A ; colon (":")81 # QUESTION = %x3F ; question mark ("?")82 83 uri_components = dict()84 parts = unquote(uri).split('?') # encoding defaults to utf-8 in Python 385 scheme, sep, remain = parts[0].partition('://')86 if sep != '://' or scheme not in ['ldap', 'ldaps']:87 return None88 89 address, _, uri_components['base'] = remain.partition('/')90 91 uri_components['ssl'] = True if scheme == 'ldaps' else False92 uri_components['host'], sep, uri_components['port'] = address.partition(':')93 if sep != ':':94 if uri_components['ssl']:95 uri_components['port'] = 63696 else:97 uri_components['port'] = None98 else:99 if not uri_components['port'].isdigit() or not (0 < int(uri_components['port']) < 65536):100 return None101 else:102 uri_components['port'] = int(uri_components['port'])103 104 uri_components['attributes'] = parts[1].split(',') if len(parts) > 1 and parts[1] else None105 uri_components['scope'] = parts[2] if len(parts) > 2 else None106 if uri_components['scope'] == 'base':107 uri_components['scope'] = BASE108 elif uri_components['scope'] == 'sub':109 uri_components['scope'] = SUBTREE110 elif uri_components['scope'] == 'one':111 uri_components['scope'] = LEVEL112 elif uri_components['scope']:113 return None114 115 uri_components['filter'] = parts[3] if len(parts) > 3 else None116 uri_components['extensions'] = parts[4].split(',') if len(parts) > 4 else None117 118 return uri_components119 