#! /usr/bin/env python # -*- coding: iso-8859-15 -*- # Copyright (C) Frédéric Pauget # Licence : GPLv2 """Ce script permet de lancer la reconfiguration des divers services Usage: %(prog)s options Les options possibles sont : \t%(options)s Les options avec = doivent être suivies d'un argument. Plusieurs arguments peuvent être founis pour une même option, les séparer par & """ import sys, signal, os, commands, getopt, smtplib, shutil sys.path.append('/usr/scripts/gestion') from ldap_crans import crans_ldap, crans, smtpserv, hostname from lock import * from affich_tools import anim, cprint, OK, ERREUR, WARNING from time import localtime, strftime, time, sleep import config args_autorises = ['quiet', 'remove=', 'add=', 'list' ,'help', 'reconnect'] if hostname == 'zamok' : args_autorises += [ 'home=', 'mail_bienvenue=', 'ML-ENS=', 'droits', 'switch=' , 'dhcp', 'dns', 'firewall' , 'del_user=', 'blacklist_upload', 'autostatus'] elif hostname == 'nectaris' : args_autorises += [ 'conf_wifi', 'bornes_wifi=' , 'droits-nectaris', 'dhcp-nectaris'] elif hostname == 'sila' : args_autorises += [ 'bl_squid_upload', 'blacklist_virus' , 'blacklist_warez' , 'bl_chbre_invalide', 'bl_carte_etudiant' ] elif hostname == 'komaz' : args_autorises += [ 'firewall-komaz=' , 'firewall-komaz-ports=' , 'firewall-komaz-blacklist'] # On vérifie que l'on est root if os.getuid() != 0: sys.stderr.write("Il faut être root\n") sys.exit(1) signal.signal(signal.SIGINT,signal.SIG_IGN) # Pas de Ctrl-C db = crans_ldap() make_lock('auto_generate','Big lock',nowait=1) ##### Options fournies ? try : if len(sys.argv) > 1 : options, arg = getopt.getopt(sys.argv[1:], 'h', args_autorises) else : options, arg = ( [],'') except getopt.error, msg : sys.stderr.write('%s\n' % msg) sys.exit(255) debug = 1 # défaut to_do = {} for opt, val in options : if opt == '--quiet' : debug = 0 elif opt == '--remove' : for serv in val.split('&') : print 'Supression de %s' % serv db.services_to_restart('-%s' % serv) sys.exit(0) elif opt == '--list' : print 'Services à redémarrer :' print db.services_to_restart() sys.exit(0) elif opt == '--reconnect' : # Personnes à reconnecter print 'Recheche personnes en fin de sanction.' hier = strftime('%d/%m/%Y %H:%M'.split()[0],localtime(time()-60*60*24)) c = db.search('blacklist=*,%s*' % hier) services = [] for a_reco in c['adherent'] + c['machine'] + c['club'] : for bl in a_reco.blacklist() : fin, sanction = bl.split(',')[1:3] if fin.split()[0] == hier and sanction not in services : services.append(sanction) for s in services : print "Ajout de blacklist_%s pour reconfiguration" % s db.services_to_restart('blacklist_%s' % s.encode()) sys.exit(0) elif opt=='--add' : # Ajout d'un item dans les services à redémarrer for serv in val.split('&') : if serv.find(',')!=-1 : serv, arg = serv.split(',',1) arg = arg.split(',') else : arg = [] print 'Ajout de %s (%s)' % ( serv, arg ) db.services_to_restart(serv, arg) sys.exit(0) elif opt =='-h' or opt == '--help' : print __doc__ % { 'prog' : sys.argv[0].split('/')[-1] , 'options' : '\n\t'.join(args_autorises) } sys.exit(0) elif len(opt)>2 and opt[:2]=='--' : to_do[opt[2:]] = val.split('&') ##### Lecture de la base LDAP si besion ce qu'il y a a faire et préparation if not to_do : if debug : print 'Lecture services à redémarrer dans la base LDAP' to_do = db.services_to_restart() auto = 1 else : auto = 0 if debug : print 'Services à redémarrer imposés (non lecture de la base LDAP)' inst = [] if hostname == 'zamok': if 'del_user' in to_do.keys() : if auto : db.services_to_restart('-del_user') cprint('Archivage fichiers utilisateur','gras') for args in to_do['del_user'] : anim('\t' + args) try : login, home = args.split(',') if not login or not home : raise ValueError('Argument invalide') warn = '' f = config.cimetiere + '/files/' + strftime('%Y-%m-%d-%Hh%Mm_') + login + '.tar.bz2' status, output = commands.getstatusoutput("tar cjf '%s' '%s' /var/spool/mail/%s" % ( f,home,login) ) if ( status != 512 and status!=0 ) or not os.path.isfile(f) : # La 512 est si un des paths n'exite pas. raise OSError(output) if os.path.isdir(home) and os.stat(home)[4] >= 500 : shutil.rmtree(home) else : warn += '%s incorrect\n' % home if os.path.isfile('/var/spool/mail/' + login ) : os.unlink('/var/spool/mail/' + login) else : warn += '/var/spool/mail/%s incorrect\n' % login if warn : print WARNING if debug : sys.stderr.write(warn) else : print OK except : print ERREUR # On devra le refaire la prochaine fois if auto : db.services_to_restart('del_user',[args]) if debug : import traceback traceback.print_exc() if 'home' in to_do.keys() : if auto : db.services_to_restart('-home') cprint('Création home','gras') for args in to_do['home'] : anim('\t' + args) try : home, uid, login = args.split(',') ### Home if not os.path.exists(home) : # Le home n'existe pas os.mkdir(home, 0755) os.chown(home, int(uid) ,config.gid) elif os.path.isdir(home) : # Il y un répertoire existant # Bon UID ? stat = os.stat(home) if stat[4] != int(uid) or stat[5] != config.gid : # Le home n'est pas à la bonne personne raise OSError('home existant') ### Mail try : os.mkdir(home + '/Mail', 0700) os.chown(home + '/Mail', int(uid) ,config.gid) except : # Pas grave pass ### Quota status, output = commands.getstatusoutput('/usr/sbin/edquota -p pauget %s' % login ) if status : print WARNING if debug : sys.stderr.write(output+'\n') else : print OK except : print ERREUR # On devra le refaire la prochaine fois if auto : db.services_to_restart('home',[args]) if debug : import traceback traceback.print_exc() if 'mail_bienvenue' in to_do.keys() : if auto : db.services_to_restart('-mail_bienvenue') cprint('Envoi mail de bienvenue','gras') for mail in to_do['mail_bienvenue'] : anim('\t' + mail) try : From = "respbats@crans.org" To = mail if To.find('@') == -1 : To += '@crans.org' conn=smtplib.SMTP(smtpserv) conn.sendmail(From, To , config.txt_mail_bienvenue % { 'From' : From, 'To' : To }) conn.quit() print OK except Exception, c: print ERREUR if auto : db.services_to_restart('mail_bienvenue',[mail]) if debug : import traceback traceback.print_exc() if 'ML-ENS' in to_do.keys() : if auto : db.services_to_restart('-ML-ENS') cprint('Inscription ML-ENS','gras') for mail in to_do['ML-ENS'] : anim('\t'+mail) status, output = commands.getstatusoutput("echo '%s' | /usr/sbin/add_members -r - com-ens >/dev/null 2>&1" % mail) if status : # Il y a eu une erreur print ERREUR if auto : db.services_to_restart('ML-ENS', [mail]) if debug : sys.stderr.write(output+'\n') else : print OK if 'droits' in to_do.keys() : if auto : db.services_to_restart('-droits') db.services_to_restart('droits-nectaris') try: from gen_confs.droits import droits a = droits() a.uids = to_do['droits'] a.debug = debug a.reconfigure() except: if auto : db.services_to_restart('droits',to_do['droits']) if 'blacklist_upload' in to_do.keys() : if auto : db.services_to_restart('-blacklist_upload') db.services_to_restart('bl_squid_upload') db.services_to_restart('firewall-komaz-blacklist') try: from gen_confs.firewall import bl_upload_fw a = bl_upload_fw() a.debug = debug a.reconfigure() except: if auto: db.services_to_restart('blacklist_upload') if 'switch' in to_do.keys() : if auto : db.services_to_restart('-switch') try: from gen_confs.switchs import switch a = switch(to_do['switch']) a.debug = debug a.reconfigure() except: if auto : db.services_to_restart('switch',to_do['switch']) sys.stdout.write('Erreur dans la config des switchs.\n') if debug : import traceback traceback.print_exc() if 'mail_modification_machine' in to_do.keys() : cprint('Modification d\'une machine : envoi d\'un mail à roots@crans.org','gras') try : from mail import mail_details # liste des machines machines = [] for ip in to_do['mail_modification_machine'] : anim('\t' + ip) print OK machines += db.search('ipHostNumber=%s' % ip)['machine'] # envoi du mail mail_details(machines, Subject = 'Modification d\'une machine de l\'association') if auto : db.services_to_restart('-mail_modification_machine') print OK except : print ERREUR if 'autostatus' in to_do.keys() : if auto : db.services_to_restart('-autostatus') try: from autostatus import autostatus a = autostatus() a.debug = debug a.reconfigure() except: if auto : db.services_to_restart('autostatus') # Les services suivants ont besoin de la liste des machines # On va donc la lire une seule fois pour leur passer ensuite restartlater = [] if 'dns' in to_do.keys() : from gen_confs.bind import dns inst.append([dns(),"dns"]) if 'dhcp' in to_do.keys() : from gen_confs.dhcpd import dhcp inst.append([dhcp(),"dhcp"]) if 'firewall' in to_do.keys() : # Quand sila et komaz liront la base LDAP from gen_confs.firewall import firewall inst.append([firewall(),"firewall"]) elif hostname == 'nectaris': restart_wifi_update = False if 'conf_wifi' in to_do.keys() or 'bornes_wifi' in to_do.keys(): # On arrete wifi-update os.system("kill $(cat /var/run/wifi-update.pid)") sleep(1) restart_wifi_update = True # On s'occupe de nectaris if 'conf_wifi' in to_do.keys(): if auto : db.services_to_restart('-conf_wifi') try: from gen_confs.wifi import conf_wifi a = conf_wifi() a.debug = debug a.reconfigure() # On va aussi demander la reconfiguration de toutes les bornes to_do['bornes_wifi'] = [] except: if auto : db.services_to_restart('conf_wifi') sys.stdout.write('Erreur dans la config du wifi.\n') if 'dhcp-nectaris' in to_do.keys() : from gen_confs.dhcpd import dhcp inst.append([dhcp(),"dhcp-nectaris"]) if 'bornes_wifi' in to_do.keys(): if auto : db.services_to_restart('-bornes_wifi') try: from gen_confs.wifi import bornes_wifi if to_do['bornes_wifi']==['all']: a = bornes_wifi() else: a = bornes_wifi(to_do['bornes_wifi']) a.debug = debug a.reconfigure() except: # Pas terrible : on va redemarrer les bornes qui ont redemarré correctement if auto : db.services_to_restart('bornes_wifi', to_do['bornes_wifi']) sys.stdout.write('Erreur dans la config des bornes wifi.\n') if 'droits-nectaris' in to_do.keys(): if auto : db.services_to_restart('-droits-nectaris') try: from gen_confs.droits import droits a = droits() a.debug = debug a.reconfigure() except: if auto : db.services_to_restart('droits-nectaris') sys.stdout.write('Erreur dans la config des droits sur nectaris.\n') if restart_wifi_update: os.system("cd / ; systrace -d /etc/systrace/wifi-update -A /usr/local/bin/twistd --syslog -o -y /usr/scripts/gestion/wifi-update.py --pidfile=/var/run/wifi-update.pid") elif hostname == 'sila' : if 'bl_carte_etudiant' in to_do.keys() : if auto : db.services_to_restart('-bl_carte_etudiant') try: from gen_confs.squid import squid_carte a = squid_carte() a.debug = debug a.reconfigure() except: if auto: db.services_to_restart('bl_carte_etudiant') if 'blacklist_virus' in to_do.keys() : if auto : db.services_to_restart('-blacklist_virus') try: from gen_confs.squid import squid_virus a = squid_virus() a.debug = debug a.reconfigure() except: if auto: db.services_to_restart('blacklist_virus') if 'blacklist_warez' in to_do.keys() : if auto : db.services_to_restart('-blacklist_warez') try: from gen_confs.squid import squid_warez a = squid_warez() a.debug = debug a.reconfigure() except: if auto: db.services_to_restart('blacklist_warez') if 'bl_squid_upload' in to_do.keys() : if auto : db.services_to_restart('-bl_squid_upload') try: from gen_confs.squid import squid_upload a = squid_upload() a.debug = debug a.reconfigure() except: if auto: db.services_to_restart('bl_squid_upload') if 'bl_chbre_invalide' in to_do.keys() : if auto : db.services_to_restart('-bl_chbre_invalide') try: from gen_confs.squid import squid_chbre a = squid_chbre() a.debug = debug a.reconfigure() except: if auto: db.services_to_restart('bl_chbre_invalide') elif hostname == 'komaz' : if 'firewall-komaz' in to_do.keys() or \ 'firewall-komaz-ports' in to_do.keys() or \ 'firewall-komaz-blacklist' in to_do.keys() : from firewall_komaz import firewall_komaz fw = firewall_komaz() fw.debug = debug cprint('Reconfiguration firewall','gras') if 'firewall-komaz' in to_do.keys() : if auto : db.services_to_restart('-firewall-komaz') try : fw.mac_ip_maj(to_do['firewall-komaz']) except : if auto : db.services_to_restart('firewall-komaz',to_do['firewall-komaz']) if 'firewall-komaz-ports' in to_do.keys() : if auto : db.services_to_restart('-firewall-komaz-ports') try : fw.port_maj(to_do['firewall-komaz-ports']) except : if auto : db.services_to_restart('firewall-komaz-ports',to_do['firewall-komaz-ports']) if 'firewall-komaz-blacklist' in to_do.keys() : if auto : db.services_to_restart('-firewall-komaz-blacklist') try : fw.blacklist() except : if auto : db.services_to_restart('firewall-komaz-blacklist',to_do['firewall-komaz-blacklist']) # On indique que les services seront a priori redemarrés if auto : for i in inst: db.services_to_restart("-%s" % i[1]) ## On fait ce qu'il reste à faire if inst : # Récolte des données cprint('Lecture base LDAP','gras') # Machines de l'assoce machines = crans(db.conn).machines() # Machines des adhérents et clubs de l'année en cours base = db.search('paiement=ok') base = base['adherent'] + base['club'] a = anim('\ttri machines',len(base)) for adh in base : a.cycle() # Adhérent ayant payé l'année en cours if 'bloq' in adh.blacklist_actif() : # Adhérent ignoré continue machines += adh.machines() a.reinit() print OK # Reconfiguration des services for i in inst : i[0].debug = debug i[0].machines = machines try : i[0].reconfigure() except : # Erreur, il faudra relancer le service la prochaine fois if auto : db.services_to_restart('%s' % i[1]) sys.stdout.write('Erreur dans la config de %s.\n' % i[1]) if debug : print 'Non traité ici mais signalé dans la base LDAP : \n\t', db.services_to_restart() signal.signal(signal.SIGINT,signal.SIG_DFL) # Comportement normal de Ctrl-C remove_lock('auto_generate')