Esempio n. 1
0
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                     //
//                                                                            //
//   You should have received a copy of the Phorum License                    //
//   along with this program.                                                 //
////////////////////////////////////////////////////////////////////////////////
define('phorum_page', 'read');
include_once "./common.php";
include_once "./include/email_functions.php";
include_once "./include/format_functions.php";
// for dev-purposes ..
//include_once('./include/timing.php');
//timing_start();
// set all our URL's ... we need these earlier
phorum_build_common_urls();
// checking read-permissions
if (!phorum_check_read_common()) {
    return;
}
// somehow we got to a folder
if ($PHORUM["folder_flag"]) {
    $dest_url = phorum_get_url(PHORUM_INDEX_URL, $PHORUM["forum_id"]);
    phorum_redirect_by_url($dest_url);
    exit;
}
$newflagkey = $PHORUM["forum_id"] . "-" . $PHORUM['user']['user_id'];
if ($PHORUM["DATA"]["LOGGEDIN"]) {
    // reading newflags in
    $PHORUM['user']['newinfo'] = null;
    if ($PHORUM['cache_newflags']) {
        $PHORUM['user']['newinfo'] = phorum_cache_get('newflags', $newflagkey, $PHORUM['cache_version']);
    }
Esempio n. 2
0
/**
 * Check if a file exists and if the active user has permission to read it.
 *
 * The function will return either an array containing descriptive data
 * for the file or FALSE, in case access was not granted.
 *
 * Note that the file_data field is not available in the return array.
 * That data can be retrieved by the {@link phorum_api_file_retrieve()}
 * function.
 *
 * @param integer $file_id
 *     The file_id of the file for which to check read access.
 *
 * @param integer $flags
 *     If the {@link PHORUM_FLAG_IGNORE_PERMS} flag is used, then permission
 *     checks are fully bypassed. In this case, the function will only check
 *     if the file exists or not.
 *
 * @return mixed
 *     On error, this function will return FALSE.
 *     The functions {@link phorum_api_strerror()} and
 *     {@link phorum_api_errno()} can be used to retrieve information about
 *     the error which occurred.
 *
 *     On success, it returns an array containing descriptive data for
 *     the file. The following fields are available in this array:
 *     <ul>
 *     <li>file_id: The file_id for the requested file.</li>
 *     <li>filename: The name of the file.</li>
 *     <li>filesize: The size of the file in bytes.</li>
 *     <li>add_datetime: Epoch timestamp describing at what time
 *         the file was stored.</li>
 *     <li>message_id: The message to which a message is linked
 *         (in case it is a message attachment).</li>
 *     <li>user_id: The user to which a message is linked
 *         (in case it is a private user file).</li>
 *     <li>link: A value describing to what type of entity the file is
 *         linked. One of {@link PHORUM_LINK_USER},
 *         {@link PHORUM_LINK_MESSAGE}, {@link PHORUM_LINK_EDITOR} and
 *         {@link PHORUM_LINK_TEMPFILE}.</li>
 *     </ul>
 */
function phorum_api_file_check_read_access($file_id, $flags = 0)
{
    global $PHORUM;
    settype($file_id, "int");
    // Reset error storage.
    $GLOBALS["PHORUM"]["API"]["errno"] = NULL;
    $GLOBALS["PHORUM"]["API"]["error"] = NULL;
    // Check if the active user has read access for the active forum_id.
    if (!$flags & PHORUM_FLAG_IGNORE_PERMS && !phorum_check_read_common()) {
        return phorum_api_error_set(PHORUM_ERRNO_NOACCESS, "Read permission for file (id {$file_id}) denied.");
    }
    // Retrieve the descriptive file data for the file from the database.
    // Return an error if the file does not exist.
    $file = phorum_db_file_get($file_id, FALSE);
    if (empty($file)) {
        return phorum_api_error_set(PHORUM_ERRNO_NOTFOUND, "The requested file (id {$file_id}) was not found.");
    }
    // For the standard database based file storage, we do not have to
    // do checks for checking file existence (since the data is in the
    // database and we found the record for it). Storage modules might
    // have to do additional checks though (e.g. to see if the file data
    // exists on disk), so here we give them a chance to check for it.
    // This hook can also be used for implementing additional access
    // rules. The hook can use phorum_api_error_set() to return an error.
    // Hooks should be aware that their input might not be $file, but
    // FALSE instead, in which case they should immediately return
    // FALSE themselves.
    if (isset($PHORUM["hooks"]["file_check_read_access"])) {
        $file = phorum_hook("file_check_read_access", $file, $flags);
        if ($file === FALSE) {
            return FALSE;
        }
    }
    // If we do not do any permission checking, then we are done.
    if ($flags & PHORUM_FLAG_IGNORE_PERMS) {
        return $file;
    }
    // Is the file linked to a forum message? In that case, we have to
    // check if the message does really belong to the requested forum_id.
    if ($file["link"] == PHORUM_LINK_MESSAGE && !empty($file["message_id"])) {
        // Retrieve the message. If retrieving the message is not possible
        // or if the forum if of the message is different from the requested
        // forum_id, then return an error.
        $message = phorum_db_get_message($file["message_id"], "message_id", TRUE);
        if (empty($message)) {
            return phorum_api_error_set(PHORUM_ERRNO_INTEGRITY, "An integrity problem was detected in the database: " . "file id {$file_id} is linked to non existent " . "message_id {$file["message_id"]}.");
        }
        if ($message["forum_id"] != $PHORUM["forum_id"]) {
            return phorum_api_error_set(PHORUM_ERRNO_NOACCESS, "Permission denied for reading the file: it does not " . "belong to the requested forum_id {$PHORUM["forum_id"]}.");
        }
    }
    // A general purpose URL host matching regexp, that we'll use below.
    $matchhost = '!^https?://([^/]+)/!i';
    // See if off site links are allowed. If this is not the case, then
    // check if an off site link is requested. We use the HTTP_REFERER for
    // doing the off site link check. This is not a water proof solution
    // (since HTTP referrers can be faked), but it will be good enough for
    // stopping the majority of the off site requests.
    if (isset($_SERVER["HTTP_REFERER"]) && $PHORUM["file_offsite"] != PHORUM_OFFSITE_ANYSITE && preg_match($matchhost, $_SERVER["HTTP_REFERER"])) {
        // Generate the base URL for the Phorum.
        $base = strtolower(phorum_get_url(PHORUM_BASE_URL));
        // Strip query string from the base URL. We mainly want to
        // check if the location matches the Phorum location.
        // Otherwise, we might get in troubles with things like
        // URI authentication, where a session id is added to the URL.
        $base = preg_replace('/\\?.*$/', '', $base);
        // FORUMONLY: Links to forum files are only allowed from the forum.
        // Check if the referrer URL starts with the base Phorum URL.
        if ($PHORUM["file_offsite"] == PHORUM_OFFSITE_FORUMONLY) {
            $refbase = substr($_SERVER["HTTP_REFERER"], 0, strlen($base));
            if (strcasecmp($base, $refbase) != 0) {
                return phorum_api_error_set(PHORUM_ERRNO_NOACCESS, "Permission denied: links to files in the forum are " . "only allowed from the forum itself.");
            }
        } elseif ($PHORUM["file_offsite"] == PHORUM_OFFSITE_THISSITE) {
            if (preg_match($matchhost, $_SERVER["HTTP_REFERER"], $rm) && preg_match($matchhost, $base, $bm) && strcasecmp($rm[1], $bm[1]) != 0) {
                return phorum_api_error_set(PHORUM_ERRNO_NOACCESS, "Permission denied: links to files in the forum are " . "only allowed from this web site.");
            }
        }
    }
    return $file;
}