Wie setze ich SGID in PHP?
Ich kann das SGID-Bit von PHP nicht setzen.
Ich habe dieses Verzeichnis:
4 drwxrwsr-x 12 www-data mygroup 4096 Oct 7 16:05 mydir
Beachten Sie das SGID-Bit. Also, wenn ich einfach ein Verzeichnis aus der Shell mit in es erstelle mkdir test, bekomme ich
4 drwxr-sr-x 2 myuser mygroup 4096 Oct 7 16:22 test
Beachten Sie, dass das SGID-Bit vererbt wird. Aber ich möchte, dass die Gruppe beschreibbar ist (was meine umask 22nicht erlaubt), damit ich es einfach kann chmod 02775 testund ich bin vollkommen glücklich:
4 drwxrwsr-x 2 myuser mygroup 4096 Oct 7 16:22 test
Jetzt möchte ich dasselbe mit einem PHP-Skript machen. Natürlich würde ich erwarten, dass dies funktioniert:
mkdir("/mydir/test2");
chmod("/mydir/test2", 02775);
Aber das tut es nicht und ich bekomme dies stattdessen (die SGID wird zurückgesetzt):
4 drwxrwxr-x 2 www-data mygroup 4096 Oct 7 16:30 test2
Hier sind einige andere nützliche Experimente:
mkdir("/mydir/test3");
mkdir("/mydir/test4");
passthru("chmod 02775 '/mydir/test4'");
mkdir("/mydir/test5");
passthru("chmod g+w '/mydir/test5'");
Die Ergebnisse sind
4 drwxr-sr-x 2 www-data mygroup 4096 Oct 7 16:39 test3
4 drwxrwxr-x 2 www-data mygroup 4096 Oct 7 16:39 test4
4 drwxrwxr-x 2 www-data mygroup 4096 Oct 7 17:06 test5
Interessanterweise hat mkdir()allein die SGID erhalten, chmod()setzt sie aber auch durch zurück passthru().
Ich weiß, dass das PHP-Handbuch besagt, chmoddass der Befehl nur drei oktale Ziffern erwartet, aber ich habe auch diese Frage zum Stapelüberlauf gelesen und es sieht so aus, als ob das Handbuch veraltete Informationen enthält und andere die SGID beeinflussen können. Außerdem sollte es die passthru()Versionen nicht beeinflussen , oder? Die gleiche Stackoverflow Frage erwähnt , etwas über , chmod()um „die letzten genannt werden“ zu sein , nachdem chown()und chgrp(), aber ich bin nicht von denen , verwende.
Was mache ich falsch?
Antworten
Läuft dies auf einem Webserver oder nur als CLI-Skript? Wenn CLI, Benutzer oder Root?
Warum auch Verzeichnisse? SGID wird für Programmdateien verwendet, damit ein Benutzer ein Programm / Skript als einen anderen Benutzer wie "sudo" ausführen kann. Haben Sie versucht, dies an Dateien anstatt an Verzeichnissen zu testen?
Am Ende könnte ich nur die Berechtigungen erhalten, die ich benötige, um vom korrekten Verhalten zu profitieren mkdir()und einen Anruf zu vermeiden, chmod()der das SGID-Bit zurückzusetzen scheint, egal was passiert. Die einzige Möglichkeit, die ich mir vorstellen kann, besteht darin, die Umask zu ändern mit umask():
$myumask = umask(2); mkdir("/mydir/test6"); umask($myumask);
Dies scheint gut zu funktionieren:
4 drwxrwsr-x 2 www-data mygroup 4096 Oct 9 14:22 test6
Dies lässt mich mit dem Thema in der Anmerkung von https://www.php.net/manual/en/function.umask.php: dass alle Threads eines Multithread-Webservers dieselbe Umask verwenden , was offensichtlich zu unerwünschtem und unvorhersehbarem Verhalten führt. Glücklicherweise konnte ich in meinem Fall feststellen, dass alle Verzeichniserstellungen in einem Monothread-Kontext (im Wesentlichen beim ersten Testlauf eines Skripts) durchgeführt werden, und fühle mich daher sicher. Daher ist dies eine nützliche Problemumgehung, aber keine allgemeine Lösung.