diff options
author | Meik Sievertsen <acydburn@phpbb.com> | 2008-08-22 12:52:48 +0000 |
---|---|---|
committer | Meik Sievertsen <acydburn@phpbb.com> | 2008-08-22 12:52:48 +0000 |
commit | 6c763cd8b65c1b63d57fb0f176d2c98a44076df1 (patch) | |
tree | bdc638c998285ad49a0876b2e5394ea31845649a /phpBB/includes | |
parent | 88c324a2a3d705cd44ce749af44079849ca091e7 (diff) | |
download | forums-6c763cd8b65c1b63d57fb0f176d2c98a44076df1.tar forums-6c763cd8b65c1b63d57fb0f176d2c98a44076df1.tar.gz forums-6c763cd8b65c1b63d57fb0f176d2c98a44076df1.tar.bz2 forums-6c763cd8b65c1b63d57fb0f176d2c98a44076df1.tar.xz forums-6c763cd8b65c1b63d57fb0f176d2c98a44076df1.zip |
change the way we do chmodd'ing. I know, my implementation really sucked... good we have motivated community members who point this out. ;) Thanks to faw for providing a way better function and for discussing and also abiding to our needs. :) LEW21 should maybe credited too... he gave the inspiration without knowing it.
git-svn-id: file:///svn/phpbb/branches/phpBB-3_0_0@8780 89ea8834-ac86-4346-8a33-228a782c2dd0
Diffstat (limited to 'phpBB/includes')
-rw-r--r-- | phpBB/includes/acm/acm_file.php | 6 | ||||
-rw-r--r-- | phpBB/includes/acp/acp_attachments.php | 2 | ||||
-rw-r--r-- | phpBB/includes/acp/acp_language.php | 2 | ||||
-rw-r--r-- | phpBB/includes/constants.php | 5 | ||||
-rw-r--r-- | phpBB/includes/db/dbal.php | 2 | ||||
-rw-r--r-- | phpBB/includes/functions.php | 166 | ||||
-rw-r--r-- | phpBB/includes/functions_compress.php | 10 | ||||
-rw-r--r-- | phpBB/includes/functions_messenger.php | 6 | ||||
-rw-r--r-- | phpBB/includes/functions_posting.php | 2 | ||||
-rw-r--r-- | phpBB/includes/functions_template.php | 2 | ||||
-rw-r--r-- | phpBB/includes/functions_upload.php | 17 |
11 files changed, 126 insertions, 94 deletions
diff --git a/phpBB/includes/acm/acm_file.php b/phpBB/includes/acm/acm_file.php index 6a5d19bc1c..1c5da0c9d0 100644 --- a/phpBB/includes/acm/acm_file.php +++ b/phpBB/includes/acm/acm_file.php @@ -93,7 +93,7 @@ class acm @flock($fp, LOCK_UN); fclose($fp); - phpbb_chmod($this->cache_dir . 'data_global.' . $phpEx, 'rwrite'); + phpbb_chmod($this->cache_dir . 'data_global.' . $phpEx, CHMOD_WRITE); } else { @@ -197,7 +197,7 @@ class acm @flock($fp, LOCK_UN); fclose($fp); - phpbb_chmod($this->cache_dir . "data{$var_name}.$phpEx", 'rwrite'); + phpbb_chmod($this->cache_dir . "data{$var_name}.$phpEx", CHMOD_WRITE); } } else @@ -416,7 +416,7 @@ class acm @flock($fp, LOCK_UN); fclose($fp); - phpbb_chmod($filename, 'rwrite'); + phpbb_chmod($filename, CHMOD_WRITE); $query_result = $query_id; } diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index 3b937c6597..66d857a3df 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -1196,7 +1196,7 @@ class acp_attachments if (!file_exists($phpbb_root_path . $upload_dir)) { @mkdir($phpbb_root_path . $upload_dir, 0777); - phpbb_chmod($phpbb_root_path . $upload_dir, 'rwrite'); + phpbb_chmod($phpbb_root_path . $upload_dir, CHMOD_READ | CHMOD_WRITE); } } diff --git a/phpBB/includes/acp/acp_language.php b/phpBB/includes/acp/acp_language.php index a988f42f0f..71970b4b50 100644 --- a/phpBB/includes/acp/acp_language.php +++ b/phpBB/includes/acp/acp_language.php @@ -277,7 +277,7 @@ class acp_language { trigger_error("Could not create directory $dir", E_USER_ERROR); } - phpbb_chmod($dir, 'write-all'); + @chmod($dir, 0777); } } } diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 7c681a4040..01300c8992 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -176,6 +176,11 @@ define('REFERER_VALIDATE_NONE', 0); define('REFERER_VALIDATE_HOST', 1); define('REFERER_VALIDATE_PATH', 2); +// phpbb_chmod() permissions +define('CHMOD_ALL', 7); +define('CHMOD_READ', 4); +define('CHMOD_WRITE', 2); +define('CHMOD_EXECUTE', 1); // Additional constants define('VOTE_CONVERTED', 127); diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index 6bec685061..289359ebeb 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -139,7 +139,7 @@ class dbal } // Connection closed correctly. Set db_connect_id to false to prevent errors - if (($result = $this->_sql_close())) + if ($result = $this->_sql_close()) { $this->db_connect_id = false; } diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 05eef16819..aaae41787a 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -460,102 +460,136 @@ function _hash_crypt_private($password, $setting, &$itoa64) } /** -* Global function for chmodding directories and files. -* This function supports different modes to distinguish between writeable/non-writeable. -* The function sets the appropiate execute bit on directories +* 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. +* The function uses bit fields to build the permissions. +* The function sets the appropiate execute bit on directories. * -* Supported modes are: +* Supported constants representing bit fields are: * -* rread (600): Restrictive, only able to be read/write by the apache/site user. -* Used for files which only need to be accessible by phpBB itself and should never be accessible from the outside/web. -* read (644): Read-only permission for the site group/everyone. Used for ordinary files. -* write (664): Write-permission for the site group, read permission for everyone. Used for writeable files. -* write-all (666): Write-permission for everyone. Should only be used for temporary files. +* CHMOD_ALL - all permissions (7) +* CHMOD_READ - read permission (4) +* CHMOD_WRITE - write permission (2) +* CHMOD_EXECUTE - execute permission (1) * -* rwrite (0660): Write-permission only for the site user/group. Used for files phpBB need to write to but within the cache/store/files directory. -* -* NOTE: If rwrite (restrictive write) is used, the function makes sure the file is writable by calling is_writable. If it is not, it falls back to 'write' -* and then to 'write-all' to make sure the file is writable on every host setup. -* NOTE: If rread (restrictive read) is used, the function makes sure the file is readable by calling is_readable. If it is not, it falls back to 'sread' (internal mode 640) and then to 'read'. +* 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 $mode The mode to set. -* @return True on success, false if the mode was not set +* @param $perms Permissions to set +* @return true on success, otherwise false +* +* @author faw, phpBB Group */ -function phpbb_chmod($filename, $mode = 'read') +function phpbb_chmod($filename, $perms = CHMOD_READ) { - switch ($mode) + // Return if the file no longer exists. + if (!file_exists($filename)) { - case 'rread': - $chmod = 0600; - break; + return false; + } - // System-read, only used internally - case 'sread': - $chmod = 0640; - break; + if (!function_exists('fileowner') || !function_exists('filegroup')) + { + $file_uid = $file_gid = false; + $common_php_owner = $common_php_group = false; + } + else + { + global $phpbb_root_path, $phpEx; - case 'rwrite': - $chmod = 0660; - break; + // 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); - case 'write': - $chmod = 0664; - break; + $file_uid = fileowner($filename); + $file_gid = filegroup($filename); - case 'write-all': - $chmod = 0666; - break; + // 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)); + { + $file_uid = fileowner($filename); + } + } - case 'read': - default: - $chmod = 0644; - break; + // 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)); + { + $file_gid = filegroup($filename); + } + } } - // Return if the file no longer exist - if (!file_exists($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; + + // Who is PHP? + if ($file_uid === false || $file_gid === false || $php_uid === false || $php_gids === false) { - return false; + $php = null; + } + else if ($file_uid == $php_uid /* && $common_php_owner !== false && $common_php_owner === $file_uid*/) + { + $php = 'owner'; + } + else if (in_array($file_gid, $php_gids)) + { + $php = 'group'; + } + else + { + $php = 'other'; } - // Add the execute bit if it is a directory + // Owner always has read/write permission + $owner = CHMOD_READ | CHMOD_WRITE; if (is_dir($filename)) { - // This line sets the correct execute bit on those "3-bits" being defined. 0644 becomes 0755 for example. - $chmod |= ($chmod & 7) ? 73 : (($chmod & 56) ? 72 : 64); - } + $owner |= CHMOD_EXECUTE; - // Set mode - $result = @chmod($filename, $chmod); + // Only add execute bit to the permission if the dir needs to be readable + if ($perms & CHMOD_READ) + { + $perms |= CHMOD_EXECUTE; + } + } - // Check for is_writable - if ($mode == 'rwrite') + switch ($php) { - // We are in rwrite mode, so, make sure the file is writable - if (!is_writable($filename)) - { - $result = phpbb_chmod($filename, 'write'); + case null: + case 'owner': + $result = @chmod($filename, ($owner << 6) + (0 << 3) + (0 << 0)); - if (!is_writable($filename)) + if (!is_null($php) || (!is_readable($filename) && is_writable($filename))) { - $result = phpbb_chmod($filename, 'write-all'); + break; } - } - } - // Check for is_readable - if ($mode == 'rread') - { - if (!is_readable($filename)) - { - $result = phpbb_chmod($filename, 'sread'); + case 'group': + $result = @chmod($filename, ($owner << 6) + ($perms << 3) + (0 << 0)); - if (!is_readable($filename)) + if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename)))) { - $result = phpbb_chmod($filename, 'read'); + break; } - } + + case 'other': + $result = @chmod($filename, ($owner << 6) + ($perms << 3) + ($perms << 0)); + + if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename)))) + { + break; + } + + default: + return false; + break; } return $result; diff --git a/phpBB/includes/functions_compress.php b/phpBB/includes/functions_compress.php index 18106a155b..881e1ba5cc 100644 --- a/phpBB/includes/functions_compress.php +++ b/phpBB/includes/functions_compress.php @@ -228,7 +228,7 @@ class compress_zip extends compress { trigger_error("Could not create directory $folder"); } - phpbb_chmod($str, 'rwrite'); + phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE); } } } @@ -257,7 +257,7 @@ class compress_zip extends compress { trigger_error("Could not create directory $folder"); } - phpbb_chmod($str, 'rwrite'); + phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE); } } } @@ -544,7 +544,7 @@ class compress_tar extends compress { trigger_error("Could not create directory $folder"); } - phpbb_chmod($str, 'rwrite'); + phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE); } } } @@ -571,7 +571,7 @@ class compress_tar extends compress { trigger_error("Could not create directory $folder"); } - phpbb_chmod($str, 'rwrite'); + phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE); } } @@ -580,7 +580,7 @@ class compress_tar extends compress { trigger_error("Couldn't create file $filename"); } - phpbb_chmod($target_filename, 'rwrite'); + phpbb_chmod($target_filename, CHMOD_READ); // Grab the file contents fwrite($fp, ($filesize) ? $fzread($this->fp, ($filesize + 511) &~ 511) : '', $filesize); diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index 98cf3b123d..7583ed48fc 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -562,7 +562,7 @@ class queue $fp = @fopen($this->cache_file . '.lock', 'wb'); fclose($fp); - phpbb_chmod($this->cache_file . '.lock', 'write-all'); + @chmod($this->cache_file . '.lock', 0777); include($this->cache_file); @@ -697,7 +697,7 @@ class queue @flock($fp, LOCK_UN); fclose($fp); - phpbb_chmod($this->cache_file, 'rwrite'); + phpbb_chmod($this->cache_file, CHMOD_WRITE); } } @@ -738,7 +738,7 @@ class queue @flock($fp, LOCK_UN); fclose($fp); - phpbb_chmod($this->cache_file, 'rwrite'); + phpbb_chmod($this->cache_file, CHMOD_WRITE); } } } diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index fd682bfcbc..ce99086a74 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -729,7 +729,7 @@ function create_thumbnail($source, $destination, $mimetype) return false; } - phpbb_chmod($destination, 'rwrite'); + phpbb_chmod($destination, CHMOD_READ | CHMOD_WRITE); return true; } diff --git a/phpBB/includes/functions_template.php b/phpBB/includes/functions_template.php index 26a309f8c5..3454c47d3e 100644 --- a/phpBB/includes/functions_template.php +++ b/phpBB/includes/functions_template.php @@ -755,7 +755,7 @@ class template_compile @flock($fp, LOCK_UN); @fclose($fp); - phpbb_chmod($filename, 'rwrite'); + phpbb_chmod($filename, CHMOD_WRITE); } return; diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index aaec7a28e4..f3363992cf 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -263,11 +263,10 @@ class filespec * * @param string $destination_path Destination path, for example $config['avatar_path'] * @param bool $overwrite If set to true, an already existing file will be overwritten - * @param string $chmod Permission mask for chmodding the file after a successful move. The mode entered here reflects the mode of phpbb_chmod() + * @param string $chmod Permission mask for chmodding the file after a successful move. The mode entered here reflects the mode of {@inline phpbb_chmod()} * @access public - * @see phpbb_chmod() */ - function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = 'rwrite') + function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false) { global $user, $phpbb_root_path; @@ -276,6 +275,8 @@ class filespec return false; } + $chmod = ($chmod === false) ? CHMOD_READ | CHMOD_WRITE : $chmod; + // We need to trust the admin in specifying valid upload directories and an attacker not being able to overwrite it... $this->destination_path = $phpbb_root_path . $destination; @@ -346,15 +347,7 @@ class filespec break; } - // Backward compatibility - in versions prior to 3.0.3 $chmod was an octal - if (!is_string($chmod)) - { - @chmod($this->destination_file, $chmod); - } - else - { - phpbb_chmod($this->destination_file, $chmod); - } + phpbb_chmod($this->destination_file, $chmod); } // Try to get real filesize from destination folder |