aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeik Sievertsen <acydburn@phpbb.com>2009-03-18 18:09:14 +0000
committerMeik Sievertsen <acydburn@phpbb.com>2009-03-18 18:09:14 +0000
commit233e62f0b5033e84964fff95d79497ba62a52f23 (patch)
tree86cc44888e7a1fe5b462285e666db376da12bdce
parent159eb5cbb4c694be16670b3ea1d7858abef29220 (diff)
downloadforums-233e62f0b5033e84964fff95d79497ba62a52f23.tar
forums-233e62f0b5033e84964fff95d79497ba62a52f23.tar.gz
forums-233e62f0b5033e84964fff95d79497ba62a52f23.tar.bz2
forums-233e62f0b5033e84964fff95d79497ba62a52f23.tar.xz
forums-233e62f0b5033e84964fff95d79497ba62a52f23.zip
backport 3.2 version of phpbb_chmod() - need to be tested further...
git-svn-id: file:///svn/phpbb/branches/phpBB-3_0_0@9394 89ea8834-ac86-4346-8a33-228a782c2dd0
-rw-r--r--phpBB/includes/functions.php128
1 files changed, 76 insertions, 52 deletions
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 65bf1f9c65..248a478145 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -461,8 +461,9 @@ function _hash_crypt_private($password, $setting, &$itoa64)
/**
* Global function for chmodding directories and files for internal use
+*
* This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions.
-* The function determines owner and group from common.php file and sets the same to the provided file. Permissions are mapped to the group, user always has rw(x) permission.
+* The function determines owner and group from common.php file and sets the same to the provided file.
* The function uses bit fields to build the permissions.
* The function sets the appropiate execute bit on directories.
*
@@ -475,76 +476,103 @@ function _hash_crypt_private($password, $setting, &$itoa64)
*
* NOTE: The function uses POSIX extension and fileowner()/filegroup() functions. If any of them is disabled, this function tries to build proper permissions, by calling is_readable() and is_writable() functions.
*
-* @param $filename The file/directory to be chmodded
-* @param $perms Permissions to set
-* @return true on success, otherwise false
+* @param string $filename The file/directory to be chmodded
+* @param int $perms Permissions to set
*
+* @return bool true on success, otherwise false
* @author faw, phpBB Group
*/
function phpbb_chmod($filename, $perms = CHMOD_READ)
{
+ static $_chmod_info;
+
// Return if the file no longer exists.
if (!file_exists($filename))
{
return false;
}
- if (!function_exists('fileowner') || !function_exists('filegroup'))
- {
- $file_uid = $file_gid = false;
- $common_php_owner = $common_php_group = false;
- }
- else
+ // Determine some common vars
+ if (empty($_chmod_info))
{
- global $phpbb_root_path, $phpEx;
+ if (!function_exists('fileowner') || !function_exists('filegroup'))
+ {
+ // No need to further determine owner/group - it is unknown
+ $_chmod_info['process'] = false;
+ }
+ else
+ {
+ global $phpbb_root_path, $phpEx;
- // Determine owner/group of common.php file and the filename we want to change here
- $common_php_owner = fileowner($phpbb_root_path . 'common.' . $phpEx);
- $common_php_group = filegroup($phpbb_root_path . 'common.' . $phpEx);
+ // Determine owner/group of common.php file and the filename we want to change here
+ $common_php_owner = fileowner($phpbb_root_path . 'common.' . $phpEx);
+ $common_php_group = filegroup($phpbb_root_path . 'common.' . $phpEx);
- $file_uid = fileowner($filename);
- $file_gid = filegroup($filename);
+ // And the owner and the groups PHP is running under.
+ $php_uid = (function_exists('posix_getuid')) ? @posix_getuid() : false;
+ $php_gids = (function_exists('posix_getgroups')) ? @posix_getgroups() : false;
- // Try to set the owner to the same common.php has
- if ($common_php_owner !== $file_uid && $common_php_owner !== false && $file_uid !== false)
- {
- // Will most likely not work
- if (@chown($filename, $common_php_owner));
+ // If we are unable to get owner/group, then do not try to set them by guessing
+ if (!$php_uid || empty($php_gids) || !$common_php_owner || !$common_php_group)
{
- clearstatcache();
- $file_uid = fileowner($filename);
+ $_chmod_info['process'] = false;
}
- }
-
- // Try to set the group to the same common.php has
- if ($common_php_group !== $file_gid && $common_php_group !== false && $file_gid !== false)
- {
- if (@chgrp($filename, $common_php_group));
+ else
{
- clearstatcache();
- $file_gid = filegroup($filename);
+ $_chmod_info = array(
+ 'process' => true,
+ 'common_owner' => $common_php_owner,
+ 'common_group' => $common_php_group,
+ 'php_uid' => $php_uid,
+ 'php_gids' => $php_gids,
+ );
}
}
}
- // And the owner and the groups PHP is running under.
- $php_uid = (function_exists('posix_getuid')) ? @posix_getuid() : false;
- $php_gids = (function_exists('posix_getgroups')) ? @posix_getgroups() : false;
-
- // Who is PHP?
- if ($file_uid === false || $file_gid === false || $php_uid === false || $php_gids === false)
- {
- $php = NULL;
- }
- else if ($file_uid == $php_uid /* && $common_php_owner !== false && $common_php_owner === $file_uid*/)
+ if ($_chmod_info['process'])
{
- $php = 'owner';
+ // Change owner
+ if (@chown($filename, $_chmod_info['common_owner']))
+ {
+ clearstatcache();
+ $file_uid = fileowner($filename);
+ }
+
+ // Change group
+ if (@chgrp($filename, $_chmod_info['common_group']))
+ {
+ clearstatcache();
+ $file_gid = filegroup($filename);
+ }
+
+ // If the file_uid/gid now match the one from common.php we can process further, else we are not able to change something
+ if ($file_uid != $_chmod_info['common_owner'] || $file_gid != $_chmod_info['common_group'])
+ {
+ $_chmod_info['process'] = false;
+ }
}
- else if (in_array($file_gid, $php_gids))
+
+ // Still able to process?
+ if ($_chmod_info['process'])
{
- $php = 'group';
+ if ($file_uid == $_chmod_info['php_uid'])
+ {
+ $php = 'owner';
+ }
+ else if (in_array($file_gid, $_chmod_info['php_gids']))
+ {
+ $php = 'group';
+ }
+ else
+ {
+ // Since we are setting the everyone bit anyway, no need to do expensive operations
+ $_chmod_info['process'] = false;
+ }
}
- else
+
+ // We are not able to determine or change something
+ if (!$_chmod_info['process'])
{
$php = 'other';
}
@@ -564,26 +592,22 @@ function phpbb_chmod($filename, $perms = CHMOD_READ)
switch ($php)
{
- case null:
case 'owner':
- /* ATTENTION: if php is owner or NULL we set it to group here. This is the most failsafe combination for the vast majority of server setups.
-
$result = @chmod($filename, ($owner << 6) + (0 << 3) + (0 << 0));
clearstatcache();
- if (!is_null($php) || (is_readable($filename) && is_writable($filename)))
+ if (is_readable($filename) && is_writable($filename))
{
break;
}
- */
case 'group':
$result = @chmod($filename, ($owner << 6) + ($perms << 3) + (0 << 0));
clearstatcache();
- if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))))
+ if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename)))
{
break;
}
@@ -593,7 +617,7 @@ function phpbb_chmod($filename, $perms = CHMOD_READ)
clearstatcache();
- if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))))
+ if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename)))
{
break;
}