#! /usr/bin/env python # -*- coding: iso-8859-15 -*- import sys, signal, os, smtplib # Imports pour LDAP sys.path.append('/usr/scripts/gestion') from gen_confs import gen_config, anim, cprint, OK, ERREUR from ldap_crans import crans_ldap, crans, preattr, ldap, smtpserv from whos import adher_details from socket import gethostname if gethostname().split(".")[0] == 'zamok': # Imports pour mailman sys.path.append('/usr/lib/mailman') from Mailman import MailList from Mailman import Utils from Mailman.UserDesc import UserDesc class droits(crans_ldap,gen_config) : ####### Les groupes base_group_dn = 'ou=Group,dc=crans,dc=org' # Quels droits donnent l'appartenacne à quel groupe ? groupes = { 'adm' : [ u'Nounou' ] , 'respbats' : [ u'Câbleur' , u'Déconnecteur', u'Nounou' ] , 'moderateurs' : [ u'Modérateur' ] , 'disconnect' : [ u'Déconnecteur' ] , 'webcvs' : [ u'CVSWeb'] } ####### Les ML # Le + devant un nom de ML indique une synchronisqtion # ML <-> fonction partielle : il n'y a pas d'effacement # des abonnés si le droit est retiré mailing_listes = { 'roots' : [ u'Nounou', u'Apprenti' ], '+nounou' : [ u'Nounou', u'Apprenti' ], 'respbats' : [ u'Câbleur', u'Nounou' ], '+moderateurs' : [ u'Modérateur' ], '+disconnect' : [ u'Déconnecteur' ] } def restart(s) : # Rien à faire pass def __str__(self): return "droits" def build_group(self) : """ Reconstruit les groupes dans la base LDAP """ self.anim.iter = len( self.groupes.keys() ) for group, fonctions in self.groupes.items() : self.anim.cycle() # Qui doit être dans ce groupe ? res = [] for f in fonctions : res += self.search('droits=%s' % f)['adherent'] # Récupération de la constitution du groupe actuel dn = 'cn=%s,%s' % (group, self.base_group_dn) data = self.conn.search_s(dn ,0,'objectClass=posixGroup')[0][1] init_data = data.copy() # Supression de tout les membres data['memberUid'] = [] # Ajout des bonnes personnes for adher in res : uid = preattr(adher.compte())[1] if uid and uid not in data['memberUid'] : data['memberUid'].append(uid) # Sauvegarde modlist = ldap.modlist.modifyModlist(init_data,data) self.conn.modify_s(dn,modlist) def build_master_passwd_group(self) : """Reconstruit les entrées à ajouter dans master.passwd Reconstruit également /etc/group pour le group wheel """ master = "" group = "wheel:*:0:root" self.anim.iter = 2 for fonction in ("Nounou", "Apprenti"): self.anim.cycle() # Qui doit être dans ce groupe ? res = self.search('droits=%s' % fonction)['adherent'] for a in res: if fonction == "Nounou": # On rajoute à /etc/group group = "%s,%s" % (group, a._data['uid'][0]) # On ajoute dans master # Le mot de passe est bidon master = "%s%s:$1$rQcJgpD8$ZZjjszWKnSp9rR6iZ9GPm2:%s:1000:ldap:0:0:%s:%s:%s\n" % (master, a._data['uid'][0], a._data['uidNumber'][0], a._data['gecos'][0], a._data['homeDirectory'][0], "/bin/zsh") # On crée le home try: os.mkdir("%s" % a._data['homeDirectory'][0]) except: # Façon Fred pass group = "%s\n" % group # On va réécrire /etc/master.passwd # cf man master.passwd fichier = file("/etc/master.passwd") for line in fichier: if line.split(":")[4].strip() != "ldap": master = "%s%s" % (line,master) fichier.close() # On va écrire par-dessus fichier = file("/etc/master.passwd", "w") fichier.write(master) fichier.close() os.system("pwd_mkdb -p /etc/master.passwd") # On réécrit /etc/group fichier = file("/etc/group") for line in fichier: if line.split(":")[0].strip() != "wheel": group = "%s%s" % (group,line) fichier.close() # On va réécrire par-dessus fichier = file("/etc/group", "w") fichier.write(group) fichier.close() def print_liste(self,poste) : """ Donne la liste des membres actifs """ for adh in self.search('droits=%s&chbre!=EXT' % poste)['adherent'] : print "%s %s" % (adh.nom(), adh.prenom()) def sync_ML(self) : self.anim.iter = len( self.mailing_listes.keys() ) for ML, fonctions in self.mailing_listes.items() : self.anim.cycle() if ML[0] == '+' : ML = ML[1:] only_add = 1 else : only_add = 0 # Instance correspondant à la ML mlist = MailList.MailList(ML) self.mlist_to_unlock = mlist # Qui doit être dans cette ML ? res = [] for f in fonctions : res += self.search('droits=%s' % f)['adherent'] # Liste des personnes déja inscrites deja_inscrits = {} # { email en miniscules : email avec case n'importe comment } for addr in mlist.getMemberCPAddresses(mlist.getMembers()): deja_inscrits[addr.lower()] = addr # Mails à ajouter to_add = [] mail_traite = [] for adher in res : mail = adher.mail().lower() if mail in mail_traite : continue mail_traite.append(mail) if mail.find('@') == -1 : mail += '@crans.org' if mail not in deja_inscrits.keys() : # Visiblement pas inscrit to_add.append([ mail, adher.Nom() ]) else : # L'adhérent est déja inscrit deja_inscrits.pop(mail) # Ajout for mail, nom in to_add : pw = Utils.MakeRandomPassword() userdesc = UserDesc( mail, nom, pw) mlist.ApprovedAddMember(userdesc) if not only_add : # Supression des personnes inscritees en trop for mail in deja_inscrits.values() : mlist.ApprovedDeleteMember(mail) mlist.Save() mlist.Unlock() self.mlist_to_unlock = None def gen_conf(self) : if gethostname().split(".")[0] == 'zamok': self.anim = anim('\tconfiguration groupes') try : self.build_group() self.anim.reinit() print OK except : self.anim.reinit() print ERREUR if self.debug : import traceback traceback.print_exc() self.anim = anim('\tconfiguration ML Crans') try : self.sync_ML() self.anim.reinit() print OK except : self.anim.reinit() try : # Au cas où... self.mlist_to_unlock.Unlock() except : pass print ERREUR if self.debug : import traceback traceback.print_exc() self.anim = anim('\tenvoi de mails à roots') try : self.mail(self.uids) self.anim.reinit() print OK except : self.anim.reinit() print ERREUR if self.debug : import traceback traceback.print_exc() elif gethostname().split(".")[0] == 'nectaris': self.anim = anim('\tconfiguration master.passwd') try: self.build_master_passwd_group() self.anim.reinit() print OK except: self.anim.reinit() print ERREUR if self.debug : import traceback traceback.print_exc() def mail (self, uids) : """ Envoi un mail à roots pour dire que certains droits ont changé """ # base du mail From = "roots@crans.org" To = "roots@crans.org" base_txt_mail = """From: %(From)s To: %(To)s Subject: Modifications des droits d'un adhérent %(Texte)s""" # boucle pour chaque adhérent modifié for uid in uids : try : adh = self.search('uid=%s' % uid)['adherent'] if len(adh): adh = adh[0] conn=smtplib.SMTP(smtpserv) conn.sendmail(From, To , base_txt_mail % { 'From' : From, 'To' : To, 'Texte' : adher_details(adh).encode('iso8859-15') }) conn.quit() except : self.services_to_restart('droits',[uid]) if __name__ == '__main__' : if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv) == 1 : print "%s " % sys.argv[0].split('/')[-1].split('.')[0] print "Génération de la liste des personnes avec le(s) droit(s) donné(s)." sys.exit(255) cl = droits() for arg in sys.argv[1:] : titre = "%s : " % arg print titre print "-" * len (titre) cl.print_liste(unicode(arg,'iso-8859-1'))