如何在PHP中设置SGID? [英] How do I set SGID in PHP?
问题描述
我无法通过PHP设置SGID位.
I cannot manage to set the SGID bit from PHP.
我有这个目录:
4 drwxrwsr-x 12 www-data mygroup 4096 Oct 7 16:05 mydir
注意SGID位.因此,如果我只是使用mkdir test
从外壳程序在其中创建目录,则会得到
Note the SGID bit. So, if I simply create a directory into it from the shell with mkdir test
, I get
4 drwxr-sr-x 2 myuser mygroup 4096 Oct 7 16:22 test
请注意,SGID位是继承的.但是我希望它可以组写(我的umask 22
不允许),所以我可以简单地chmod 02775 test
,我感到非常高兴:
Note that the SGID bit is inherited. But I would want it group writable (which my umask 22
does not allow) so I can simply chmod 02775 test
and I am perfectly happy:
4 drwxrwsr-x 2 myuser mygroup 4096 Oct 7 16:22 test
现在,我想通过PHP脚本执行相同的操作.当然,我希望它能起作用:
Now I would like to do the same from a PHP script. Naturally, I would expect this to work:
mkdir("/mydir/test2");
chmod("/mydir/test2", 02775);
但是没有,我得到了(SGID重置):
But it does not and I get this instead (the SGID is reset):
4 drwxrwxr-x 2 www-data mygroup 4096 Oct 7 16:30 test2
以下是一些其他有用的实验:
Here are a couple of other useful experiments:
mkdir("/mydir/test3");
mkdir("/mydir/test4");
passthru("chmod 02775 '/mydir/test4'");
mkdir("/mydir/test5");
passthru("chmod g+w '/mydir/test5'");
结果是
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
有趣的是,仅mkdir()
保留了SGID,但chmod()
甚至通过passthru()
对其进行了重置.
Interestingly, mkdir()
alone has preserved the SGID, but chmod()
resets it, even through passthru()
.
我知道PHP手册对chmod
说,该命令仅期望三个八进制数字,但我也阅读了 stackoverflow问题提到了有关chmod()
需要最后被称为在chown()
和chgrp()
之后,但我没有使用任何这些.
I know that the PHP manual says for chmod
that the command expects only three octal digits, but I read also this stackoverflow question and it looks like the manual contains obsolete information and others can affect the SGID. Besides, it should not affect the passthru()
versions, should it? The same stackoverflow question mentions something about chmod()
needing to be "the last to be called" after chown()
and chgrp()
, but I am not using any of those.
我在做什么错了?
推荐答案
最后,我发现获得所需权限的唯一方法是利用mkdir()
的正确行为,避免调用chmod()
无论如何,这似乎都会重置SGID位.我能想到的唯一方法是用umask()
更改 umask :
In the end, the only way I could find to obtain the permissions I need is to profit of the correct behaviour of mkdir()
and avoid calling chmod()
which appears to reset the SGID bit no matter what. The only way I can think of doing this is to change the umask with umask()
:
$myumask = umask(2);
mkdir("/mydir/test6");
umask($myumask);
这似乎工作正常:
4 drwxrwsr-x 2 www-data mygroup 4096 Oct 9 14:22 test6
这留给了我 https://注释中提出的问题www.php.net/manual/zh-CN/function.umask.php :多线程Web服务器的所有线程都共享相同的 umask ,这显然会导致不良行为和不可预测的行为.幸运的是,对于我来说,我可以确定所有目录创建都是在单线程上下文中完成的(本质上是在脚本的第一次测试运行中),因此我感到很安全.因此,这是一个有用的解决方法,但不是一种通用解决方案.
This leaves me with the issue raised in the note of https://www.php.net/manual/en/function.umask.php: that all threads of a multithreaded webserver share the same umask, obviously leading to undesired and unpredictable behaviour. Luckily, in my case, I could ascertain that all directory creations are done in a monothreaded context (essentially, on the first test run of a script) and thus I feel safe. Hence, this is a useful workaround but not a general solution.
这篇关于如何在PHP中设置SGID?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!