Как заставить PHP установить правильные разрешения на загрузку файлов?
У меня есть сервер с FreeBSD 8.0, Apache 2.2.23 и PHP 5.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>
/ usr / home / site / pub / tmp / принадлежит сайту:www с разрешением 4770. Создание файлов сессий правильно (660 и сайт:www). Но загрузил временные файлы, создав с 600 в разрешениях. Таким образом, поскольку этот временный файл, принадлежащий site:www и Apache, работающему с www:www, move_uploaded_file() не может переместить файл.
Как это исправить?
Я думаю, что мне нужно патч PHP для разрешения принудительного набора для этого файла TMP. Но где? А какая внутренняя функция в PHP может это делать?
4 ответа
Я нашел способ это исправить. Это код моего патча:
*** 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);
Теперь он работает нормально, но показывает предупреждение "Предупреждение: move_uploaded_file(): операция не разрешена в /path/to/script.php в строке 111". Как подавить это предупреждение - я не знаю.
Создать файл, а затем установить разрешение будет работать.
chmod("/somedir/yourfile", 0644);
Попробуйте посмотреть на 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.
Не отрицайте, что люди говорят вам, чтобы использовать chmod()
потому что это единственное решение для изменения прав доступа к файлам из PHP. Тем не менее, основная проблема заключается в том, что либо Apache создает файлы с другим идентификатором пользователя, чем тот, на котором выполняется скрипт, [не похоже на AFAIK], либо вы пытаетесь изменить файлы, созданные с использованием другого процесса, выполняющегося как другой пользователь.
Только владелец файла может изменять права доступа / владельца файла, и если только отдельный процесс не был запущен специально для передачи права собственности другому uid, владельцем файла является uid, который его создал.
Снова, chmod()
а также chown()
являются единственными двумя способами, с помощью которых вы можете изменить разрешения и владельца, и эквивалентны выдаче команд оболочки через exec()
,