Article publié dans Linux Magazine 83, mai 2006.
La perle de ce mois-ci a été rédigée par Sébastien Aperghis-Tramoni
(sebastien@aperghis.net
), de Marseille.pm.
Dans bien des sociétés informatiques, si la plupart des personnes techniques sont sur des postes tournant avec des systèmes libres, il y a aussi toujours des personnes travaillant sur des postes dit « de bureautique » et le réseau se retrouve bien évidemment orienté Windows, avec un serveur de domaine centralisé et dans certains cas un serveur TSE pour que les Unixiens aient accès à une console Windows quand ils en ont besoin. Mais cela implique généralement que les imprimantes, même quand elles sont en réseau, doivent être définies sur le serveur Windows, et dans certains cas en accès exclusif à ce serveur. Et bien sûr, pour accéder au partage du serveur qui permet d'imprimer, il faut s'authentifier.
Afin de parachever cette politique de sécurité, les mots de passe doivent être régulièrement changés. Le problème est que si un utilisateur Windows va immédiatement le savoir, puisque cela lui sera demandé lorsqu'il va se connecter, un utilisateur Unix ne le verra pas automatiquement, mais observera des blocages comme l'impression qui ne fonctionne plus (et CUPS n'est de plus pas très efficace pour faire remonter l'erreur.. mais passons). Et comme il ne pensera pas nécessairement à Windows, il va perdre du temps.
Comme vous vous en doutez, c'est justement ce qui m'est arrivé, et j'ai donc cherché à automatiser ça. Surtout qu'en moyenne, le mot de passe Windows n'est pas utilisé ailleurs que pour les quelques services Windows, donc ce n'est pas un mot de passe vraiment utile à retenir. Conséquence logique, il suffit d'écrire un petit programme qui effectue le changement tout seul.
Premier point, comment changer le mot de passe. Ce n'est pas très
compliqué, la commande smbpasswd(8) est là pour ça. On va ici
utiliser les options -r
, qui permet d'indiquer le contrôleur du
domaine sur lequel on veut changer son mot de passe, -U
pour
spécifier son identifiant, et -s
qui signale à smbpasswd de
lire les mots de passe de son entrée standard et non pas de /dev/tty
.
Comme tout programme typique de changement de mot de passe, il
demande d'entrer l'ancien avant d'entrer deux fois le nouveau.
Petit exemple :
$ echo -e "pwadak,123\nprout,123\nprout,123" | smbpasswd -s -r pdc.societe.com -U maddingue Password changed for user maddingue
Ça fonctionne ! Passons maintenant à la configuration de l'imprimante. Comme j'utilise CUPS, et que l'impression via le partage SMB nécessite une authentification, mon login et mon mot de passe sont enregistrés dans le fichier /etc/cups/printers.conf (et dans son double /etc/cups/printers.conf.0). Ce fichier ressemble à ça :
<DefaultPrinter Laser> DeviceURI beh:/1/1/30/smb://maddingue:pwadak,123@pdc.societe.com/Laser State Idle Accepting Yes JobSheets none none QuotaPeriod 0 PageLimit 0 KLimit 0 </Printer>
Rien de bien compliqué. Ne reste qu'à écrire un petit programme pour mettre tout ça en place :
1 #!/usr/bin/perl 2 use strict; 3 use File::Copy; 4 use File::Slurp; 5 6 my $conf = '/etc/cups/printers.conf'; 7 my $server = 'pdc.societe.com'; 8 9 my $passwd = join '', map { chr(97+rand(26)) } 1..5; 10 $passwd .= join '', ',', sprintf "%04d", int(10000*rand); 11 12 my $file = read_file($conf); 13 my($login,$oldpass) = $file =~ s{smb://(\w+):([^@]+)\@}{smb://$login\:$passwd\@}m; 14 15 open(SMBPASSWD, "| smbpasswd -s -r $server -U $login") 16 or die "can't execute smbpasswd: $!"; 17 print SMBPASSWD "$oldpass\n$passwd\n$passwd\n"; 18 close(SMBPASSWD) and die "error with smbpasswd: status=$?"; 19 20 open(CONF, '>', $conf) or die "can't write '$conf': $!"; 21 print CONF $file; 22 close(CONF); 23 24 copy($conf, "$conf.0"); 25 26 system qw(/etc/rc.d/init.d/cupsd restart);
Lignes 9 et 10, on génère un nouveau mot de passe qui respecte la politique de sécurité, à savoir au moins huit caractères de long et inclure au moins un chiffre et un caractère spécial. Ici, on utilise cinq caractères alphabétiques aléatoires, une virgule et quatre chiffres aléatoires.
Lignes 12 et 13, on lit le fichier printers.conf, et avec
l'opérateur s///
on cherche le login et le mot de passe actuel,
et on remplace avec le nouveau mot de passe.
Lignes 15 à 18, on exécute smbpasswd en lui passant les mots de
passe. Si tout se passe bien, close()
(qui renvoie le statut de
la commande), doit renvoyer zéro. Sinon, le
script meurt.
Si smbpasswd s'est bien exécuté, on peut sauver les modifications dans les fichiers printers.conf et printers.conf.0, lignes 20 à 24. On relance alors le daemon CUPSd pour qu'il prenne en compte le nouveau fichier.
Pour ceux qui n'auraient pas fait attention, ce script doit
s'exécuter en tant que root
. Et pour qu'il s'exécute automatiquement,
il suffit d'ajouter une entrée dans la crontab
de root
ou
dans la vôtre en l'exécutant avec sudo(8). Par exemple, la
ligne suivante dans ma crontab
l'exécutera tous les lundis
à midi :
0 12 * * 1 sudo /home/maddingue/bin/autochwinpass
Et pour connaître le mot de passe courant ? Il suffit de le lire
depuis le fichier printers.conf avec l'uniligne suivant, qui est
simplement la partie de correspondance du s///
du script précédent,
que l'on pourra coller dans un script nommé winpass par exemple :
$ perl -MFile::Slurp -le 'read_file(shift)=~m{smb://(\w+):([^@]+)\@}&&print$2' /etc/cups/printers.conf
Petite note pour les inquiets : même si les mots de passe indiqués
ici avaient été vrais, le délai entre l'écriture de cette perle et sa
publication implique qu'ils auraient depuis été changés au moins quatre
ou cinq fois ;-)
Envoyez vos perles à perles@mongueurs.net
, elles seront peut-être
publiées dans un prochain numéro de Linux Magazine.
Copyright © Les Mongueurs de Perl, 2001-2011
pour le site.
Les auteurs conservent le copyright de leurs articles.