2016-07-26 21 views
0

Ich versuche, den Inhalt der Variablen $ PASSWORD mit expect in passwd zu übergeben. Dies scheint zu funktionieren und fügt die Benutzer hinzu, aber sobald Sie versuchen, sich mit einem der Benutzer über ssh einzuloggen, funktioniert es nicht. Wenn ich das Passwort manuell einstelle, ist es in Ordnung.expect übergibt keine Eingabe an passwd im Bash-Skript

Hatte jemand dieses Problem vor?

USERS=(user1 user2 user3) 



generatePassword() 
{ 
     pwgen 16 -N 1 
} 

# Check if user is root 
if [ $(whoami) != 'root' ]; then 
     echo "Must be root to run $0" 
     exit 1; 
fi 

# Check if pwgen is installed: 
if [[ $(dpkg -s pwgen > /dev/null 2>&1; echo ${PIPESTATUS}) != '0' ]]; then 
     echo -e "pwgen is not installed, this script will not work without it\n\n'apt-get install pwgen'\n" 
     exit 1; 
    else 
     echo -e "Starting Script...\n\n" 
fi 

# Iterate through users and add them with a password 
for i in ${USERS[@]}; do 
     PASSWORD=$(generatePassword) 
     echo "$i $PASSWORD" >> passwords 

     useradd -m "${i}" 

     echo -e "Adding $i with a password of '$PASSWORD'\n" 

     expect -c " 
      spawn passwd ${i} 

      expect \"Enter new UNIX password:\" 
      send -- \"$PASSWORD\r\" 
      send -- \"\r\" 
      expect \"Retype new UNIX password:\" 
      send -- \"$PASSWORD\r\" 
      send -- \"\r\" 
      " 
      echo -e "\nADDED $i with a password of '$PASSWORD'\n" 
done 
+0

EWWW. Sie führen String-Ersetzungen für Inhalte durch, von denen Sie erwarten, dass sie als Code analysiert werden? Das ist ein merkwürdiger Code-Geruch - wenn Benutzer jemals ihre eigenen Passwörter setzen könnten, könnte dies als eine willkürliche Kommando-Injection-Schwachstelle verwendet werden. –

+0

BTW, siehe http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html für POSIX-Konventionen um Umgebungsvariablen Namen (und damit Namen von Shell-Variablen, die einen Namespace teilen) - Großbuchstaben-Namen sind verwendet von Variablen mit Bedeutung für die Shell oder das Betriebssystem, und Namen mit mindestens einem Kleinbuchstaben sind für die Anwendung reserviert; Betrachten Sie daher "password" anstelle von "PASSWORD", um zu vermeiden, dass versehentlich eine Variable mit Bedeutung für das Betriebssystem überschrieben wird. –

+0

@CharlesDuffy - Ich weiß, das ist das Ergebnis einer Stunde des Fummelns in Ignoranz! Ich versuche, besser zu werden – Detnon

Antwort

0

Sie con't brauchen überhaupt erwarten: Verwenden Sie chpasswd statt passwd

#!/bin/bash 
users=(user1 user2 user3) 

# Check if user is root 
if [[ "$(id -un)" != 'root' ]]; then 
    echo "Must be root to run $0" 
    exit 1 
fi 

# Check if pwgen is installed: 
if ! dpkg -s pwgen > /dev/null 2>&1; then 
    printf "pwgen is not installed, this script will not work without it\n\n'apt-get install pwgen'\n" 
    exit 1 
else 
    printf "Starting Script...\n\n" 
fi 

# Iterate through users and create a password 
passwords=() 
for user in "${users[@]}"; do 
    useradd -m "$user" 
    password="$user:$(pwgen 16 -N 1)" 
    passwords+=("$password") 
    echo "Adding user '$user' with '$password'" 
done 

printf "%s\n" "${passwords[@]}" | chpasswd 

ich mehrere Angebote hinzugefügt haben, die erforderlich sind.
Ich habe die Prüfung dpkg vereinfacht.

Oder, vielleicht einfacher, newusers, um die "useradd" und "passwd" Funktionen atomar durchzuführen.

Ich glaube nicht, dass newusers das Home-Verzeichnis von/etc/skel auffüllt.

0

Erstens: Das unmittelbare Problem ist, dass Sie nicht die Backslash Literale sind auf der Flucht, wenn Sie \r geben, so werden diese nur in r s auf der expect Seite geändert; Die kleinste mögliche Änderung, die das Problem zu beheben scheint, wäre, diese auf \\r zu ändern.


jedoch - tun Sie es nicht, dass die Art und Weise: In expect als mit anderen Sprachen, soll Strings als Literale übergeben wird, nicht in dem Code ersetzt.

expect -f <(printf '%s\n' ' 
set username [lindex $argv 0]; 
set password [lindex $argv 1]; 
spawn passwd $username 

expect "Enter new UNIX password:" 
send -- "$password\r" 
send -- "\r" 
expect "Retype new UNIX password:" 
send -- "$password\r" 
send -- "\r" 
') -- "$i" "$PASSWORD" 

Sie könnten auch den wörtlichen Text in Frage in eine Datei speichern und starten Sie expect -f passwd.expect -- "$i" "$PASSWORD", die genauso gut funktionieren würden (und vermeiden die Abhängigkeit von <() Syntax, die eine KSH Erweiterung von bash angenommen ist).

+0

Ich kann Expect in einer Un _expect_ed Weise dann verwenden ... Bin ich richtig in der Annahme, dass ich die [Lindex $ argv 0] Teile brauche? Ich dachte, das wäre nötig, wenn ich zu Beginn meines Skripts Argumente verwende? – Detnon

+0

Also, re: die '[lindex $ argv 0]' Teile, was das macht, zieht die Variablen aus der Befehlszeile in awk. (Siehe am Ende, nach dem '- ', wo wir die Shell-Variablen auf die awk-Befehlszeile setzen; die' set username' und 'set password' sind, wo wir diese Befehlszeilenparameter nehmen und awk-Variablen machen von ihnen). –

+0

Der Sinn dieser Vorgehensweise besteht darin, Injektionsattacken durch einen überraschenden oder böswilligen Benutzernamen oder ein Passwort zu vermeiden, anstatt die Werte direkt in das awk-Skript einzusetzen. Eine kurze Einführung in das SQL-Äquivalent des Angriffs, vor dem Sie sich schützen, finden Sie unter https://xkcd.com/327/. Die beste Methode, um Daten vom Eingeben von Inhalt in Code fernzuhalten, besteht darin, * Ihre Daten out-of-band aus Code * zu übermitteln, was hier geschieht. –