Server-Administration

Benutzerverwaltung unter Linux

Im Kernel

Damit der Kernel die Zugriffsrechte überwachen kann, sind Strukturen erfordeerlich, in denen die notwendigen Angaben mitgeführt werden. Beim Anmelden am System erhält die Login-Shell die UID und GIDs des Nutzers und vererbt diese an neu generierte Prozesse weiter. Für jeden Befehl auf der Kommandozeile generiert die Shell über die Systemaufrufe fork() oder exec() einen neuen Prozess. Threads nach POSIX.1 vererben die UID und GUIDs vom ausführenden Prozess.

Schauen wir uns die Strukturen in den Linux-Quellen etwas näher an:

include/linux/sched.h:

struct task_struct {

volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */

..

/* process credentials */

const struct cred __rcu *real_cred;

const struct cred __rcu *cred;

..

}

Die Struktur "task_struct" wird vom Kernel mit allen notwendigen Angaben versehen, um einen Prozess zu managen. Dort enthalten ist auch eine Referenz auf die Struktur "cred", die Informationen über die UID und die GIDs des Prozesses liefert.

Es sind vier Paare für Prozess- und Gruppen-ID im Linux-Kernel definiert:

  • uid, gid: Die Benutzer- und die Gruppen-ID des Users, der den Prozess gestartet hat.

  • effektive uid und gid: Ausführbare Dateien können das setuid- oder setgid-Bit gesetzt haben, dann wird die uid und/oder die gid von dort verwendet, sobald die Datei ausgeführt wird. Die ursprüngliche uid und gid bleiben bestehen. Effektiv werden aber die uid und gid der Datei verwendet, denn der Kernel nutzt die effektive uid und gid für die Zugriffskontrolle.

  • file system uid und gid: In der Regel sind diese gleich wie die effektive uid und gid. Sie werden vom Kernel verwendet, um die Dateisystem-Zugriffsrechte zu verifizieren. Der NFS-Server, der beispielsweise im Usermode operiert, nutzt diese IDs für den Dateizugriff. Es werden nur die Dateisystem-uid und -gid geändert, nicht die effektive uid oder gid. Der vollständige Dateizugriff auf eine Datei ist somit möglich, ohne dass der Prozess mit den gleichen IDs operiert. Im anderen Fall könnte der Besitzer der Datei dem NFS-Server ein kill-Signal senden, und dieser würde sich beenden. Kill-Signale werden normalerweise nur an Prozesse mit der gleichen effektiven uid und gid gesendet.

  • saved uid und gid: Diese werden gemäß des POSIX-Standards dann verwendet, wenn Programme über den Systemcall "setuid()" die uid oder gid ändern. Die reale uid und gid werden dort gespeichert.

struct cred {

..

uid_t uid; /* real UID of the task */

gid_t gid; /* real GID of the task */

uid_t suid; /* saved UID of the task */

gid_t sgid; /* saved GID of the task */

uid_t euid; /* effective UID of the task */

gid_t egid; /* effective GID of the task */

uid_t fsuid; /* UID for VFS ops */

gid_t fsgid; /* GID for VFS ops */

struct group_info *group_info;

..

}

Hier noch ein Beispiel für ein setuid-Programm:

> cp /usr/bin/id myid

> ./myid

uid=1000(thomas) gid=1000(thomas) groups=1000 ..

# chown root myid; chmod 4750 myid; ls -l myid

-rwsr-x--- 1 root thomas 26152 2011-02-14 16:43 myid

> ./myid

uid=1000(thomas) gid=1000(thomas) euid=0(root) ..