BASH: Checken Sie / etc / shadow ein, wenn das Benutzerkennwort gesperrt ist

6

Ziel: Überprüfen Sie, /etc/shadowob das Benutzerkennwort gesperrt ist, dh ob das erste Zeichen im zweiten Feld in / etc / shadow, das das Hash-Passwort des Benutzers enthält, ein Ausrufezeichen ('!') Ist.

Gewünschte Ausgabe: Eine Variable mit dem Namen $disabled'True' oder 'False'.

Benutzername ist in der $unameVariablen und ich mache so etwas:

disabled=`cat /etc/shadow |grep $uname |awk -F\: '{print$2}'`
# I now have the password and need one more pipe into the check for the character
# which is where I'm stuck. I would like to do like (in PHP syntax):
| VARIABLE=="!"?"True":"False"`

Dies ist ein Fragment eines Skripts, das von Cron mit Root-Berechtigungen ausgeführt wird, sodass auf alle gewünschten Informationen zugegriffen werden kann.

DavDav
quelle
4
Beachten Sie, dass nicht alle Betriebssysteme eine "Schatten" -Datei haben und diejenigen, die sich in den Flag-Konventionen für "gesperrte" Konten unterscheiden. Diese Frage bezieht sich tatsächlich !auf den Schattenkennwortmechanismus in Linux-Betriebssystemen.
JdeBP
2
Nur bis diese Distributionen Ersatzsysteme wie tcb von OpenWall oder eine Implementierung von Daniel Renchs Benutzerverzeichnis übernehmen oder sich jemand für LDAP entscheidet. (-:
JdeBP
2
Nutzlose Verwendung von cat; grepkann eine Datei als Befehlszeilenargument verwenden.
D. Ben Knoble
2
Nutzloser Gebrauch von grepauch; awkist perfekt in der Lage, eine Zeichenfolge in einer Datei zu finden.
Mustaccio
2
@PatrickMevzek Ich vermute, DavDav wollte fragen, ob das erste Zeichen des Feldes, in dem normalerweise der Passwort-Hash gespeichert ist (nicht das Passwort selbst), a ist !. Sie haben also technisch Recht, aber das scheint eher ein Tippfehler in der Frage zu sein als ein Fehler in der zugrunde liegenden Absicht.
David Z

Antworten:

3

Warum nicht einfach alles mit awk machen?

awk -F: '/<username>/ {if(substr($2,1,1) == "!"){print "True"} else {print "False"}}' /etc/shadow
hardillb
quelle
1
Genau das war ich. Mein Skript ist jetzt fertig - danke.
DavDav
Nun, dies muss einen Unterprozess erstellen. Mein Vorschlag funktioniert in der Shell und benötigt keinen Unterprozess.
schily
1
@schily keine Notwendigkeit für einen Skript-Wrapper um awk, wenn Sie wirklich wollten, könnten Sie es zu einem Alias ​​machen ...
hardillb
/<username>/stimmt mit ganzen Datensätzen überein, die dem <username>erweiterten regulären Ausdruck entsprechen. So j.doewürde beispielsweise mit einem Datensatz übereinstimmen, der sich b.judoerim Benutzerfeld oder j7doeim Passwort-Hash-Feld befindet.
Stéphane Chazelas
Es ist nur ein Platzhalter, um das Blatt zu zeigen, um den Benutzernamen zu setzen
hardillb
26

Analysieren Sie die shadowDatei nicht manuell

Das Parsen solcher Dateien ist fragil, wenn Sie nicht alle Eventualitäten berücksichtigen (z. B. werden deaktivierte Kennwörter häufig als einzelne verschlüsselt *; behandeln andere Lösungen dies?).

Darüber hinaus erfolgt die Authentifizierung möglicherweise nicht über shadow(sondern über NIS oder ldap oder wer weiß was). Es gibt Standardtools, die all dies für Sie erledigen. In diesem Fall passwd:

-S, --status Zeigt Kontostatusinformationen an. Die Statusinformationen bestehen aus 7 Feldern. Das erste Feld ist der Anmeldename des Benutzers. Das zweite Feld gibt an, ob das Benutzerkonto ein gesperrtes Kennwort (L), kein Kennwort (NP) oder ein verwendbares Kennwort (P) hat. Das dritte Feld gibt das Datum der letzten Passwortänderung an. Die nächsten vier Felder sind das Mindestalter, das Höchstalter, der Warnzeitraum und der Inaktivitätszeitraum für das Kennwort. Dieses Alter wird in Tagen ausgedrückt.

So passwd -S | cut -d ' ' -f 2erhalten Sie, was Sie brauchen. Ein einfaches Wenn / Dann übersetzt es in Ihre gewünschte Variable:

if [ "$(passwd -S "$USER" | cut -d ' ' -f 2)" = "P" ]
then
    disabled="False"
else
    disabled="True"
fi

Gleiches gilt für das Sperren des Passworts eines Benutzers. Dies erfolgt vorzugsweise über usermod( --lockOption) und nicht shadowmanuell.

marcelm
quelle
Außerdem benötigen Sie Root-Berechtigungen, um die shadowDatei lesen zu können (die Berechtigungsanforderung ist der Hauptgrund, warum die Datei schließlich vorhanden ist).
Simon Richter
2
@SimonRichter Soweit ich das beurteilen kann, benötigen Sie root, um auch passwd -Sfür andere Benutzer ausgeführt zu werden. Nicht für Ihren eigenen Benutzer.
Marcelm
3
FWIW, es meldet sich hier (fälschlicherweise) Lfür mein eigenes Konto (Kerberos mit LDAP), ich nehme an, weil es den Passwort-Hash nicht erreichen kann. Die Chancen stehen gut passwd -S, dass sie für viele Authentifizierungsschemata jenseits von / etc / shadow ohnehin nicht nützlich sind.
Stéphane Chazelas
@ StéphaneChazelas Hmm, das ist eine Schande ... Ich hätte eher gehofft, dass sie diesem Feld ein LDAP-Attribut zuordnen würden. (Ich habe LDAP seit
einiger Zeit
2
getent passwd $ACCOUNTRuft den Eintrag von der Quelle ab, die für die Authentifizierung verwendet wird.
Patrick Mevzek
3
U=$user LC_ALL=C awk -F: < /etc/shadow '
  $1 "" == ENVIRON["U"] {
    user_found = 1
    if ($2 ~ /^!/) {
      print "True"
      exit 0
    } else {
      print "False"
      exit 1
    }
  }
  END {
    if (!user_found) {
      print "False"
      print "User "ENVIRON["U"]" not found" > "/dev/stderr"
      exit 2
    }
  }'

$1 "" == ENVIRON["U"]vergleicht das erste Feld mit ENVIRON["U"]lexikalisch. Ohne das ""könnten die Felder numerisch verglichen werden, wenn sie wie Zahlen aussehen (was infdazu führt, dass sie mit INFoder Infinityzum Beispiel übereinstimmen ).

Ohne LC_ALL=C, da einige awkImplementierungen strcoll()für den ==lexikalischen Vergleich verwendet werden, könnte dies dazu führen, dass falsche Einträge auf Benutzernamen überprüft werden, die gleich sortiert sind.

Stéphane Chazelas
quelle
-1

Ein Benutzer ist gesperrt, wenn das Feld passwd die Zeichenfolge *LK*ist. Sie können dies jedoch nicht überprüfen, da /etc/shadowes aus Sicherheitsgründen nur von root gelesen werden kann.

Wenn Berechtigungen kein Problem darstellen, versuchen Sie Folgendes:

while IFS=: read USER PW REST; do 
    if [ "$USER" = "$uname" ]; then 
            if [ "$PW" = "*LK*" ]; then 
                    echo "$uname" Locked 
            fi 
    fi 
done < /etc/shadow 

Bearbeiten: IFS =: verschoben, um den Code zu vereinfachen

schily
quelle
1
Ich habe meine Frage bearbeitet - Berechtigungen sind kein Problem. Als ich das letzte Mal nachgesehen habe, bedeutet ein Ausrufezeichen an erster Stelle im Passwort, dass das Passwort gesperrt ist.
DavDav
schillix.sourceforge.net/man/man4/shadow.4.html Alles, was kein verschlüsseltes Passwort sein kann, macht das Konto unbrauchbar. Wenn Sie jedoch das falsche Muster verwenden, wird dies möglicherweise falsch interpretiert. Bitte beachten Sie: Diese Datei wird von verschiedenen Plattformen gemeinsam genutzt über z NIS.
schily
4
*LK*ist nur für SysV-Systeme, passwd -l(zum Sperren) auf Linux-Basis verwendet !. passwd -lmacht das Konto nicht unbrauchbar, sondern deaktiviert nur die Kennwortauthentifizierung.
Stéphane Chazelas
2
In der Tat lautet das Ziel der Frage: "Ist das erste Zeichen im Passwort des Benutzers ein Ausrufezeichen ('!')"
Jeff Schaller
Durch IFS=: read -r user pw restdie Verwendung wird vermieden, dass gespeichert und wiederhergestellt werden muss $IFS. Siehe auch -r, um die Backslash-Verarbeitung zu vermeiden (Backslash wird in / etc / shadow nicht erwartet)
Stéphane Chazelas