172 lines
6.5 KiB
Python
172 lines
6.5 KiB
Python
#!/usr/bin/env python
|
||
"""
|
||
Скрипт для проверки записи пользователя в LDAP
|
||
"""
|
||
import sys
|
||
from ldap3 import Server, Connection, ALL, SUBTREE, Tls
|
||
import ssl
|
||
|
||
# Данные для подключения из .env (закомментированные строки)
|
||
LDAP_URI = "ldaps://DCII.robotail.local:636"
|
||
LDAP_BIND_DN = "corp@robotail.local"
|
||
LDAP_BIND_PASSWORD = "xZ25379565"
|
||
LDAP_BASE_DN = "DC=robotail,DC=local"
|
||
LDAP_USERS_BASE = "OU=Users,OU=company,DC=robotail,DC=local"
|
||
LDAP_CA_CERT = "C:\\ca\\corp-ca.pem"
|
||
|
||
# Email пользователя для поиска
|
||
USER_EMAIL = "nadein-igor-vladimirovich@05-04-1999.ru"
|
||
|
||
def main():
|
||
print(f"=" * 80)
|
||
print(f"Подключение к LDAP: {LDAP_URI}")
|
||
print(f"Bind DN: {LDAP_BIND_DN}")
|
||
print(f"=" * 80)
|
||
|
||
try:
|
||
# Настройка TLS
|
||
tls = Tls(
|
||
ca_certs_file=LDAP_CA_CERT,
|
||
validate=ssl.CERT_REQUIRED
|
||
)
|
||
|
||
# Подключение к серверу
|
||
server = Server(
|
||
"DCII.robotail.local",
|
||
port=636,
|
||
use_ssl=True,
|
||
tls=tls,
|
||
get_info=ALL
|
||
)
|
||
|
||
conn = Connection(
|
||
server,
|
||
user=LDAP_BIND_DN,
|
||
password=LDAP_BIND_PASSWORD,
|
||
auto_bind=True
|
||
)
|
||
|
||
print(f"✅ Успешное подключение к LDAP")
|
||
print(f"Server info: {server.info}")
|
||
print(f"\n" + "=" * 80)
|
||
print(f"Поиск пользователя с email: {USER_EMAIL}")
|
||
print(f"=" * 80)
|
||
|
||
# Поиск пользователя по email
|
||
search_filter = f"(&(objectClass=user)(mail={USER_EMAIL}))"
|
||
|
||
conn.search(
|
||
search_base=LDAP_BASE_DN,
|
||
search_filter=search_filter,
|
||
search_scope=SUBTREE,
|
||
attributes=['*'] # Получаем все атрибуты
|
||
)
|
||
|
||
if not conn.entries:
|
||
print(f"❌ Пользователь с email {USER_EMAIL} не найден в LDAP")
|
||
|
||
# Попробуем поиск по userPrincipalName
|
||
print(f"\nПоиск по userPrincipalName...")
|
||
upn_filter = f"(&(objectClass=user)(userPrincipalName=*{USER_EMAIL.split('@')[0]}*))"
|
||
conn.search(
|
||
search_base=LDAP_BASE_DN,
|
||
search_filter=upn_filter,
|
||
search_scope=SUBTREE,
|
||
attributes=['*']
|
||
)
|
||
|
||
if not conn.entries:
|
||
print(f"❌ Не найдено по userPrincipalName")
|
||
|
||
# Поиск по sAMAccountName
|
||
print(f"\nПоиск по sAMAccountName...")
|
||
sam_filter = f"(&(objectClass=user)(sAMAccountName=*nadein*))"
|
||
conn.search(
|
||
search_base=LDAP_BASE_DN,
|
||
search_filter=sam_filter,
|
||
search_scope=SUBTREE,
|
||
attributes=['*']
|
||
)
|
||
|
||
if not conn.entries:
|
||
print(f"❌ Не найдено записей с 'nadein' в sAMAccountName")
|
||
else:
|
||
print(f"\n✅ Найдено записей: {len(conn.entries)}")
|
||
else:
|
||
print(f"\n✅ Найдено записей: {len(conn.entries)}")
|
||
else:
|
||
print(f"\n✅ Найдено записей: {len(conn.entries)}")
|
||
|
||
# Выводим все найденные записи
|
||
for idx, entry in enumerate(conn.entries, 1):
|
||
print(f"\n{'=' * 80}")
|
||
print(f"ЗАПИСЬ #{idx}")
|
||
print(f"{'=' * 80}")
|
||
print(f"DN: {entry.entry_dn}")
|
||
print(f"\nАтрибуты:")
|
||
print(f"-" * 80)
|
||
|
||
# Основные атрибуты
|
||
important_attrs = [
|
||
'cn', 'givenName', 'sn', 'displayName', 'mail',
|
||
'userPrincipalName', 'sAMAccountName', 'objectGUID',
|
||
'telephoneNumber', 'mobile', 'userAccountControl',
|
||
'whenCreated', 'whenChanged', 'memberOf', 'thumbnailPhoto'
|
||
]
|
||
|
||
for attr in important_attrs:
|
||
if hasattr(entry, attr):
|
||
value = getattr(entry, attr).value
|
||
if attr == 'thumbnailPhoto' and value:
|
||
print(f" {attr:25}: <binary data, length={len(value)} bytes>")
|
||
elif attr == 'memberOf' and value:
|
||
print(f" {attr:25}:")
|
||
if isinstance(value, list):
|
||
for group in value:
|
||
print(f" - {group}")
|
||
else:
|
||
print(f" - {value}")
|
||
elif attr == 'objectGUID' and value:
|
||
# Преобразуем GUID в читаемый формат
|
||
guid_bytes = value
|
||
if isinstance(guid_bytes, bytes):
|
||
guid_str = '-'.join([
|
||
guid_bytes[3::-1].hex(),
|
||
guid_bytes[5:3:-1].hex(),
|
||
guid_bytes[7:5:-1].hex(),
|
||
guid_bytes[8:10].hex(),
|
||
guid_bytes[10:].hex()
|
||
])
|
||
print(f" {attr:25}: {guid_str}")
|
||
else:
|
||
print(f" {attr:25}: {value}")
|
||
else:
|
||
print(f" {attr:25}: {value}")
|
||
|
||
# Дополнительные атрибуты
|
||
print(f"\n Все остальные атрибуты:")
|
||
for attr_name in entry.entry_attributes:
|
||
if attr_name not in important_attrs:
|
||
value = entry[attr_name].value
|
||
if isinstance(value, bytes):
|
||
print(f" {attr_name:23}: <binary data, length={len(value)} bytes>")
|
||
else:
|
||
print(f" {attr_name:23}: {value}")
|
||
|
||
conn.unbind()
|
||
print(f"\n{'=' * 80}")
|
||
print(f"✅ Проверка завершена")
|
||
print(f"{'=' * 80}")
|
||
|
||
except Exception as e:
|
||
print(f"\n❌ Ошибка: {type(e).__name__}")
|
||
print(f" {str(e)}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return 1
|
||
|
||
return 0
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|