From a1f324c604748b568c74f78bf8bd4c598d9012b7 Mon Sep 17 00:00:00 2001 From: Christian Ringger <ringger@phys.ethz.ch> Date: Tue, 13 Nov 2018 09:45:39 +0100 Subject: [PATCH] add sync-winhosts to git --- bin/sync-winhosts.py | 217 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100755 bin/sync-winhosts.py diff --git a/bin/sync-winhosts.py b/bin/sync-winhosts.py new file mode 100755 index 0000000..07483fa --- /dev/null +++ b/bin/sync-winhosts.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python3 + +import lib_path +import lib +#import dphysldap +import ssl +import os + +from datetime import datetime +from itertools import count, filterfalse +from ldap3 import Server, Connection, ALL, Tls, SASL, GSSAPI, ServerPool, RANDOM + +# ldap = dphysldap.Ldap(ca_certs_file=".\\ca-certificates.crt") +main_windows_netgroup = "windows" +windows_log_path = "c:\\scratch\\" +unix_log_path = "/var/log/" +log_file = "sync-winhost.log" +ca_certs_file = "/etc/ssl/certs/ca-certificates.crt" + +def connect_ldap(server_names, base): + """Connet to the ldap server""" + server_names = server_names + base = base + tls = Tls( + validate=ssl.CERT_REQUIRED, + version=ssl.PROTOCOL_TLSv1_2, + ca_certs_file=ca_certs_file) + servers = [Server(s, tls=tls, get_info=ALL) for s in server_names] + server_pool = ServerPool( + servers, + pool_strategy=RANDOM, + active=True, + exhaust=False) + connection = Connection( + server_pool, + user='ldapadmin/phd-systemxen.ethz.ch', + authentication=SASL, + sasl_mechanism=GSSAPI, + auto_bind='NONE', + version=3, + client_strategy='SYNC') + connection.open() + connection.start_tls() + connection.bind() + user_classes = ['posixAccount', 'dphysUser', 'inetOrgPerson', 'shadowAccount'] + group_classes = ['posixGroup', 'dphysGroup'] + obj_user = None + obj_group = None + + return connection + +def get_netgroups(cn_name): + """Get the nisnetgroups""" + windows_netgroups = [] + + search_filter = "(&(objectClass=nisNetgroup)(cn="+ cn_name +"))" + ldap.search(search_base="ou=netgroup,dc=phys,dc=ethz,dc=ch", search_filter=search_filter, attributes=['memberNisNetgroup']) + found_groups = ldap.entries + + for found_group in found_groups: + windows_netgroups += found_group['memberNisNetgroup'] + + return windows_netgroups + +def get_netgroup_members(group_name): + """Get windows clients of specific nisnetgroup""" + windows_clients = [] + + search_filter = "(&(objectClass=nisNetgroup)(cn="+ group_name +"))" + ldap.search(search_base="ou=netgroup,dc=phys,dc=ethz,dc=ch", search_filter=search_filter, attributes=['nisNetgroupTriple']) + found_groups = ldap.entries + + for found_group in found_groups: + for client_fqdn in found_group['nisNetgroupTriple']: + client_temp = client_fqdn.replace('(','') + client_ldap = client_temp.replace('.ethz.ch,-,-)','') + '$' + windows_clients.append(client_ldap) + + return windows_clients + +def get_netgroup_clients(main_windows_netgroup): + """Get all windows clients from nisnetgroup""" + clients_netgroup = [] + + windows_netgroups = get_netgroups(main_windows_netgroup) + + for windows_netgroup in windows_netgroups: + clients_netgroup += get_netgroup_members(windows_netgroup) + + return clients_netgroup + + +def get_ldap_clients(): + """Get Windows clients in LDAP""" + windows_clients = [] + + search_filter = "(objectClass=device)" + ldap.search(search_base="ou=ad,dc=phys,dc=ethz,dc=ch", search_filter=search_filter, attributes=['cn']) + found_clients = ldap.entries + + for client in found_clients: + windows_clients.append(str(client['cn'])) + + return windows_clients + +def sync_clients(clients_netgroup, clients_ldap): + """Synchronisation der windows clients im ldap zur master db nisnetgroup""" + remove_clients_from_ldap(list(set(clients_ldap) - set(clients_netgroup))) + add_clients_to_ldap(list(set(clients_netgroup) - set(clients_ldap))) + +def remove_clients_from_ldap(clients): + """Remove old obsolet Computers""" + write_log("Remove " + str(len(clients)) + " clients from ldap.", True) + for client in clients: + write_output("remove client "+ client +" from ldap.....", False) + delete_windows_host(client) + +def add_clients_to_ldap(clients): + """Add new Windows Computers to Ldap""" + write_log("Add " + str(len(clients)) + " clients to ldap.", True) + for client in clients: + write_output("add client "+ client + " to ldap.....", False) + create_windows_host(client) + +def create_windows_host(computername): + """create windows host in ldap""" + hostname = computername + host_dn = "uid="+ hostname +",ou=ad,dc=phys,dc=ethz,dc=ch" + host_objectClass = ["device","posixAccount"] + host_gidNumber = "60000" + host_home = "/home/" + hostname + host_cn = hostname + host_uidNumber = new_uidNumber() + host_attrib = {'gidNumber':host_gidNumber,'homeDirectory':host_home, 'cn':host_cn, 'uidNumber':host_uidNumber} + + ldap.add(host_dn, host_objectClass, host_attrib) + write_output(str(ldap.result['description']), True, False) + +def new_uidNumber(): + """check next free uidNumber and return it""" + used_nr = [] + + ldap.search("ou=ad,dc=phys,dc=ethz,dc=ch", search_filter="(objectClass=device)", attributes=['uid' ,'uidNumber']) + entries = ldap.entries + + for entrie in entries: + nr = str(entrie['uidNumber']) + used_nr.append(int(nr)) + + free_nr = next(filterfalse(set(used_nr).__contains__, count(60001))) + + return str(free_nr) + +def delete_windows_host(computername): + """remove windows host in ldap""" + hostname = computername + host_dn = "uid="+ hostname +",ou=ad,dc=phys,dc=ethz,dc=ch" + + ldap.delete(host_dn) + write_output(str(ldap.result['description']), True, False) + +def write_log(message,new_line,with_timestamp=True): + """write output to logfile""" + if os.name == "nt": + logfile_path = windows_log_path + log_file + else: + logfile_path = unix_log_path + log_file + + if with_timestamp: + log_message = datetime.now().strftime('%d-%m-%Y %H:%M:%S') + ": " + message + else: + log_message = message + + if new_line: + log_message += "\n" + + f = open(logfile_path, "a+") + f.write(log_message) + +def write_output(message, new_line,with_timestamp=True): + """wirte output to standardout and logfile""" + write_log(message, new_line, with_timestamp) + if new_line: + message += "\n" + print(message, end='') + +############### +# +# Start Script +# +############### +write_log("", True) +write_log("Start Sync-Windowshost",True) +write_log("",True) + +# LDAP Connection +write_log("Start connection to LDAP",True) +ldap = connect_ldap(["phd-aa1.ethz.ch","phd-aa2.ethz.ch","phd-aa3.ethz.ch"],'ou=ldap,dc=phys,dc=ethz,dc=ch') + +# Get all Clients from nis Netgroup +write_log("Get from Netgroup all clients",True) +clients_netgroup = get_netgroup_clients(main_windows_netgroup) +#clients_netgroup = ['peter$', 'heidi$', 'geisse$'] +write_log("found "+ str(len(clients_netgroup))+ " clients in netgroup",True) + +# Get all Clients for LDAP +write_log ("Get from LDAP all clients",True) +clients_ldap = get_ldap_clients() +write_log("found "+ str(len(clients_ldap))+ " clients in ldap",True) + +# Synchrnisation von netgroup auf ldap +write_log("Start Sync",True) +sync_clients(clients_netgroup, clients_ldap) + +write_log("",True) +write_log("End Sync-Windowshost",True) +write_log("",True) -- GitLab