Sessions unter Linux
« | 06 Dec 2018 | »Während der Session-Begriff unter Windows noch einigermaßen eindeutig ist, haben wir unter Linux mehrere Hierarchie-Ebenen, auf die dieser Begriff bedeutet werden kann.
Von Prozessen über Logins bis hin zu grafischen Sitzungen finden wir hier unterschiedliche Mechanismen vor, die wir jeweils als “Session” bezeichnen können.
Prozessgruppen
Prozessgruppen sind logische
Container von einem oder mehreren Prozessen. Intern werden sie als “Sessions”
bezeichnet und mit der API setsid()
erzeugt.
Der erste Prozess einer Session wird zum Session-Leader
und seine PID ist gleichzeitig die Session-ID.
Nun kann man mit kill
Signale
an die Session senden, womit alle Kindprozesse der Session angesteuert werden.
Login und Umgebung
Das Programm login
ist für das Anmelden eines neuen Benutzers zuständig
und startet danach die konfigurierte Shell UND bereitet die Umgebung vor.
Unzählige Funktionen in Unix-Derivaten benötigen bestimmte Environment Variablen. Fehlen diese oder sind falsch eingetragen, treten “seltsame” Seiteneffekte auf.
Da sich die Environment-Tabelle im Normalfall ebenfalls an alle Kindprozesse weitervererbt, kann man auch ein Login als “Session” bezeichnen.
X11
Wird auf einem System auch noch ein X11-Server hochgefahren, bildet sich ein zum Kernsystem paralleles Login-System ab. Der X-Server kann mehrere “Sessions” parallel bedienen und setzt ebenso für alle zusammengehörigen Prozesse bestimmte Environment-Variablen auf, damit (vor allem die grafischen) Prozesse ihre gemeinsamen Ressourcen finden.
Linux APIs
So lange man als Programmierer seine Software nur innerhalb einer solchen Session betreiben möchte, muss man sich weiter keine Gedanken machen, da sich alle Einstellungen in der Regel vererben.
Will man allerdings selbst steuernd eingreifen, wird es in der Folge schwerer.
Prozessgruppen sind als einzige in POSIX
standardisiert und haben mit
setsid()
und
getsid()
definierte Schnittstellen.
Bei Logins wird es schon schwieriger. Man kann natürlich das Programm
login
starten um eine neue Session zu erzeugen, was aber
User-Eingaben erwartet.
Ist man selbst ein Daemon und will Logins verwalten bzw. Prozesse
gezielt in Login Sessions injizieren, kann man die
Konfigurationsdaten versuchen selbst auszulesen und das Environment
selbst aufsetzen.
Ich experimentiere hierbei mit dynamisch zusammengestellten Shell-Scripts,
die per source
die
Profile-Scripts einbinden und dann das Zielprogramm ausführen.
Den Benutzerwechsel kann man mit der API
setuid()
auslösen und das Script mit dem anderen User so starten. Eine
API, die etwas
Vergleichbares tut, kenne ich bislang nicht.
Bleibt am Ende noch der X-Server.
Dass man in einer bestehenden X-Sitzung ein Programm ausführt ist von
außerhalb der Sitzung recht schwierig, weil es keinen programmatisch
standardisierten Weg gibt herauszufinden, welche Sitzungen überhaupt
laufen und wie man sein Programm vorbereiten muss um einer Sitzung beizutreten.
Hier nutze ich gerne den Workaround, dass die Environment-Tabelle eines
Prozesses innerhalb der Session ausgelesen und für den Zielprozess kopiert
wird.
Natürlich benötigt man dafür root
Rechte oder entsprechende Privilegien.
Die Liste der Sessions und der Prozesse in Sessions ist leider auch nicht
offiziell zugänglich. Allerdings nutzen die aktuellen Implementierung das
Verzeichnis /tmp/.ICE-unix/
um dort für jeden Session-Prozess eine Datei
anzulegen, deren Name dessen PID ist.
Über das procfs
zieht man sich dann
die für X11 relevanten Environment-Variablen heraus (z.B.: DISPLAY
) und fügt
sie dem eigenen Kindprozess bei. Das Kind kann dann über die X11 APIs auf die
Umgebung der laufenden X-Session zugreifen und schon tauchen seine Fenster
auf der GUI der X-Session auf.