Jak ustawić SGID w PHP?

Oct 07 2020

Nie mogę ustawić bitu SGID z PHP.

Mam ten katalog:

  4 drwxrwsr-x 12 www-data mygroup  4096 Oct  7 16:05 mydir

Zwróć uwagę na bit SGID. Tak więc, jeśli po prostu utworzę w nim katalog z powłoki za pomocą mkdir test, otrzymam

  4 drwxr-sr-x  2 myuser   mygroup   4096 Oct  7 16:22 test

Zauważ, że bit SGID jest dziedziczony. Ale chciałbym, żeby grupa była zapisywalna (na co moja umask 22nie pozwala), więc mogę po prostu chmod 02775 testi jestem całkowicie szczęśliwy:

  4 drwxrwsr-x  2 myuser   mygroup   4096 Oct  7 16:22 test

Teraz chciałbym zrobić to samo ze skryptu PHP. Oczywiście spodziewałbym się, że to zadziała:

mkdir("/mydir/test2");
chmod("/mydir/test2", 02775);

Ale tak się nie dzieje i zamiast tego otrzymuję to (SGID jest resetowany):

  4 drwxrwxr-x  2 www-data mygroup   4096 Oct  7 16:30 test2

Oto kilka innych przydatnych eksperymentów:

mkdir("/mydir/test3");
mkdir("/mydir/test4");
passthru("chmod 02775 '/mydir/test4'");
mkdir("/mydir/test5");
passthru("chmod g+w '/mydir/test5'");

Wyniki są

  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

Co ciekawe, mkdir()sam zachował SGID, ale chmod()resetuje go, nawet przez passthru().

Wiem, że podręcznik PHP mówi, chmodże polecenie oczekuje tylko trzech cyfr ósemkowych, ale czytałem również to pytanie o przepływie stosu i wygląda na to, że podręcznik zawiera przestarzałe informacje, a inne mogą wpływać na SGID. Poza tym nie powinno to wpływać na passthru()wersje, prawda? To samo pytanie o chmod()przepełnienie stosu wspomina o konieczności bycia „ostatnim, do którego można zadzwonić” po chown()i chgrp(), ale nie używam żadnego z nich.

Co ja robię źle?

Odpowiedzi

DanielB Oct 08 2020 at 21:11

Czy to działa na serwerze internetowym, czy po prostu jako skrypt CLI? Jeśli CLI, użytkownik czy root?

Poza tym, dlaczego katalogi? SGID jest używany w plikach programów, aby umożliwić użytkownikowi uruchomienie programu / skryptu jako inny użytkownik, np. „Sudo”. Czy próbowałeś przetestować to na plikach, a nie katalogach?

Paolo Oct 09 2020 at 12:37

Ostatecznie jedynym sposobem, w jaki mogłem znaleźć potrzebne uprawnienia, jest skorzystanie z prawidłowego zachowania mkdir()i uniknięcie wywołania, chmod()które wydaje się resetować bit SGID bez względu na wszystko. Jedyny sposób, w jaki mogę o tym pomyśleć, to zmienić umask za pomocą umask():

$myumask = umask(2); mkdir("/mydir/test6"); umask($myumask);

Wygląda na to, że działa dobrze:

  4 drwxrwsr-x  2 www-data mygroup   4096 Oct  9 14:22 test6

Pozostaje mi kwestia poruszona w nocie https://www.php.net/manual/en/function.umask.php: że wszystkie wątki wielowątkowego serwera WWW mają tę samą umaskę , co oczywiście prowadzi do niepożądanego i nieprzewidywalnego zachowania. Na szczęście w moim przypadku mogłem się upewnić, że wszystkie tworzenie katalogów są wykonywane w kontekście jednowątkowym (zasadniczo przy pierwszym testowym uruchomieniu skryptu) i dzięki temu czuję się bezpiecznie. Dlatego jest to przydatne obejście, ale nie jest to ogólne rozwiązanie.