Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dn.py 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. """
  2. dn.py - misc stuff for handling distinguished names (see RFC 4514)
  3. See https://www.python-ldap.org/ for details.
  4. """
  5. import sys
  6. from ldap.pkginfo import __version__
  7. import _ldap
  8. assert _ldap.__version__==__version__, \
  9. ImportError('ldap %s and _ldap %s version mismatch!' % (__version__,_ldap.__version__))
  10. import ldap.functions
  11. def escape_dn_chars(s):
  12. """
  13. Escape all DN special characters found in s
  14. with a back-slash (see RFC 4514, section 2.4)
  15. """
  16. if s:
  17. s = s.replace('\\','\\\\')
  18. s = s.replace(',' ,'\\,')
  19. s = s.replace('+' ,'\\+')
  20. s = s.replace('"' ,'\\"')
  21. s = s.replace('<' ,'\\<')
  22. s = s.replace('>' ,'\\>')
  23. s = s.replace(';' ,'\\;')
  24. s = s.replace('=' ,'\\=')
  25. s = s.replace('\000' ,'\\\000')
  26. if s[0]=='#' or s[0]==' ':
  27. s = ''.join(('\\',s))
  28. if s[-1]==' ':
  29. s = ''.join((s[:-1],'\\ '))
  30. return s
  31. def str2dn(dn,flags=0):
  32. """
  33. This function takes a DN as string as parameter and returns
  34. a decomposed DN. It's the inverse to dn2str().
  35. flags describes the format of the dn
  36. See also the OpenLDAP man-page ldap_str2dn(3)
  37. """
  38. if not dn:
  39. return []
  40. if sys.version_info[0] < 3 and isinstance(dn, unicode):
  41. dn = dn.encode('utf-8')
  42. return ldap.functions._ldap_function_call(None,_ldap.str2dn,dn,flags)
  43. def dn2str(dn):
  44. """
  45. This function takes a decomposed DN as parameter and returns
  46. a single string. It's the inverse to str2dn() but will always
  47. return a DN in LDAPv3 format compliant to RFC 4514.
  48. """
  49. return ','.join([
  50. '+'.join([
  51. '='.join((atype,escape_dn_chars(avalue or '')))
  52. for atype,avalue,dummy in rdn])
  53. for rdn in dn
  54. ])
  55. def explode_dn(dn, notypes=False, flags=0):
  56. """
  57. explode_dn(dn [, notypes=False [, flags=0]]) -> list
  58. This function takes a DN and breaks it up into its component parts.
  59. The notypes parameter is used to specify that only the component's
  60. attribute values be returned and not the attribute types.
  61. """
  62. if not dn:
  63. return []
  64. dn_decomp = str2dn(dn,flags)
  65. rdn_list = []
  66. for rdn in dn_decomp:
  67. if notypes:
  68. rdn_list.append('+'.join([
  69. escape_dn_chars(avalue or '')
  70. for atype,avalue,dummy in rdn
  71. ]))
  72. else:
  73. rdn_list.append('+'.join([
  74. '='.join((atype,escape_dn_chars(avalue or '')))
  75. for atype,avalue,dummy in rdn
  76. ]))
  77. return rdn_list
  78. def explode_rdn(rdn, notypes=False, flags=0):
  79. """
  80. explode_rdn(rdn [, notypes=0 [, flags=0]]) -> list
  81. This function takes a RDN and breaks it up into its component parts
  82. if it is a multi-valued RDN.
  83. The notypes parameter is used to specify that only the component's
  84. attribute values be returned and not the attribute types.
  85. """
  86. if not rdn:
  87. return []
  88. rdn_decomp = str2dn(rdn,flags)[0]
  89. if notypes:
  90. return [avalue or '' for atype,avalue,dummy in rdn_decomp]
  91. else:
  92. return ['='.join((atype,escape_dn_chars(avalue or ''))) for atype,avalue,dummy in rdn_decomp]
  93. def is_dn(s,flags=0):
  94. """
  95. Returns True is `s' can be parsed by ldap.dn.str2dn() like as a
  96. distinguished host_name (DN), otherwise False is returned.
  97. """
  98. try:
  99. str2dn(s,flags)
  100. except Exception:
  101. return False
  102. else:
  103. return True