Dmitry Kovtun 2024-05-23 17:16:29 +03:00
parent 8184dee91d
commit a01e0b3bdc
1 changed files with 65 additions and 200 deletions

View File

@ -1,4 +1,3 @@
#!/usr/bin/python3
from ldap3 import Server, Connection, ALL, NTLM, SUBTREE, SAFE_SYNC, BASE from ldap3 import Server, Connection, ALL, NTLM, SUBTREE, SAFE_SYNC, BASE
from samba.samdb import SamDB from samba.samdb import SamDB
from samba.auth import system_session from samba.auth import system_session
@ -8,11 +7,9 @@ import samba.param
import logging import logging
from pprint import pprint from pprint import pprint
import json import json
import csv
import subprocess import subprocess
import sched import csv
import time
import datetime
@ -28,15 +25,20 @@ class AD_provaider():
logging.warning("status connect AD.........error") logging.warning("status connect AD.........error")
def search_ms_ad(self, search_filter ,filter:list = ["*"])->dict: def search_ms_ad(self,search_filter ,filter:list = ["*"], dn = None)->dict:
logging.info("search >>>>>>>>>>>>>> AD") logging.info("search >>>>>>>>>>>>>> AD")
self.__connect.search(self.__ad_serch_tree, search_filter, SUBTREE, attributes=filter) if dn is not None:
self.__connect.search(dn, search_filter, SUBTREE, attributes=filter)
else:
self.__connect.search(self.__ad_serch_tree, search_filter, SUBTREE, attributes=filter)
response = self.__connect.response_to_json() response = self.__connect.response_to_json()
response = json.loads(response) response = json.loads(response)
response = json.dumps(response, ensure_ascii="utf-8") response = json.dumps(response, ensure_ascii="utf-8")
return json.loads(response) return json.loads(response)
class Samba_provaider(): class Samba_provaider():
def __init__(self, path) -> None: def __init__(self, path) -> None:
self.__lp = samba.param.LoadParm() self.__lp = samba.param.LoadParm()
@ -64,214 +66,77 @@ class Samba_provaider():
return False return False
class Manager(): class Manager:
def __init__(self, samba_prov:Samba_provaider, ad:AD_provaider) -> None: def __init__(self, samba_ad:Samba_provaider, ad:AD_provaider) -> None:
self._smb = samba_prov self._smb = samba_ad
self.__ad = ad self.__ad = ad
def find_user_by_groups(self, name:str, ou:str, base_ou:str)->dict: def creat_branch_ou(self, data_path_list:list):
str_base_ou = self.__get_str_base_ou(base_ou) for item in data_path_list:
return self.__ad.search_ms_ad(f"(memberOf=CN={name},{ou},{str_base_ou})") i = item.split(",")
date = [m.split("=") for m in i]
date_list = list(reversed(date))
def find_group(self, name, ou, base): self.__seach_path_ou_and_add(date_list)
base_ou = self.__get_str_base_ou(base)
return self.__ad.search_ms_ad(f"(&(objectCategory=group)(name={name})(distinguishedName=CN={name},{ou},{base_ou}))")
def __get_str_base_ou(self, base:str)->str: def __seach_path_ou_and_add(self, ou_list:list):
ou_list = [] path = ""
for i in base.split(","): try:
dn = i.split("=")[0] for i in ou_list:
v = i.split("=")[1] if str(i[0]).replace('"', '') == "OU":
out = "{}={}".format( dn.upper(), v) if len(path) == 0:
ou_list.append(out) path = path + i[0].replace('"', '') +"="+i[1]
return ",".join(ou_list) str_add = "add ou -> {} <- status ....ok".format(path)
print("***************************************")
logging.info(str_add)
print("***************************************")
self._smb.add_ou(path)
else:
path = i[0].replace('"', '') +"="+i[1]+","+ path
str_add = "add ou -> {} <- status ....ok".format(path)
print("***************************************")
logging.info(str_add)
print("***************************************")
self._smb.add_ou(path)
except Exception as ex:
logging.warning(ex)
def open_file_list_groups(self, path:str)->dict: def open_csv_file(self, path)->list:
list_grups = [] out_list = []
with open(path, encoding="utf-8") as sv: try:
render = csv.DictReader(sv) with open(path, encoding="utf-8") as f:
for i in render: reader = csv.reader(f, delimiter="\t" )
list_grups.append(i) next(reader)
return list_grups next(reader)
for row in reader:
out_list.append(row[0].split(";"))
def find_smb_groups(self, name:str, ou:str, base:str): return out_list
group = self._smb.search_samba_ad(f"(&(objectCategory=group)(name={name})(distinguishedName=CN={name},{ou},{self.__get_str_base_ou(base)}))") except Exception as ex:
for i in group: logging.error(ex)
return dict(i) print("при открытии файла произошла ошибка необходимо проверить кодировку файла, а также путь до файла")
return None
def create_group_for_samba(self, name:str, ou:str, data_group:dict, base:str )->bool:
cmd = self._smb.add_group(name, ou)
if cmd:
self.__create_attrs(data_group, ou, base)
return True
return False
def __create_attrs(self, data_group:dict, ou, base_ou:str)->int:
logging.info("-> add attr <-")
attr_list = []
base_ou = self.__get_str_base_ou(base_ou)
l = []
for i in data_group.get("entries")[0].get("dn").split(","):
if i.split("=")[0] != "DC":
l.append(i)
l.append(base_ou)
dn = ",".join(l)
attr_list.append("dn: {}".format(dn))
attr_list.append("changetype: modify")
data = data_group.get("entries")[0].get("attributes")
if data.get("description"):
attr_list.append("add:description")
attr_list.append("description: {}".format(",".join(data.get("description"))))
if data.get("mail"):
attr_list.append("add:mail")
attr_list.append("mail: {}".format(data.get("mail")))
if data.get("info"):
attr_list.append("add:info")
attr_list.append("info: {}".format(data.get("info")))
if data.get("groupType"):
attr_list.append("replace:groupType")
attr_list.append("groupType: {}".format(data.get("groupType")))
cmd = ["ldbmodify", "-H", "/var/lib/samba/private/sam.ldb", "/tmp/group.ldif"]
with open("/tmp/group.ldif", "w") as file:
file.write("\n".join(attr_list))
out = subprocess.call(cmd,restore_signals=True, shell=False)
return out
def find_user_by_groups_samba(self, name, ou, base_ou):
str_base_ou = self.__get_str_base_ou(base_ou)
return self._smb.search_samba_ad(f"(memberOf=CN={name},{ou},{str_base_ou})")
def compare_entry_by_group(self, ms:list, name_group:str, samba_data, base):
if len(samba_data) == 0:
for items in ms:
if "person" in items.get("attributes").get("objectClass"):
if self.__is_user_samba(items.get("attributes").get("sAMAccountName")):
self.__add_entry_for_group_samba(name_group, items.get("attributes").get("sAMAccountName"))
if "group" in items.get("attributes").get("objectClass"):
add_name = self.__is_group_samba(items.get("dn"), base)
if add_name is not None:
self.__add_entry_for_group_samba(name_group, add_name)
else:
smb_list_name = []
ms_list_name = []
for i in samba_data:
smb_list_name.append(str(dict(i).get("sAMAccountName")))
for ms_i in ms:
if "person" in ms_i.get("attributes").get("objectClass"):
if ms_i.get("attributes").get("sAMAccountName") not in smb_list_name and self.__is_user_samba(ms_i.get("attributes").get("sAMAccountName")):
self.__add_entry_for_group_samba(name_group, ms_i.get("attributes").get("sAMAccountName"))
logging.info("-> add in group <-")
if "group" in ms_i.get("attributes").get("objectClass"):
if ms_i.get("attributes").get("sAMAccountName") not in smb_list_name:
add_name = self.__is_group_samba(ms_i.get("dn"), base)
if add_name is not None:
self.__add_entry_for_group_samba(name_group, add_name)
logging.info("-> add in group <-")
ms_list_name.append(ms_i.get("attributes").get("sAMAccountName"))
self.__delet_entry(ms_list_name, smb_list_name, name_group)
def __delet_entry(self, buf_ms:list, samba_buf:list, name_group:str):
for i in samba_buf:
if i not in buf_ms:
cmd = ["samba-tool", "group", "removemembers", name_group, i]
out = subprocess.call(cmd, restore_signals=True)
def __is_user_samba(self, name)->bool:
user = self._smb.search_samba_ad(f"(&(objectCategory=person)(objectClass=user)(sAMAccountName={name}))")
if len(user) !=0:
return True
return False
def __is_group_samba(self, ou, base):
path = []
for i in ou.split(","):
if i.split("=")[0] != "DC":
path.append(i)
p = ",".join(path)
group = self._smb.search_samba_ad(f"(&(objectCategory=group)(distinguishedName={p},{self.__get_str_base_ou(base)}))")
for i in group:
if dict(i).get("sAMAccountName"): return str(dict(i).get("sAMAccountName"))
return None
def __add_entry_for_group_samba(self, name_group, name_user)->int:
cmd = ["samba-tool", "group", "addmembers", name_group, name_user]
out = subprocess.call(cmd,restore_signals=True)
if out == 0:
logging.info("Added members to group {} account {}".format(name_group, name_user))
return out
if __name__ == "__main__": if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
MS_AD_ADRESS = 'ldap://cp-vm-dc01.energo.ru' MS_AD_ADRESS = 'ldap://cp-vm-dc01.energo.ru'
SEARCH_FREE_MS = "dc=energo,dc=ru" SEARCH_FREE_MS = "dc=energo,dc=ru"
MS_USER = 'energo\\administrator' MS_USER = 'energo\\administrator'
PASSWORD = "P@sww0rd" PASSWORD = "P@sww0rd"
PATH_SCV = "List_groups.csv" PATH_CSV = "MigrBatch1.csv"
SEARCH_FREE_SAMBA = "dc=lenenergo,dc=ru" SEARCH_FREE_SAMBA = "dc=lenenergo,dc=ru"
TIME_RUN = "13:43"
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
def run_script(): logging.info("> Run script <")
logging.info("> Run script <") ad = AD_provaider(MS_AD_ADRESS, SEARCH_FREE_MS, MS_USER, PASSWORD)
ad = AD_provaider(MS_AD_ADRESS, SEARCH_FREE_MS, MS_USER, PASSWORD) smb = Samba_provaider(SEARCH_FREE_SAMBA)
smb = Samba_provaider(SEARCH_FREE_SAMBA) manager = Manager(smb, ad)
manager = Manager(smb, ad) date_file = manager.open_csv_file(PATH_CSV)
try: if date_file is not None:
flag_out = True ou_add_list = [ i[5] for i in date_file]
count = 0 logging.info("run create ou")
while flag_out: manager.creat_branch_ou(ou_add_list)# Создаст структуру OU
data = manager.open_file_list_groups(PATH_SCV) logging.info("> END <")
for items in data:
group_data_ms = manager.find_group(items.get("SamAccountName"), items.get("OU"), SEARCH_FREE_MS)
samba_groups = manager.find_smb_groups(items.get("SamAccountName"), items.get("OU"),SEARCH_FREE_SAMBA)
if samba_groups is None:
logging.info("-> Create group <-")
manager.create_group_for_samba(items.get("SamAccountName"), items.get("OU"), group_data_ms, SEARCH_FREE_SAMBA)
else:
ms_group = manager.find_user_by_groups(items.get("SamAccountName"), items.get("OU"), SEARCH_FREE_MS)
samba_group = manager.find_user_by_groups_samba(items.get("SamAccountName"), items.get("OU"), SEARCH_FREE_SAMBA)
manager.compare_entry_by_group(ms_group.get("entries"), items.get("SamAccountName"), samba_group, SEARCH_FREE_SAMBA)
logging.info("> End script <-")
time.sleep(2)
count += 1
if count > 1: break
except KeyboardInterrupt as kb:
print("ctr+c")
except Exception as ex:
logging.error(ex)
def time_run(hour:int, minuts:int):
if isinstance(hour, int) and isinstance(minuts, int) is False:
raise "Type error hour and minute is not int !!!!!"
try:
logging.info(f" -> The launch will be every day in {hour}:{minuts} <-")
while True:
time.sleep(1)
z = time.localtime()
if z.tm_hour == hour and z.tm_min == minuts and z.tm_sec == 0:
logging.info(f"-> Run time {hour}:{minuts}")
run_script()
logging.info(f" -> The launch will be every day in {hour}:{minuts} <-")
except KeyboardInterrupt:
logging.warning("ctr+c")
exit()
time_data = TIME_RUN.split(":")
time_run(int(time_data[0]), int(time_data[1]))