add check_ad_2fa.py - interactive AD group membership checker
This commit is contained in:
+110
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Проверка наличия пользователя в группе 2FA через Active Directory.
|
||||
Использует credentials и настройки из config/config.py.
|
||||
|
||||
Запуск:
|
||||
python check_ad_2fa.py
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
from ldap3 import Server, Connection, ALL, SUBTREE
|
||||
|
||||
# Подтягиваем конфиг
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from config.config import AD_SERVER, AD_USER, AD_PASSWORD, AD_BASE
|
||||
|
||||
|
||||
def find_user(login: str) -> dict | None:
|
||||
"""Найти пользователя в AD по логину (sAMAccountName или mail)."""
|
||||
server = Server(AD_SERVER, get_info=ALL)
|
||||
conn = Connection(server, user=AD_USER, password=AD_PASSWORD, auto_bind=True)
|
||||
|
||||
filter_login = login.lower().replace("\\", "\\5c").replace("*", "\\2a").replace("(", "\\28").replace(")", "\\29")
|
||||
|
||||
if "@" in filter_login:
|
||||
ldap_filter = f"(|(mail={filter_login})(sAMAccountName={filter_login}))"
|
||||
else:
|
||||
ldap_filter = f"(|(sAMAccountName={filter_login})(mail={filter_login}))"
|
||||
|
||||
conn.search(search_base=AD_BASE, search_filter=ldap_filter, attributes=["cn", "sAMAccountName", "memberOf"])
|
||||
|
||||
if not conn.entries:
|
||||
return None
|
||||
|
||||
entry = conn.entries[0]
|
||||
return {
|
||||
"dn": entry.entry_dn,
|
||||
"cn": str(entry.cn),
|
||||
"sam": str(entry.sAMAccountName),
|
||||
"groups": [str(g) for g in entry.memberOf],
|
||||
}
|
||||
|
||||
|
||||
def check_2fa_group(login: str) -> dict:
|
||||
"""Проверить, входит ли пользователь в группу 2FA."""
|
||||
user = find_user(login)
|
||||
if user is None:
|
||||
return {"found": False, "error": f"Пользователь '{login}' не найден в AD."}
|
||||
|
||||
# Ищем группу, содержащую "2FA" в имени
|
||||
groups_2fa = [g for g in user["groups"] if "2FA" in g.upper()]
|
||||
|
||||
return {
|
||||
"found": True,
|
||||
"user": user,
|
||||
"in_2fa_group": len(groups_2fa) > 0,
|
||||
"matching_groups": groups_2fa,
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
print("\n" + "=" * 60)
|
||||
print(" Проверка пользователя в группе 2FA (Active Directory)")
|
||||
print("=" * 60)
|
||||
print(f"\n Сервер AD: {AD_SERVER}")
|
||||
print(f" База поиска: {AD_BASE}")
|
||||
print(f" Подключено как: {AD_USER}")
|
||||
print()
|
||||
|
||||
while True:
|
||||
login = input(" Введите логин (sAMAccountName или email) или 'q' для выхода:\n > ").strip()
|
||||
if not login or login.lower() == "q":
|
||||
print("\n До свидания!\n")
|
||||
break
|
||||
|
||||
result = check_2fa_group(login)
|
||||
|
||||
if not result["found"]:
|
||||
print(f"\n ❌ {result['error']}")
|
||||
continue
|
||||
|
||||
u = result["user"]
|
||||
print(f"\n ✅ Пользователь найден:")
|
||||
print(f" CN: {u['cn']}")
|
||||
print(f" sAM: {u['sam']}")
|
||||
print(f" DN: {u['dn']}")
|
||||
print(f" Групп: {len(u['groups'])}")
|
||||
|
||||
if result["in_2fa_group"]:
|
||||
print(f"\n 🟢 Пользователь ВХОДИТ в группу 2FA:")
|
||||
for g in result["matching_groups"]:
|
||||
print(f" {g}")
|
||||
else:
|
||||
print(f"\n 🔴 Пользователь НЕ найден в группе 2FA")
|
||||
if u["groups"]:
|
||||
print(f"\n Все группы пользователя ({len(u['groups'])}):")
|
||||
for g in u["groups"]:
|
||||
print(f" {g}")
|
||||
print()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print("\n Прервано пользователем.\n")
|
||||
except Exception as e:
|
||||
print(f"\n ❌ Ошибка: {e}")
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user