Changement de mot de passe Expect Script

premier appelant, auditeur de longue date, j’ai une question centrée sur un script attendu et sur la modification du mot de passe sur plusieurs hôtes. Je n’ai aucun problème à faire pivoter le script ou à modifier le mot de passe, le problème que j’éprouve est la capacité des scripts à gérer plusieurs «attentes». Je dois tenir compte de 4 choses, notre environnement est bouleversé et stupide – s’il vous plaît supportez-moi.

  1. Le compte va bien, le mot de passe doit être modifié – cela fonctionne
  2. Le compte a expiré, le mot de passe a changé – cela fonctionne
  3. Le compte utilise déjà un nouveau mot de passe – pas encore intégré
  4. Le compte est verrouillé – non intégré

Mon script passe en revue une liste d’hôtes et se connecte, je veux qu’il fasse quelques choses – lorsqu’il se connecte, si le compte a expiré, il attend certaines choses et change le mot de passe, cela fonctionne. Si cela ne se produit pas et que le script se connecte bien avec l’ancien mot de passe, exécutez simplement la commande passwd et modifiez le mot de passe. Le problème que je rencontre actuellement consiste à faire fonctionner les deux choses ensemble correctement.

Si la liste des hôtes contient un mélange, où le compte a expiré et est en règle, je veux pouvoir passer en revue et gérer chaque situation de manière appropriée, puis la connecter. En ce moment, si je mets des hôtes de test (4 à 5) où le compte a expiré et bien, le script fonctionne si les derniers hôtes ont expiré. Mais cela ne fonctionnera pas si le premier hôte est arrivé à expiration et doit alors se déplacer vers un nouvel hôte.

Voici le code ci-dessous, j’ai parcouru Internet à la recherche de connaissances et rien ne correspond à cela.

Je veux pouvoir dire si la valeur attendue == (mot de passe UNIX actuel) le fait alors, si l’ancien mot de passe est utilisé, passez au nouveau mot de passe … vous aurez vraiment du mal à le faire fonctionner ensemble.

#!/usr/bin/expect set timeout 10 set user userAccount set password oldPassword set new_password newPassword set f [open "input.txt"] set hosts [read $f] close $f ## need to say if the expected value is "(current) UNIX password: then do this" foreach host $hosts { spawn -noecho /bin/ssh -q -o SsortingctHostKeychecking=no "$user\@$host" expect "Password:" send "$password\r" expect { "(current) UNIX password:" {send $password\r; exp_continue} "New password:" {send $new_password\r; exp_continue} "Retype new password:" {send $new_password\r; exp_continue} "~]$" {close} } send "echo -e '$password\n$new_password\n$new_password' | passwd\r" expect "~]$" {close} } 

Je pense que la solution la plus simple consiste à apporter une petite modification à votre première commande attendue:

 expect { "(current) UNIX password:" {send $password\r; exp_continue} "New password:" {send $new_password\r; exp_continue} "Retype new password:" {send $new_password\r} "~]$" {send "echo -e '$password\n$new_password\n$new_password' | passwd\r"} } expect "~]$" {close} 

Le point crucial est qu’il n’ya pas d’exp_continue après la deuxième fois que vous envoyez le nouveau mot de passe. Il va alors sortir de la première commande expect et correspondre uniquement à l’invite de la deuxième commande expect. Si le mot de passe n’a pas expiré, l’invite à l’intérieur de la première commande attendue sera trouvée. Donc, c’est là que vous pouvez exécuter la commande passwd.


Avec vos autres souhaits ajoutés, le corps de la boucle pourrait ressembler à ceci:

 spawn -noecho /bin/ssh -q -o SsortingctHostKeychecking=no "$user\@$host" expect "assword: " send "$password\r" expect { -timeout 30 "(current) UNIX password: " { # Password has expired send $password\r expect { "New password: " { send $new_password\r exp_continue } "Retype new password: " { send $new_password\r exp_continue } "all authentication tokens updated successfully." { # Password has been changed } default { error "Failed to change the password" } } } "assword: " { # Old password was not accepted send $new_password\r expect { -timeout 30 -ex "~]$" { # New password was accepted } "assword: " { # New password was not accepted either error "None of the passwords was accepted" } default { error "Failed to log in" } } } "locked" { # Account is locked } -ex "~]$" { # Logged in with old password send "echo -e '$password\n$new_password\n$new_password' | passwd\r" expect { -ex "~]$" { # Password successfully updated } default { error "passwd command failed" } } } default { error "Log in timed out" } } close 

Ce serait la structure de base. Si cela ne fonctionne pas tout à fait, ajoutez une commande exp_internal 1 pour déterminer les modifications nécessaires.