From 41620614b3ec2cd5e3af8fa83279ca4e4aac5b42 Mon Sep 17 00:00:00 2001 From: pauget Date: Thu, 9 Sep 2004 02:16:48 +0200 Subject: [PATCH] Utilitaire de changement de mot de passe dans la base LDAP pour les cbleurs. Avantage par rapport l'ancien chgpass : vritable obligation de mettre un mot de passe fort, pas seulement un avertissement. darcs-hash:20040909001648-41617-92fa1b807fe4dade792e316994e7a63f5fe26184.gz --- gestion/chgpass.py | 132 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 112 insertions(+), 20 deletions(-) diff --git a/gestion/chgpass.py b/gestion/chgpass.py index 69b4d125..6e2387c0 100755 --- a/gestion/chgpass.py +++ b/gestion/chgpass.py @@ -1,41 +1,133 @@ #! /usr/bin/env python # -*- coding: iso-8859-15 -*- -import getpass, commands, os +import getpass, commands, os, sys +from affich_tools import cprint import ldap_secret def chgpass(dn) : + cprint("""Le nouveau mot de passe doit comporter au minimum 6 caractères. +Il ne doit pas être basé sur un mot du dictionnaire.""",'jaune') + print "Il est conseillé d'utiliser une combinaison de minuscules, majuscules,\nde chiffres et d'au moins un caractère spécial." print "Le mot de passe tapé ne sera pas écris à l'écran." - print "Taper Ctrl-C pour abandonner" + print "Taper Ctrl-D pour abandonner" try : - while 1 : - mdp = getpass.getpass('Nouveau mot de passe :') - mdp1 = getpass.getpass('Retaper mot de passe :') + mdp = getpass.getpass('Nouveau mot de passe : ') - if mdp != mdp1 : - print 'Les deux mots de passe entrés sont différents, réesayer' + ### Test du mdp + ## 1 - Longueur + if len(mdp) < 6 : + cprint('Mot de passe trop court','rouge') continue + + ## 2 - assez de caractères de types différents ? + chiffres = 0 + majuscules = 0 + minuscules = 0 + autres = 0 + for c in mdp[:] : + if c.isdigit() : + # Un chiffre rapporte 1.5 point avec un maximum de 5 + if chiffres < 4.5 : chiffres += 1.5 + elif c.islower() : + if minuscules < 3 : minuscules += 1 + elif c.isupper() : + if majuscules < 3 : majuscules += 1 + else : + autres += 4 + if len(mdp) < 16 - minuscules - majuscules - chiffres - autres or \ + (not majuscules and not minuscules) : + cprint('Mot de passe trop simple.','rouge') + continue + + ## 3 - Cracklib + test = commands.getoutput("echo '%s' | /usr/sbin/crack_testlib" % mdp) + if test.split(':')[1] != ' ok' : + commentaire = { + ' it does not contain enough DIFFERENT characters' : 'Il y a trop de caractères identiques.' , + ' it is based on a dictionary word' : 'Le mot de passe est basé sur un mot du dictionnaire' + }.get(test.split(':')[1],test.split(':')[1]) + cprint(commentaire,'rouge') + continue + + ### On redemande le mot de passe + mdp1 = getpass.getpass('Retaper mot de passe : ') + if mdp != mdp1 : + cprint('Les deux mots de passe entrés sont différents, réesayer','rouge') + continue + + break - # Test du mdp - test = commands.getoutput('echo "%s" | /usr/sbin/crack_testlib' % mdp) - - if test.split(':')[1] == ' ok' : - break - else : - print test.split(':')[1] - # Changement mdp - if os.system('/usr/bin/ldappasswd -x -D "%s" -w %s "%s" -s %s > /dev/null' % (ldap_secret.auth_dn, ldap_secret.password, dn, mdp) ): - print 'Erreur lors du changement de mot de passe' + if os.system("/usr/bin/ldappasswd -x -D '%s' -w '%s' '%s' -s '%s' > /dev/null" % (ldap_secret.auth_dn, ldap_secret.password, dn, mdp) ): + cprint('Erreur lors du changement de mot de passe','rouge') else : - print 'Changement effectué avec succès' + cprint('Changement effectué avec succès','vert') except KeyboardInterrupt : + cprint('\nAbandon','rouge') + pass + except EOFError : + # Un Ctrl-D + cprint('\nAbandon','rouge') pass if __name__ == '__main__' : - print 'TODO : interface de sélection' - chgpass('aid=10,dc=crans,dc=org') + sys.stdout.write('\r \r') # Pour esthétique lors de l'utilisation par sudo + if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv) != 2 : + print "%s " % sys.argv[0].split('/')[-1].split('.')[0] + print "Changement du mot de passe du compte choisi." + sys.exit(255) + + for c in sys.argv[1][:] : + if not c.isalnum() and not c=='-' : + cprint('Login incorrect','rouge') + sys.exit(1) + + if os.getlogin() == sys.argv[1] : + cprint('Utiliser passwd pour changer son propre mot de passe','rouge') + sys.exit(2) + + s = commands.getoutput("/usr/bin/ldapsearch -x -LLL '(&(objectClass=posixAccount)(uid=%s))' dn nom prenom droits" % sys.argv[1]).strip() + if not s : + cprint('Login non trouvé dans la base LDAP','rouge') + sys.exit(3) + + # Ca a l'air bon + if s.find('\n\n') != -1 : + # Plusieurs trouvé : pas normal + cprint('Erreur lors de la recherche du login : plusieur occurences !','rouge') + sys.exit(4) + + s = s.split('\n') + try : + dn = s[0].split()[1] + cprint("Changement du mot de passe de %s %s " % ( s[2].split()[1], s[1].split()[1] ),'vert') + except : + cprint('Erreur lors de la recherche du login','rouge') + sys.exit(5) + + if len(s) > 3 : + # Adhérent avec droits + From = 'respbats@crans.org' + To = 'roots@crans.org' + mail = """From: Respbats <%s> +To: %s +Subject: Tentative de changement de mot de passe ! + +Tentative de changement du mot de passe de %s par %s. +""" % ( From, To , sys.argv[1], os.getlogin() ) + + # Envoi mail + import smtplib + conn = smtplib.SMTP('localhost') + conn.sendmail(From, To , mail ) + conn.quit() + cprint('Impossible de changer le mot de passe de cet adhérent : compte privilégié','rouge') + sys.exit(6) + + # Finalement ! + chgpass(dn)