"""
"""
# 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