123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- """
- dn.py - misc stuff for handling distinguished names (see RFC 4514)
-
- See https://www.python-ldap.org/ for details.
- """
-
- import sys
- from ldap.pkginfo import __version__
-
- import _ldap
- assert _ldap.__version__==__version__, \
- ImportError('ldap %s and _ldap %s version mismatch!' % (__version__,_ldap.__version__))
-
- import ldap.functions
-
-
- def escape_dn_chars(s):
- """
- Escape all DN special characters found in s
- with a back-slash (see RFC 4514, section 2.4)
- """
- if s:
- s = s.replace('\\','\\\\')
- s = s.replace(',' ,'\\,')
- s = s.replace('+' ,'\\+')
- s = s.replace('"' ,'\\"')
- s = s.replace('<' ,'\\<')
- s = s.replace('>' ,'\\>')
- s = s.replace(';' ,'\\;')
- s = s.replace('=' ,'\\=')
- s = s.replace('\000' ,'\\\000')
- if s[0]=='#' or s[0]==' ':
- s = ''.join(('\\',s))
- if s[-1]==' ':
- s = ''.join((s[:-1],'\\ '))
- return s
-
-
- def str2dn(dn,flags=0):
- """
- This function takes a DN as string as parameter and returns
- a decomposed DN. It's the inverse to dn2str().
-
- flags describes the format of the dn
-
- See also the OpenLDAP man-page ldap_str2dn(3)
- """
- if not dn:
- return []
- if sys.version_info[0] < 3 and isinstance(dn, unicode):
- dn = dn.encode('utf-8')
- return ldap.functions._ldap_function_call(None,_ldap.str2dn,dn,flags)
-
-
- def dn2str(dn):
- """
- This function takes a decomposed DN as parameter and returns
- a single string. It's the inverse to str2dn() but will always
- return a DN in LDAPv3 format compliant to RFC 4514.
- """
- return ','.join([
- '+'.join([
- '='.join((atype,escape_dn_chars(avalue or '')))
- for atype,avalue,dummy in rdn])
- for rdn in dn
- ])
-
- def explode_dn(dn, notypes=False, flags=0):
- """
- explode_dn(dn [, notypes=False [, flags=0]]) -> list
-
- This function takes a DN and breaks it up into its component parts.
- The notypes parameter is used to specify that only the component's
- attribute values be returned and not the attribute types.
- """
- if not dn:
- return []
- dn_decomp = str2dn(dn,flags)
- rdn_list = []
- for rdn in dn_decomp:
- if notypes:
- rdn_list.append('+'.join([
- escape_dn_chars(avalue or '')
- for atype,avalue,dummy in rdn
- ]))
- else:
- rdn_list.append('+'.join([
- '='.join((atype,escape_dn_chars(avalue or '')))
- for atype,avalue,dummy in rdn
- ]))
- return rdn_list
-
-
- def explode_rdn(rdn, notypes=False, flags=0):
- """
- explode_rdn(rdn [, notypes=0 [, flags=0]]) -> list
-
- This function takes a RDN and breaks it up into its component parts
- if it is a multi-valued RDN.
- The notypes parameter is used to specify that only the component's
- attribute values be returned and not the attribute types.
- """
- if not rdn:
- return []
- rdn_decomp = str2dn(rdn,flags)[0]
- if notypes:
- return [avalue or '' for atype,avalue,dummy in rdn_decomp]
- else:
- return ['='.join((atype,escape_dn_chars(avalue or ''))) for atype,avalue,dummy in rdn_decomp]
-
-
- def is_dn(s,flags=0):
- """
- Returns True is `s' can be parsed by ldap.dn.str2dn() like as a
- distinguished host_name (DN), otherwise False is returned.
- """
- try:
- str2dn(s,flags)
- except Exception:
- return False
- else:
- return True
|