如何在PHP中设置SGID? [英] How do I set SGID in PHP?

查看:141
本文介绍了如何在PHP中设置SGID?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法通过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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆