Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger

 << zurück
Linux-UNIX-Programmierung von Jürgen Wolf
Das umfassende Handbuch – 2., aktualisierte und erweiterte Auflage 2006
Buch: Linux-UNIX-Programmierung

Linux-UNIX-Programmierung
1216 S., mit CD, 49,90 Euro
Rheinwerk Computing
ISBN 3-89842-749-8
gp Kapitel 6 System- und Benutzerdateien
  gp 6.1 Die Datei /etc/passwd
    gp 6.1.1 Die Datei /etc/passwd auswerten
    gp 6.1.2 getpwuid und getpwnam – einzelne Abfrage von /etc/passwd
    gp 6.1.3 getpwent, setpwent und endpwent – komplette Abfrage von /etc/passwd
  gp 6.2 Die Datei /etc/shadow
    gp 6.2.1 Die Datei /etc/shadow auswerten
    gp 6.2.2 getspent, setspent und endspent – komplette Abfrage von /etc/shadow
  gp 6.3 Die Datei /etc/group
    gp 6.3.1 Die Datei /etc/group auswerten
    gp 6.3.2 getgrnam und getgrgid – einzelne Einträge aus /etc/group abfragen
    gp 6.3.3 getgrent, setgrent und endgrent – alle Einträge in /etc/group abfragen
  gp 6.4 uname – Informationen zum lokalen System erfragen
  gp 6.5 Das Verzeichnis /etc/skel und Network Information Service (NIS)
  gp 6.6 Dateien für Netzwerkinformationen


Rheinwerk Computing

6.2 Die Datei /etc/shadodowntop

Wie bereits erwähnt, speicherten ältere Linux-/UNIX-Versionen die Passwörter noch direkt in der Datei /etc/passwd im zweiten Feld. Hatte ein Anwender Zugriff auf diese Datei, wurde häufig ein so genannter Wörterbuchangriff gemacht, um dieses Passwort zu entschlüsseln. Hierzu wurde dazumal das Kommando crypt zum Entschlüsseln verwendet. Hatte der Anwender dabei ein einfaches Passwort aus Buchstaben verwendet, war es in der Tat möglich, das Passwort zu knacken. Hierauf soll aber nicht näher eingegangen werden.

Fakt ist, dass eben eine Angriffsfläche vorhanden war, die mit der Passwortdatei /etc/shadow beseitigt wurde. Da der Eigentümer und die Gruppe dieser Datei root ist, ist diese auch nicht mehr zum Lesen zu öffnen. Der Eintrag in die Datei erfolgt nach demselben Schema wie schon in der Datei /etc/passwd. Ein Eintrag steht jeweils in einer Zeile, und die einzelnen Felder wiederum werden durch einen Doppelpunkt getrennt. Die Syntax:

Name:Pass:DOC:MinTag:MaxTag:Warn:DeaktivIn:DeaktivSeit:Frei
gp  Name – Der Benutzername, der im ersten Feld steht, verknüpft diesen Eintrag mit einem gleichnamigen Eintrag in der Datei /etc/passwd. Somit sollten für alle Einträge in der Datei /etc/passwd auch Einträge in der Datei /etc/shadow existieren.
gp  Pass – Hier steht das verschlüsselte Passwort des Benutzers. Befindet sich hier ein »*« oder »!«, bedeutet dies, dass kein Passwort eingetragen ist – was aus Gründen der Datensicherheit vermieden werden sollte.
gp  DOC (Day of last change) – Hier steht der Tag, an dem das Datum seit dem 1.1.1970 verändert wurde. Dieser Tag (eine Integer-Zahl) wird zur Überprüfung der Lebensdauer von Passwörtern verwendet.
gp  MinTag – Der frühestmögliche Zeitpunkt (in Tagen), wann der Benutzer sein Passwort ändern kann.
gp  MaxTag – Der spätmöglichste Termin (in Tagen), wann der Benutzer sein Passwort ändern muss.
gp  Warn – Hier wird eingetragen, wie viele Tage vor Ablauf des Passwortes (siehe »MaxTage«) der Benutzer eine Warnung bei der Anmeldung auf dem Bildschirm angezeigt bekommt.
gp  Deaktiv – Hier wird eingetragen, wie viele Tag das Passwort nach Ablauf von »MaxTage« noch gülig ist. Danach kann sich der Benutzer nicht mehr anmelden.
gp  DeaktivSeit – Hier findet man die Anzahl von Tagen, seit ein Passwort gesperrt wurde (deaktiv ist).
gp  Frei – Ein freies Feld für eventuell spätere Erweiterungen. Hat jetzt noch keine Bedeutung.

Hierzu ein einfaches Beispiel aus meiner /etc/shadow-Datei:

john:$1$oLLnoOfp$MQch.ycZRIzUZ0JYnaXRB/:12952:0:99999:7:::

Der Benutzer heißt hier »john«, das verschlüsselte Passwort lautet »$1$oLLnoOfp$MQch.ycZRIzUZ0JYnaXRB/«, das Passwort wurde am 12952. Tag nach 1.1.1970 das letzte Mal verändert und kann frühestens in 0 Tagen (also heute) und muss spätestens in 99999 Tagen (ca. 274 Jahren) geändert werden – in dem Fall also immer. 14 Tage (sofern Sie diesen Tag überleben) vor Ablauf des Passwortes soll eine Warnung ausgegeben werden. Die anderen Werte wurden vom Administrator nicht definiert und sind leer.


Rheinwerk Computing

6.2.1 Die Datei /etc/shadow auswerten  downtop

Die einzelnen Felder der Datei /etc/shadow sind in der Struktur struct spwd enthalten und in der Headerdatei <shadow.h> definiert.


Tabelle 6.2    Die Struktur spwd in der Headerdatei <shadow.h>

Strukturvariable Bedeutung
char *sp_namp Benutzername (Loginname)
char *sp_pwdp Verschlüsseltes Passwort
long int sp_lstchg Datum der letzten Änderung (seit dem 1.1.1970)
long int sp_min Nächste Änderung frühestens möglich in sp_min Tagen
long int sp_max Spätestens muss eine Änderung gemacht werden in sp_max Tagen.
long int sp_warn Anzahl Tage, die der Benutzer gewarnt werden soll, bevor das Passwort abläuft.
long int sp_inact Anzahl nach sp_max, wenn der Account deaktiviert wird
long int sp_expire Anzahl Tage nach dem 1.1.1970, seit der Account deaktiviert bzw. gesperrt wurde
unsigned long int sp_flag Wird noch nicht verwendet.


Rheinwerk Computing

6.2.2 getspent, setspent und endspent – komplette Abfrage von /etc/shadotoptop

Wie auch schon bei der Datei /etc/passwd stehen Ihnen bei der Datei /etc/shadow entsprechende Funktionen zur Verfügung, wo Sie alle Daten in /etc/shadow erfragen können.

#include <shadow.h>
struct spwd *getspent(void);
void setspent(void);
void endspent(void);

Die Funktion getspent() liefert einen Zeiger auf die Struktur spwd zurück, die den Inhalt einer Zeile in /etc/shadow beinhaltet. Auch hier wird beim ersten Aufruf immer der erste Eintrag der Datei /etc/shadow zurückgeliefert. Jeder weitere Aufruf von getspent() holt sich immer die nächste Zeile der Datei /etc/shadow. Nach jedem Aufruf von getspent() wird der alte Inhalt in der Struktur von neuem überschrieben. Der Rückgabewert ist bei einem Fehler oder dem Ende der Datei /etc/shadow NULL.

Wollen Sie sichergehen, dass getspent() wirklich vom Anfang der Datei /etc/shadow beginnt, müssen Sie die Funktion setspent() aufrufen. Hiermit wird der Lesezeiger auf den Anfang der Datei /etc/shadow gesetzt.

Wenn Sie mit getspent() fertig sind, können Sie mit endspent() die Datei /etc/shadow wieder schließen. Dies garantiert Ihnen bei einem erneuten Aufruf von getspent(), dass /etc/shadow wieder neu geöffnet wird und sich der Dateizeiger am Anfang dieser Datei befindet.

Hierzu ein einfaches Beispiel von getspent() und endspent(). Sie geben über der Kommandozeile einen entsprechenden Benutzer ein, wovon Sie die Passwortinformationen aus der /etc/shadow-Datei ermitteln können. Da /etc/shadow eine Datei ist, die nur vom Benutzer und der Gruppe root gelesen werden kann, benötigen Sie für dieses Programm auch die entsprechende Superuser-Rechte.

/* read_shadow.c */
/* Programm benötigt Superuser-Rechte  */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <shadow.h>
#include <string.h>
#include <time.h>
struct spwd *getshadow(const char *loginname) {
   struct spwd *shadow_ptr;
   while( shadow_ptr=getspent() ) {
      if( strcmp(shadow_ptr->sp_namp, loginname) == 0) {
         endspent();
         return shadow_ptr;
      }
   }
   endspent();
   return NULL;
}
int main(int argc, char *argv[]) {
   struct spwd *shadow_ptr;
   if( argc != 2 ) {
      fprintf(stderr, "Usage: %s Name\n", argv[0]);
      exit (EXIT_FAILURE);
   }
   shadow_ptr=getshadow(argv[1]);
   if(shadow_ptr == NULL) {
      printf("Konnte nichts über %s ermitteln\n", argv[1]);
      exit (EXIT_FAILURE);
   }
   printf("Folgendes wurde zu %s ermittelt: \n", argv[1]);
   printf("Benutzername              : %s\n",
      shadow_ptr->sp_namp);
   printf("Passwort (verschlüsselt)   : %d\n", 
      shadow_ptr->sp_pwdp);
   printf("Tag der letzten Änderung  : %li Tage\n",
      shadow_ptr->sp_lstchg);
   printf("Nächste Änderung möglich  : %li Tage\n", 
      shadow_ptr->sp_min);
   printf("Nächste Änderung fällig   : %li Tage\n", 
      shadow_ptr->sp_max);
   printf("Warnung, wenn Passwort fällig %li Tage zuvor!\n", 
      shadow_ptr->sp_warn);
   printf("Konto nach %li Tagen vor Ablauf der Frist sperren!\n", 
      shadow_ptr->sp_inact);
   return EXIT_SUCCESS;
}

Das Programm bei der Ausführung:

you@host > sudo ./read_shadow tot
Passwort:*******
Folgendes wurde zu tot ermittelt:
Benutzername              : tot
Passwort (verschlüsselt)   : 134520844
Tag der letzten Änderung  : 12928 Tage
Nächste Änderung möglich  : 0 Tage
Nächste Änderung fällig   : 99999 Tage
Warnung, wenn Passwort fällig 7 Tage zuvor!
Konto nach -1 Tagen vor Ablauf der Frist sperren!

Eine Ausgabe von -1 wie in der letzten Zeile zeigt an, dass dieser Wert nicht verwendet wird.

Natürlich gibt es auch eine entsprechende Funktion wie getpwnam() bei /etc/passwd für /etc/shadow mit getspnam(). Die Syntax:

#include <shadow.h>
struct spwd *getspnam(const char *name);

Die Funktion getspnam() gibt ebenfalls einen Zeiger auf eine Struktur spwd zurück, die den Inhalt einer Zeile in /etc/shadow mit dem Benutzernamen name enthält. Ansonsten bei einem Fehler oder wenn der Name nicht gefunden werden konnte, gibt diese Funktion NULL zurück. Hierzu das Beispiel zu getspnam():

/* read_shadow2.c */
/* Programm benötigt Superuser-Rechte  */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <shadow.h>
#include <string.h>
#include <time.h>
int main(int argc, char *argv[]) {
   struct spwd *shadow_ptr;
   if( argc != 2 ) {
      fprintf(stderr, "Usage: %s Name\n", argv[0]);
      exit (EXIT_FAILURE);
   }
   shadow_ptr=getspnam(argv[1]);
   if(shadow_ptr == NULL) {
      printf("Konnte nichts über %s ermitteln\n", argv[1]);
      exit (EXIT_FAILURE);
   }
   printf("Folgendes wurde zu %s ermittelt: \n", argv[1]);
   printf("Benutzername              : %s\n",
      shadow_ptr->sp_namp);
   printf("Passwort (verschlüsselt)   : %d\n",
      shadow_ptr->sp_pwdp);
   printf("Tag der letzten Änderung  : %li Tage\n", 
      shadow_ptr->sp_lstchg);
   printf("Nächste Änderung möglich  : %li Tage\n", 
      shadow_ptr->sp_min);
   printf("Nächste Änderung fällig   : %li Tage\n", 
      shadow_ptr->sp_max);
   printf("Warnung, wenn Passwort fällig %li Tage zuvor!\n", 
      shadow_ptr->sp_warn);
   printf("Konto nach %li Tagen vor Ablauf der Frist sperren!\n", 
      shadow_ptr->sp_inact);
   return EXIT_SUCCESS;
}

Bei der Ausführung entspricht das Programme exakt dem von »read_shadow.c«. Natürlich benötigen Sie auch hierzu wieder die Superuser-Rechte, um die Datei /etc/shadow lesen zu können.


Hinweis   Neben den hier vorgestellten Funktionen bietet die <shadow.h >-API noch einige Funktionen mehr an. Ein Aufruf von z. B. »man getspent« bringt die weiteren Routinen zum Vorschein.


 << zurück
  
  Zum Rheinwerk-Shop
Neuauflage: Linux-UNIX-Programmierung
Neuauflage:
Linux-UNIX-
Programmierung

bestellen
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: Linux-Server






 Linux-Server


Zum Rheinwerk-Shop: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Rheinwerk-Shop: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Rheinwerk-Shop: Shell-Programmierung






 Shell-
 Programmierung


Zum Rheinwerk-Shop: Linux Handbuch






 Linux Handbuch


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
Info





Copyright © Rheinwerk Verlag GmbH 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern