Signatur
Beschreibung
posix_setuid() setzt die reale Benutzer-ID (UID) des aktuellen Prozesses. Dies entspricht dem POSIX-Systemaufruf setuid(2). Die Funktion ist typischerweise in Daemon-Prozessen oder CLI-Skripten nützlich, die mit Root-Rechten gestartet werden, nach der Initialisierung jedoch auf einen unprivilegierten Benutzer wechseln sollen, um das Sicherheitsprinzip der minimalen Rechtevergabe (Principle of Least Privilege) umzusetzen.
Wenn der Prozess als Root (UID 0) läuft, werden sowohl die reale, die effektive als auch die gespeicherte Benutzer-ID auf $user_id gesetzt. Läuft der Prozess als normaler Benutzer, darf er die UID nur auf seine eigene setzen. Ein Wechsel zu einer anderen UID schlägt in diesem Fall fehl und gibt false zurück.
Die Funktion ist ausschließlich auf POSIX-kompatiblen Systemen verfügbar (Linux, macOS, BSD usw.) und steht unter Windows nicht zur Verfügung. Sie erfordert zudem, dass die POSIX-Erweiterung (ext/posix) in PHP aktiviert ist.
Im Fehlerfall kann mit posix_get_last_error() und posix_strerror() die genaue Fehlerursache ermittelt werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $user_id Pflicht | int | Die numerische Benutzer-ID (UID), auf die der aktuelle Prozess gesetzt werden soll. Die UID 0 entspricht dem Root-Benutzer. |
Rückgabewert
true zurück, wenn die Benutzer-ID erfolgreich gesetzt wurde, andernfalls false. Im Fehlerfall kann posix_get_last_error() für Details herangezogen werden.Beispiele
Privilegien nach Initialisierung abgeben
<?php
// Skript läuft zunächst als Root, um privilegierte Ressourcen zu öffnen
// Danach wird auf einen unprivilegierten Benutzer gewechselt
$targetUser = posix_getpwnam('www-data');
if ($targetUser === false) {
die('Benutzer www-data nicht gefunden.' . PHP_EOL);
}
// Privilegierten Teil des Prozesses hier ausführen...
// Nun UID auf www-data wechseln
if (posix_setuid($targetUser['uid'])) {
echo 'UID erfolgreich auf ' . $targetUser['uid'] . ' gesetzt.' . PHP_EOL;
echo 'Aktuelle UID: ' . posix_getuid() . PHP_EOL;
} else {
$errno = posix_get_last_error();
echo 'Fehler beim Setzen der UID: ' . posix_strerror($errno) . PHP_EOL;
}
Prüfen ob Root-Rechte vorhanden sind, bevor UID gewechselt wird
<?php
$currentUid = posix_getuid();
if ($currentUid !== 0) {
echo 'Warnung: Prozess läuft nicht als Root (UID: ' . $currentUid . ').' . PHP_EOL;
echo 'UID-Wechsel zu einem anderen Benutzer wird fehlschlagen.' . PHP_EOL;
} else {
$nobodyUser = posix_getpwnam('nobody');
if ($nobodyUser !== false && posix_setuid($nobodyUser['uid'])) {
echo 'Erfolgreich auf nobody (UID ' . $nobodyUser['uid'] . ') gewechselt.' . PHP_EOL;
} else {
$errno = posix_get_last_error();
echo 'UID-Wechsel fehlgeschlagen: ' . posix_strerror($errno) . PHP_EOL;
}
}
// Wichtig · Fallstricke
Sicherheitshinweis: Ein UID-Wechsel mit posix_setuid() ist in der Regel irreversibel, wenn der Prozess als Root läuft und die UID auf einen Nicht-Root-Benutzer gesetzt wird. Nachdem die UID gewechselt wurde, kann der Prozess nicht mehr auf Root-Rechte zurückgreifen. Dies ist ausdrücklich gewünscht für sicherheitskritische Anwendungen.
Achtung: posix_setuid() setzt nur die UID, nicht die Gruppen-ID (GID). Um auch die Gruppenrechte zu entziehen, sollte zusätzlich posix_setgid() aufgerufen werden — und zwar vor posix_setuid(), da nach dem UID-Wechsel möglicherweise keine Berechtigung mehr besteht, die GID zu ändern.
Unter Linux kann das Verhalten durch Kernel-Capabilities beeinflusst werden. Prozesse mit der Capability CAP_SETUID können die UID beliebig setzen, auch ohne UID 0.