如何强制PHP设置文件上传的正确权限?

如何强制PHP设置文件上传的正确权限?,php,permissions,apache2,freebsd,patch,Php,Permissions,Apache2,Freebsd,Patch,我的服务器使用FreeBSD8.0、Apache2.2.23和PHP5.4.10。这是我的VirtualHost配置: <VirtualHost *> ServerName site.com ServerAlias www.site.com DocumentRoot /usr/home/site/pub/htdocs/ php_admin_value open_basedir /usr/home/site/ php_admin_value se

我的服务器使用FreeBSD8.0、Apache2.2.23和PHP5.4.10。这是我的VirtualHost配置:

<VirtualHost *>
    ServerName site.com
    ServerAlias www.site.com
    DocumentRoot /usr/home/site/pub/htdocs/
    php_admin_value open_basedir /usr/home/site/
    php_admin_value session.save_path 0;0660;/usr/home/site/pub/tmp/
    php_admin_value upload_tmp_dir /usr/home/site/pub/tmp/
</VirtualHost>

服务器名网站
ServerAlias www.site.com
DocumentRoot/usr/home/site/pub/htdocs/
php\u admin\u value open\u basedir/usr/home/site/
php_admin_value session.save_路径0;0660;/usr/home/site/pub/tmp/
php_admin_value upload_tmp_dir/usr/home/site/pub/tmp/
/usr/home/site/pub/tmp/由site拥有:www,拥有4770权限。会话文件创建正确(660和站点:www)。但上载了临时文件,创建权限为600。所以,由于这个临时文件由site:www和Apache拥有,并从www:www运行,move_uploaded_file()无法移动文件

如何修复它


我想我需要补丁PHP来获得这个tmp文件的强制设置权限。但是在哪里呢?PHP中的哪个内部函数可以执行此操作?

创建文件,然后设置权限即可

chmod("/somedir/yourfile", 0644);

不要否决告诉您使用
chmod()
的人,因为这是从PHP更改文件权限的唯一解决方案。然而,主要的问题似乎是,要么Apache使用与脚本运行时不同的uid创建文件,[不太可能是AFAIK],要么您试图修改使用不同用户运行的不同进程创建的文件

只有文件的所有者才能更改文件的权限/所有权,除非专门运行单独的进程将所有权转移到另一个uid,否则文件的所有者就是创建它的uid


同样,
chmod()
chown()
是您可以更改权限和所有权的唯一两种方法,相当于通过
exec()
发出shell命令

尝试查看
chown
您可以临时更改文件的所有者,以便进行适当的更改:

$File = '/path/to/file';
chown($File, USERNAMEPHPISRUNNIGNAT);
chmod($File, 0644);
// Makes Appropriate changes To Files 
chown($File, originalowner);
// Changes your file back to it's original owner
要了解php运行的用户名是什么:

echo exec('whoami')


上面的内容将返回运行php的用户。

我找到了修复它的方法。这是我的补丁的代码:

*** main/php_open_temporary_file.c.orig 2013-01-11 20:33:42.000000000 +0400
--- main/php_open_temporary_file.c  2013-01-11 21:17:44.000000000 +0400
***************
*** 101,113 ****
    char cwd[MAXPATHLEN];
    cwd_state new_state;
    int fd = -1;
! #ifndef HAVE_MKSTEMP
!   int open_flags = O_CREAT | O_TRUNC | O_RDWR
! #ifdef PHP_WIN32
!       | _O_BINARY
! #endif
!       ;
! #endif

    if (!path || !path[0]) {
        return -1;
--- 101,107 ----
    char cwd[MAXPATHLEN];
    cwd_state new_state;
    int fd = -1;
!   int open_flags = O_CREAT | O_TRUNC | O_RDWR;

    if (!path || !path[0]) {
        return -1;
***************
*** 144,169 ****
        return -1;
    }

- #ifdef PHP_WIN32
- 
-   if (GetTempFileName(new_state.cwd, pfx, 0, opened_path)) {
-       /* Some versions of windows set the temp file to be read-only,
-        * which means that opening it will fail... */
-       if (VCWD_CHMOD(opened_path, 0600)) {
-           efree(opened_path);
-           free(new_state.cwd);
-           return -1;
-       }
-       fd = VCWD_OPEN_MODE(opened_path, open_flags, 0600);
-   }
- 
- #elif defined(HAVE_MKSTEMP)
-   fd = mkstemp(opened_path);
- #else
    if (mktemp(opened_path)) {
!       fd = VCWD_OPEN(opened_path, open_flags);
    }
- #endif

    if (fd == -1 || !opened_path_p) {
        efree(opened_path);
--- 138,146 ----
        return -1;
    }

    if (mktemp(opened_path)) {
!       fd = VCWD_OPEN_MODE(opened_path, open_flags, 0660);
    }

    if (fd == -1 || !opened_path_p) {
        efree(opened_path);

现在它工作正常,但显示警告“warning:move_uploaded_file():第111行的/path/to/script.php中不允许操作”。如何抑制此警告-我不知道。

此函数无法帮助,因为site:www with 600拥有的文件和从www:www运行的Apache。此函数无法帮助,因为site:www with 600拥有的文件和从www:www运行的Apache拥有的文件,很抱歉,但这不是我的反对票。是的,你说得对。但是会话文件创建正确。因此,PHP可以设置权限强制。现在我想我必须修补php_open_temporary_file.c。