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

Kapitel 6 System- und Benutzerdateien

Gerade als Programmierer von Programmen sollten Sie sich auch mit den zentralen Benutzerdateien auskennen. Gewöhnlich finden Sie diese Dateien im Verzeichnis /etc unter dem Namen /etc/passwd, /etc/shadow oder /etc/group. Meldet sich z. B. ein neuer Anwender beim System an, wird die Datei /etc/passwd benötigt. Aber auch Kommandos wie »who«,» ls –l« oder »finger« benötigen Daten aus der Datei /etc/passwd. Neben der Möglichkeit, Informationen zu Benutzer- bzw. Gruppendateien zu beschaffen, gibt es auch noch die entsprechenden Netzwerkdateien /etc/service, /etc/networks, /etc/protocols und /etc/hosts. Wie Sie an die entsprechenden Informationen programmiertechnisch herankommen, erfahren Sie in diesem Kapitel.


Rheinwerk Computing

6.1 Die Datei /etc/passwdowntop

Alle Benutzer werden gewöhnlich zentral über die Datei /etc/passwd verwaltet. Laut POSIX.1 wird diese Datei als Benutzerdatenbank bezeichnet. Neben dem Namen des Benutzers enthält diese Datei einige Kenndaten. Hierbei finden Sie allerdings nicht nur die Kenndaten der normalen Benutzer, sondern auch die vom Superuser root und Standard- und Systembenutzer. Mit cat können Sie sich die Datei ansehen:

you@host > cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
...
tot:x:1000:1000:J.Wolf,,,:/home/tot:/bin/bash
john:x:1001:1001:John Wolf,Augsburg,,:/home/john:/bin/bash

Jede Zeile dieser Datei beinhaltet einen Benutzer. Die einzelnen Doppelpunkte dienen als Trennzeichen zwischen den einzelnen Feldern. Somit hat eine solche Zeile folgende Syntax:

Benutzername:Passwort:UID:GID:Info:Heimatverzeichnis:Shell
gp  Benutzername – Unter diesem Namen kann sich der Benutzer am System anmelden. Daher sollte dieser Name eindeutig sein. Da die Datei von oben nach unten abgearbeitet wird, wird bei einem doppelten Eintrag immer der erste Eintrag verwendet, der gefunden wird.
gp  Passwort – Bei älteren Systemen befand sich beim zweiten Feld früher das verschlüsselte Passwort. In der Regel sollte man allerdings heutzutage ein »x« dort stehen sehen. Dies bedeutet, dass das Passwort in /etc/shadow steht (verschlüsselt). Der Grund ist ganz einfach, da viele Programme auf die Datei /etc/passwd zurückgreifen müssen, weil hier auch die Shell und der Pfadname zum Heimatverzeichnis vermerkt sind, heißt das Leserecht für alle. Zwar sind die Passwörter immer noch verschlüsselt, aber jetzt bestand hier die Möglichkeit, ein Passwort zu entschlüsseln. Auch wenn dies im Augenblick nicht sehr einfach zu knacken ist, die Angriffsfläche ist nun mal da – daher auch die Auslagerung nach /etc/shadow. Diese Datei ist nicht mehr für jedermann lesbar. Befindet sich in diesem Feld ein »*« (für nobody), dann erfolgt die Anmeldung ohne Passwortanfrage.
gp  UID – Die Benutzernummer des Benutzers. Der Wert dieser Nummer sollte in Praxis größer als 100 (auf vielen Systemen mittlerweile auch größer als 1000) sein, weil die Zahlen darunter für den Systembenutzer vorgesehen sind. Aus technischen Gründen sollte die UID allerdings nicht größer als 64000 sein. Die UID 0 ist natürlich weiterhin dem Superuser root vorbehalten.
gp  GID – Die Gruppennummer des Benutzers. Auch hierbei sollte die Zahl nicht größer als 64000 sein.
gp  Info – Hier werden ggf. weitere Informationen zum Benutzer hinterlegt, wie z. B. der vollständige Name, die Adresse usw. - das Feld kann also mit einem beliebigen Text gefüllt werden. Gewöhnlich gibt man hier den vollständigen Namen des Benutzers an. Mehrere Angaben werden durch ein Komma getrennt.
gp  Heimatverzeichnis – Hier steht das Heimatverzeichnis des Benutzers bzw. das Startverzeichnis nach dem Login. Die Angabe erfolgt immer über eine absolute Pfadangabe und sollte natürlich im Dateisystem liegen, das zum Zeitpunkt der Anmeldung auch eingebunden ist. Natürlich sollte der Benutzer des Heimatverzeichnisses auch der Besitzer dessen sein. Die Angabe des Heimatverzeichnisses wird in der Variablen HOME abgelegt und steuert somit auch das Verhalten des Kommandos cd, wenn dies ohne Parameter aufgerufen wird. Natürlich wird hierdurch auch das Tilde-Zeichen ~ beeinflusst.
gp  Shell – Auch wenn hier gewöhnlich eine Shell steht, die nach der Anmeldung des Benutzers gestartet werden kann, können Sie hierbei auch jedes beliebige andere Startprogramm verwenden (vom Sinn abgesehen). Alle erlaubten Programme, die gestartet werden können, müssen in der Datei /etc/shells eingetragen sein. Wird dieses Feld leer gelassen, wird standardmäßig die Bourne-Shell (/bin/sh) verwendet – was unter Linux wieder nur ein symbolischer Link zur Bash ist.

Somit können Sie die folgende Zeile wie folgt interpretieren:

john:x:1001:1001:John Wolf,Augsburg,,:/home/john:/bin/bash

Der Benutzername lautet »john«, das Passwort steht verschlüsselt in /etc/shadow, die UID und die GID lauten 1001, als zusätzliche Angaben wurde hier der Namen »John Wolf« und »Augsburg« angegeben. Das Heimatverzeichnis lautet /home/john und das Startprogramm (die Shell) ist die Bash (Bourne-Again-Shell).


Rheinwerk Computing

6.1.1 Die Datei /etc/passwd auswerten  downtop

Die einzelnen Felder der Datei /etc/passwd sind in der Struktur struct passwd enthalten, die in der Headerdatei <pwd. h.> definiert ist.


Tabelle 6.1    Die Struktur struct passwd der Headerdatei <pwd. h.>

Strukturvariable Bedeutung
char *pw_name Benutzername
char *pw_passwd Verschlüsseltes Passwort (nicht POSIX.1)
uid_t pw_uid Benutzernummer UID
gid_t pw_gid Gruppennummer GID
char *pw_gecos Kommentarfeld (nicht POSIX.1)
char *pw_dir Startverzeichnis nach dem Login
char *pw_shell Loginshell


Rheinwerk Computing

6.1.2 getpwuid und getpwnam – einzelne Abfrage von /etc/passwd  downtop

Mit den beiden Funktionen getpwname() und getpwuid() können Sie einen Eintrag der Passwortdatei /etc/passwd erfragen. Beide Funktionen sind POSIX.1-konform. Dies ist die Syntax:

#include <pwd. h.>
#include <sys/types.h>
struct passwd *getpwnam(const char * name);
struct passwd *getpwuid(uid_t uid);

Die Funktion getpwnam() gibt bei Erfolg einen Zeiger auf eine Struktur passwd zurück, die den Inhalt einer Zeile in /etc/passwd mit dem Benutzernamen name enthält (erstes Feld in /etc/passwd).

Die Funktion getpwuid() hingegeben gibt einen Zeiger auf eine Struktur zurück, die eine Zeile in /etc/passwd enthält, die der User-ID uid entspricht.

Beide Funktionen geben bei einem Fehler NULL zurück, wenn kein passender Eintrag in /etc/passwd gefunden wurde oder ein anderer Fehler aufgetreten ist. Konnte nicht ausreichend Speicher für eine passwd-Struktur alloziiert werden, wird errno auf ENOMEM gesetzt.

Hier die Funktion getpwnam() bei der Ausführung. Wollen Sie getpwuid() verwenden, brauchen Sie nur den entsprechenden Codeabschnitt auszukommentieren und die Kommentare um getpwuid() zu entfernen.

/* pasname.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pwd. h.>
#include <string.h>
int main(int argc, char *argv[]) {
   struct passwd *pas_ptr;
   if( argc != 2 ) {
      fprintf(stderr, "Usage: %s Name\n", argv[0]);
      exit (EXIT_FAILURE);
   }
  /* Alternativ mit getpwuid() :                       */
  /* pas_ptr=getpwuid( strtoul(argv[1], NULL, 10) );   */
   pas_ptr=getpwnam(argv[1]);
   if(pas_ptr == NULL) {
      printf("Konnte nichts über %s ermitteln\n", argv[1]);
      exit (EXIT_FAILURE);
   }
   printf("Folgende Angaben wurden ermittelt: \n");
   printf("Benutzername     : %s\n", pas_ptr->pw_name);
   printf("Benutzernummer   : %d\n", pas_ptr->pw_uid);
   printf("Gruppennummer    : %d\n", pas_ptr->pw_gid);
   printf("Kommentar        : %s\n", pas_ptr->pw_gecos);
   printf("Loginverzeichnis : %s\n", pas_ptr->pw_dir);
   printf("Loginshell       : %s\n", pas_ptr->pw_shell);
   return EXIT_SUCCESS;
}

Das Programm bei der Ausführung:

you@host > gcc -Wall -o pasname pasname.c
you@host > ./pasname john
Folgende Angaben wurden zu john ermitteln:
Benutzername     : john
Benutzernummer   : 1001
Gruppennummer    : 1001
Kommentar        : John Wolf,Augsburg,,
Loginverzeichnis : /home/john
Loginshell       : /bin/bash
you@host > ./pasname tot
Folgende Angaben wurden zu tot ermittelt:
Benutzername     : tot
Benutzernummer   : 1000
Gruppennummer    : 1000
Kommentar        : J.Wolf,,,
Loginverzeichnis : /home/tot
Loginshell       : /bin/bash

Hinweis   Bei BSD-UNIX wird bei den Funktionen getpwnam() und getpwuid() das verschlüsselte Passwort automatisch aus /etc/shadow gelesen und in die Strukturvariable pw_passwd geschrieben, wenn das Programm vom Superuser (UID=0) gestartet wurde.



Rheinwerk Computing

6.1.3 getpwent, setpwent und endpwent – komplette Abfrage von /etc/passwtoptop

Wollen Sie alle Daten in /etc/passwd erfragen, stehen Ihnen die drei Funktionen getpwent(), setpwent() und endpwent() zur Verfügung.

#include <pwd. h.>
#include <sys/types.h>
struct passwd *getpwent(void);
void setpwent(void);
void endpwent(void);

Die Funktion getpwent() liefert einen Zeiger auf die Struktur passwd zurück, die den Inhalt einer Zeile in /etc/passwd beinhaltet. Beim ersten Aufruf von getpwent() wird immer der erste Eintrag zurückgegeben. Jeder weitere Aufruf liefert dann den nächsten Eintrag (Zeile) in /etc/passwd zurück. Beachten Sie bitte außerdem, dass nach jedem erneuten Aufruf von getpwent() der alte Inhalt in der Struktur passwd mit dem neuen überschrieben wird. Tritt ein Fehler auf oder sind alle Einträge gelesen worden, gibt getpwent() NULL zurück. Konnte kein Speicher für die Struktur passwd alloziiert werden, wird errno auf ENOMEM gesetzt.

Die Funktion setpwent() öffnet die Datei /etc/passwd, wenn diese nicht bereits geöffnet wurde, und setzt den Dateizeiger auf den Anfang der Passwortdatei. setpwent() muss nicht unbedingt vor einem getpwent()-Aufruf verwendet werden.

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

Hierzu sind die Funktion getpwent() und endpwent() im Einsatz. Im Beispiel wird die Funktion getpwnam() nachgebildet.

/* pasname2.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pwd. h.>
#include <string.h>
struct passwd *getpasswd(const char *loginname) {
   struct passwd *pas_ptr;
   while( pas_ptr=getpwent() ) {
      if( strcmp(pas_ptr->pw_name, loginname) == 0) {
         endpwent();
         return pas_ptr;
      }
   }
   endpwent();
   return NULL;
}
int main(int argc, char *argv[]) {
   struct passwd *pas_ptr;
   if( argc != 2 ) {
      fprintf(stderr, "Usage: %s Name\n", argv[0]);
      exit (EXIT_FAILURE);
   }
   pas_ptr=getpasswd(argv[1]);
   if(pas_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", pas_ptr->pw_name);
   printf("Benutzernummer   : %d\n", pas_ptr->pw_uid);
   printf("Gruppennummer    : %d\n", pas_ptr->pw_gid);
   printf("Kommentar        : %s\n", pas_ptr->pw_gecos);
   printf("Loginverzeichnis : %s\n", pas_ptr->pw_dir);
   printf("Loginshell       : %s\n", pas_ptr->pw_shell);
   return EXIT_SUCCESS;
}

Die Ausführung des Programms entspricht exakt der von »pasname.c«, das im Beispiel zuvor demonstriert wurde.

 << 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