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.
 
 
 
 

180 line
6.1 KiB

  1. import re
  2. from functools import wraps
  3. from binascii import unhexlify
  4. from ldap3.protocol.formatters.formatters import format_sid
  5. import argparse
  6. import datetime
  7. import json
  8. import ldap3
  9. import logging
  10. import os
  11. import ssl
  12. import sys
  13. import hashlib
  14. import binascii
  15. import xml.dom.minidom
  16. from pathlib import Path # <-- corregge "import Path"
  17. __all__ = ['LDAP']
  18. def cast_to_dict(cid):
  19. out = {}
  20. for key, value in cid.items():
  21. if type(value) == bytes:
  22. out[key] = str(value)
  23. elif type(value) == list:
  24. if len(value) == 1:
  25. value = value[0]
  26. if type(value) == bytes:
  27. out[key] = str(value)
  28. elif type(value) == datetime.datetime:
  29. out[key] = value.strftime('%Y-%m-%d %H:%M:%S')
  30. elif type(value) == datetime.timedelta:
  31. out[key] = value.seconds
  32. else:
  33. out[key] = value
  34. else:
  35. newlist = []
  36. for element in value:
  37. if type(element) == bytes:
  38. newlist.append(str(element))
  39. elif type(element) == datetime.datetime:
  40. newlist.append(element.strftime('%Y-%m-%d %H:%M:%S'))
  41. elif type(element) == datetime.timedelta:
  42. newlist.append(element.seconds)
  43. out[key] = newlist
  44. elif type(value) == datetime.datetime:
  45. out[key] = value.strftime('%Y-%m-%d %H:%M:%S')
  46. elif type(value) == datetime.timedelta:
  47. out[key] = value.seconds
  48. else:
  49. out[key] = value
  50. return out
  51. def dict_get_paths(d):
  52. paths = []
  53. for key in d.keys():
  54. if type(d[key]) == dict:
  55. paths = [[key]+p for p in dict_get_paths(d[key])]
  56. else:
  57. paths.append([key])
  58. return paths
  59. def dict_path_access(d, path):
  60. for key in path:
  61. if key in d.keys():
  62. d = d[key]
  63. else:
  64. return None
  65. return d
  66. class LDAPConsole(object):
  67. """docstring for LDAPConsole."""
  68. def __init__(self, debug=True):
  69. super(LDAPConsole, self).__init__()
  70. self.ldap_server = None
  71. self.ldap_session = None
  72. self.tls_version = None
  73. self.delegate_from = None
  74. self.target_dn = None
  75. self.debug = debug
  76. self.host = None
  77. self.binddn = None
  78. self.bindpwd = None
  79. self.suffix = None
  80. # Carica il file XML di configurazione:
  81. # usa la variabile d'ambiente FASTAPI_CONFUR se presente,
  82. # altrimenti di default FastAPI/include/confur.xml relativo al progetto.
  83. base_dir = Path(__file__).resolve().parents[1] # /var/opt/FastAPI
  84. conf_path = os.getenv("FASTAPI_CONFUR", str(base_dir / "include" / "confur.xml"))
  85. doc = xml.dom.minidom.parse(conf_path)
  86. ssonode = doc.getElementsByTagName("sso")
  87. for skill in ssonode:
  88. self.binddn = self.getText(skill.getElementsByTagName("bind-dn")[0].childNodes)
  89. self.suffix = self.getText(skill.getElementsByTagName("suffix")[0].childNodes)
  90. self.host = self.getText(skill.getElementsByTagName("host")[0].childNodes)
  91. self.bindpwd = self.getText(skill.getElementsByTagName("bind-pwd")[0].childNodes)
  92. if self.debug:
  93. print(self.binddn + " " + self.suffix + " " + self.host + " " + self.bindpwd)
  94. self.init_ldap_connection()
  95. def getText(self, nodelist):
  96. rc = []
  97. for node in nodelist:
  98. if node.nodeType == node.TEXT_NODE:
  99. rc.append(node.data)
  100. return ''.join(rc)
  101. def init_ldap_connection(self):
  102. if self.tls_version is not None:
  103. use_ssl = True
  104. port = 636
  105. tls = ldap3.Tls(validate=ssl.CERT_NONE, version=self.tls_version)
  106. else:
  107. use_ssl = False
  108. port = 389
  109. tls = None
  110. self.ldap_server = ldap3.Server(self.host, get_info=ldap3.ALL, port=port, use_ssl=use_ssl, tls=tls)
  111. self.ldap_session = ldap3.Connection(self.ldap_server, self.binddn, self.bindpwd,
  112. authentication='SIMPLE', auto_bind=True)
  113. def queryallusers(self, subtree, attributes=['*']):
  114. results = {}
  115. try:
  116. if self.debug:
  117. print(subtree + ',' + self.suffix)
  118. self.ldap_session.search(subtree + ',' + self.suffix, '(&(uid=*))', attributes=attributes)
  119. for entry in self.ldap_session.response:
  120. if self.debug:
  121. print(entry)
  122. for entry in self.ldap_session.response:
  123. if entry['type'] != 'searchResEntry':
  124. continue
  125. results[entry['dn']] = entry["attributes"]
  126. except ldap3.core.exceptions.LDAPInvalidFilterError:
  127. print("Invalid Filter. (ldap3.core.exceptions.LDAPInvalidFilterError)")
  128. except Exception as e:
  129. raise e
  130. return results
  131. def doLdapGetUser(self, subtree, username):
  132. if self.debug:
  133. print(subtree + ',' + self.suffix)
  134. results = {'authen': 'none'}
  135. try:
  136. self.ldap_session.search(subtree + ',' + self.suffix, f'(&(uid={username}))', attributes=['ntPassword'])
  137. for entry in self.ldap_session.response:
  138. if self.debug:
  139. print("response present")
  140. if entry['type'] != 'searchResEntry':
  141. continue
  142. results['data'] = entry["attributes"]
  143. if entry['attributes'].get('ntPassword'):
  144. results['authen'] = "yeah"
  145. except ldap3.core.exceptions.LDAPInvalidFilterError:
  146. print("Invalid Filter. (ldap3.core.exceptions.LDAPInvalidFilterError)")
  147. except Exception as e:
  148. raise e
  149. return results
  150. def bytessize(data):
  151. l = len(data)
  152. units = ['B', 'kB', 'MB', 'GB', 'TB', 'PB']
  153. for k in range(len(units)):
  154. if l < (1024 ** (k + 1)):
  155. break
  156. return "%4.2f %s" % (round(l / (1024 ** k), 2), units[k])