function banPermissions() { global $user_info, $sourcedir, $modSettings, $context; // Somehow they got here, at least take away all permissions... if (isset($_SESSION['ban']['cannot_access'])) { $user_info['permissions'] = array(); } elseif (isset($_SESSION['ban']['cannot_post']) || !empty($modSettings['warning_mute']) && $modSettings['warning_mute'] <= $user_info['warning']) { $denied_permissions = array('pm_send', 'calendar_post', 'calendar_edit_own', 'calendar_edit_any', 'poll_post', 'poll_add_own', 'poll_add_any', 'poll_edit_own', 'poll_edit_any', 'poll_lock_own', 'poll_lock_any', 'poll_remove_own', 'poll_remove_any', 'manage_attachments', 'manage_smileys', 'manage_boards', 'admin_forum', 'manage_permissions', 'moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'edit_news', 'profile_identity_any', 'profile_extra_any', 'profile_title_any', 'post_new', 'post_reply_own', 'post_reply_any', 'delete_own', 'delete_any', 'delete_replies', 'make_sticky', 'merge_any', 'split_any', 'modify_own', 'modify_any', 'modify_replies', 'move_any', 'send_topic', 'lock_own', 'lock_any', 'remove_own', 'remove_any', 'post_unapproved_topics', 'post_unapproved_replies_own', 'post_unapproved_replies_any'); $user_info['permissions'] = array_diff($user_info['permissions'], $denied_permissions); } elseif (!empty($modSettings['warning_moderate']) && $modSettings['warning_moderate'] <= $user_info['warning']) { // Work out what permissions should change... $permission_change = array('post_new' => 'post_unapproved_topics', 'post_reply_own' => 'post_unapproved_replies_own', 'post_reply_any' => 'post_unapproved_replies_any', 'post_attachment' => 'post_unapproved_attachments'); foreach ($permission_change as $old => $new) { if (!in_array($old, $user_info['permissions'])) { unset($permission_change[$old]); } else { $user_info['permissions'][] = $new; } } $user_info['permissions'] = array_diff($user_info['permissions'], array_keys($permission_change)); } //!!! Find a better place to call this? Needs to be after permissions loaded! // Finally, some bits we cache in the session because it saves queries. if (isset($_SESSION['mc']) && $_SESSION['mc']['time'] > $modSettings['settings_updated'] && $_SESSION['mc']['id'] == $user_info['id']) { $user_info['mod_cache'] = $_SESSION['mc']; } else { require_once $sourcedir . '/Subs-Auth.php'; rebuildModCache(); } // Now that we have the mod cache taken care of lets setup a cache for the number of mod reports still open if (isset($_SESSION['rc']) && $_SESSION['rc']['time'] > $modSettings['last_mod_report_action'] && $_SESSION['rc']['id'] == $user_info['id']) { $context['open_mod_reports'] = $_SESSION['rc']['reports']; } elseif ($_SESSION['mc']['bq'] != '0=1') { require_once $sourcedir . '/ModerationCenter.php'; recountOpenReports(); } else { $context['open_mod_reports'] = 0; } }
function loadPermissions() { global $user_info, $board, $board_info, $modSettings, $sourcedir; if ($user_info['is_admin']) { banPermissions(); return; } if (!empty($modSettings['cache_enable'])) { $cache_groups = $user_info['groups']; asort($cache_groups); $cache_groups = implode(',', $cache_groups); // If it's a spider then cache it different. if ($user_info['possibly_robot']) { $cache_groups .= '-spider'; } if ($modSettings['cache_enable'] >= 2 && !empty($board) && ($temp = CacheAPI::getCache('permissions:' . $cache_groups . ':' . $board, 240)) != null && time() - 240 > $modSettings['settings_updated']) { list($user_info['permissions']) = $temp; banPermissions(); return; } elseif (($temp = CacheAPI::getCache('permissions:' . $cache_groups, 240)) != null && time() - 240 > $modSettings['settings_updated']) { list($user_info['permissions'], $removals) = $temp; } } // If it is detected as a robot, and we are restricting permissions as a special group - then implement this. $spider_restrict = $user_info['possibly_robot'] && !empty($modSettings['spider_group']) ? ' OR (id_group = {int:spider_group} && add_deny = 0)' : ''; if (empty($user_info['permissions'])) { // Get the general permissions. $request = smf_db_query(' SELECT permission, add_deny FROM {db_prefix}permissions WHERE id_group IN ({array_int:member_groups}) ' . $spider_restrict, array('member_groups' => $user_info['groups'], 'spider_group' => !empty($modSettings['spider_group']) ? $modSettings['spider_group'] : 0)); $removals = array(); while ($row = mysql_fetch_assoc($request)) { if (empty($row['add_deny'])) { $removals[] = $row['permission']; } else { $user_info['permissions'][] = $row['permission']; } } mysql_free_result($request); if (isset($cache_groups)) { CacheAPI::putCache('permissions:' . $cache_groups, array($user_info['permissions'], $removals), 240); } } // Get the board permissions. if (!empty($board)) { // Make sure the board (if any) has been loaded by loadBoard(). if (!isset($board_info['profile'])) { fatal_lang_error('no_board'); } $request = smf_db_query(' SELECT permission, add_deny FROM {db_prefix}board_permissions WHERE (id_group IN ({array_int:member_groups}) ' . $spider_restrict . ') AND id_profile = {int:id_profile}', array('member_groups' => $user_info['groups'], 'id_profile' => $board_info['profile'], 'spider_group' => !empty($modSettings['spider_group']) ? $modSettings['spider_group'] : 0)); while ($row = mysql_fetch_assoc($request)) { if (empty($row['add_deny'])) { $removals[] = $row['permission']; } else { $user_info['permissions'][] = $row['permission']; } } mysql_free_result($request); } // Remove all the permissions they shouldn't have ;). if (!empty($modSettings['permission_enable_deny'])) { $user_info['permissions'] = array_diff($user_info['permissions'], $removals); } if (isset($cache_groups) && !empty($board) && $modSettings['cache_enable'] >= 2) { CacheAPI::putCache('permissions:' . $cache_groups . ':' . $board, array($user_info['permissions'], null), 240); } // Banned? Watch, don't touch.. banPermissions(); // Load the mod cache so we can know what additional boards they should see, but no sense in doing it for guests if (!$user_info['is_guest']) { if (!isset($_SESSION['mc']) || $_SESSION['mc']['time'] <= $modSettings['settings_updated']) { require_once $sourcedir . '/lib/Subs-Auth.php'; rebuildModCache(); } else { $user_info['mod_cache'] = $_SESSION['mc']; } } }
function loadUserSettings() { global $modSettings, $user_settings, $sourcedir, $smcFunc; global $cookiename, $user_info, $language; // Check first the integration, then the cookie, and last the session. if (isset($modSettings['integrate_verify_user']) && is_callable($modSettings['integrate_verify_user'])) { $id_member = (int) call_user_func(strpos($modSettings['integrate_verify_user'], '::') === false ? $modSettings['integrate_verify_user'] : explode('::', $modSettings['integrate_verify_user'])); $already_verified = $id_member > 0; } else { $id_member = 0; } if (empty($id_member) && isset($_COOKIE[$cookiename])) { // Fix a security hole in PHP 4.3.9 and below... if (preg_match('~^a:[34]:\\{i:0;(i:\\d{1,6}|s:[1-8]:"\\d{1,8}");i:1;s:(0|40):"([a-fA-F0-9]{40})?";i:2;[id]:\\d{1,14};(i:3;i:\\d;)?\\}$~i', $_COOKIE[$cookiename]) == 1) { list($id_member, $password) = @unserialize($_COOKIE[$cookiename]); $id_member = !empty($id_member) && strlen($password) > 0 ? (int) $id_member : 0; } else { $id_member = 0; } } elseif (empty($id_member) && isset($_SESSION['login_' . $cookiename]) && ($_SESSION['USER_AGENT'] == $_SERVER['HTTP_USER_AGENT'] || !empty($modSettings['disableCheckUA']))) { // !!! Perhaps we can do some more checking on this, such as on the first octet of the IP? list($id_member, $password, $login_span) = @unserialize($_SESSION['login_' . $cookiename]); $id_member = !empty($id_member) && strlen($password) == 40 && $login_span > time() ? (int) $id_member : 0; } // Only load this stuff if the user isn't a guest. if ($id_member != 0) { // Is the member data cached? if (empty($modSettings['cache_enable']) || $modSettings['cache_enable'] < 2 || ($user_settings = cache_get_data('user_settings-' . $id_member, 60)) == null) { $request = $smcFunc['db_query']('', ' SELECT mem.*, IFNULL(a.id_attach, 0) AS id_attach, a.filename, a.attachment_type FROM {db_prefix}members AS mem LEFT JOIN {db_prefix}attachments AS a ON (a.id_member = {int:id_member}) WHERE mem.id_member = {int:id_member} LIMIT 1', array('id_member' => $id_member)); $user_settings = $smcFunc['db_fetch_assoc']($request); $smcFunc['db_free_result']($request); if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2) { cache_put_data('user_settings-' . $id_member, $user_settings, 60); } } // Did we find 'im? If not, junk it. if (!empty($user_settings)) { // As much as the password should be right, we can assume the integration set things up. if (!empty($already_verified) && $already_verified === true) { $check = true; } elseif (strlen($password) == 40) { $check = sha1($user_settings['passwd'] . $user_settings['password_salt']) == $password; } else { $check = false; } // Wrong password or not activated - either way, you're going nowhere. $id_member = $check && ($user_settings['is_activated'] == 1 || $user_settings['is_activated'] == 11) ? $user_settings['id_member'] : 0; } else { $id_member = 0; } // If we no longer have the member maybe they're being all hackey, stop brute force! if (!$id_member || !empty($user_settings['passwd_flood'])) { require_once $sourcedir . '/LogInOut.php'; validatePasswordFlood(!empty($user_settings['id_member']) ? $user_settings['id_member'] : $id_member, !empty($user_settings['passwd_flood']) ? $user_settings['passwd_flood'] : false, $id_member != 0); } } // Found 'im, let's set up the variables. if ($id_member != 0) { // Let's not update the last visit time in these cases... // 1. SSI doesn't count as visiting the forum. // 2. RSS feeds and XMLHTTP requests don't count either. // 3. If it was set within this session, no need to set it again. // 4. New session, yet updated < five hours ago? Maybe cache can help. if (SMF != 'SSI' && !isset($_REQUEST['xml']) && (!isset($_REQUEST['action']) || $_REQUEST['action'] != '.xml') && empty($_SESSION['id_msg_last_visit']) && (empty($modSettings['cache_enable']) || ($_SESSION['id_msg_last_visit'] = cache_get_data('user_last_visit-' . $id_member, 5 * 3600)) === null)) { // Do a quick query to make sure this isn't a mistake. $result = $smcFunc['db_query']('', ' SELECT poster_time FROM {db_prefix}messages WHERE id_msg = {int:id_msg} LIMIT 1', array('id_msg' => $user_settings['id_msg_last_visit'])); list($visitTime) = $smcFunc['db_fetch_row']($result); $smcFunc['db_free_result']($result); $_SESSION['id_msg_last_visit'] = $user_settings['id_msg_last_visit']; // If it was *at least* five hours ago... if ($visitTime < time() - 5 * 3600) { updateMemberData($id_member, array('id_msg_last_visit' => (int) $modSettings['maxMsgID'], 'last_login' => time(), 'member_ip' => $_SERVER['REMOTE_ADDR'], 'member_ip2' => $_SERVER['BAN_CHECK_IP'])); $user_settings['last_login'] = time(); if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2) { cache_put_data('user_settings-' . $id_member, $user_settings, 60); } if (!empty($modSettings['cache_enable'])) { cache_put_data('user_last_visit-' . $id_member, $_SESSION['id_msg_last_visit'], 5 * 3600); } } } elseif (empty($_SESSION['id_msg_last_visit'])) { $_SESSION['id_msg_last_visit'] = $user_settings['id_msg_last_visit']; } $username = $user_settings['member_name']; if (empty($user_settings['additional_groups'])) { $user_info = array('groups' => array($user_settings['id_group'], $user_settings['id_post_group'])); } else { $user_info = array('groups' => array_merge(array($user_settings['id_group'], $user_settings['id_post_group']), explode(',', $user_settings['additional_groups']))); } // Because history has proven that it is possible for groups to go bad - clean up in case. foreach ($user_info['groups'] as $k => $v) { $user_info['groups'][$k] = (int) $v; } // This is a logged in user, so definitely not a spider. $user_info['possibly_robot'] = false; } else { // This is what a guest's variables should be. $username = ''; $user_info = array('groups' => array(-1)); $user_settings = array(); if (isset($_COOKIE[$cookiename])) { $_COOKIE[$cookiename] = ''; } // Do we perhaps think this is a search robot? Check every five minutes just in case... if ((!empty($modSettings['spider_mode']) || !empty($modSettings['spider_group'])) && (!isset($_SESSION['robot_check']) || $_SESSION['robot_check'] < time() - 300)) { require_once $sourcedir . '/ManageSearchEngines.php'; $user_info['possibly_robot'] = SpiderCheck(); } elseif (!empty($modSettings['spider_mode'])) { $user_info['possibly_robot'] = isset($_SESSION['id_robot']) ? $_SESSION['id_robot'] : 0; } else { $ci_user_agent = strtolower($_SERVER['HTTP_USER_AGENT']); $user_info['possibly_robot'] = strpos($_SERVER['HTTP_USER_AGENT'], 'Mozilla') === false && strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') === false || strpos($ci_user_agent, 'googlebot') !== false || strpos($ci_user_agent, 'slurp') !== false || strpos($ci_user_agent, 'crawl') !== false; } } // Set up the $user_info array. $user_info += array('id' => $id_member, 'username' => $username, 'name' => isset($user_settings['real_name']) ? $user_settings['real_name'] : '', 'email' => isset($user_settings['email_address']) ? $user_settings['email_address'] : '', 'passwd' => isset($user_settings['passwd']) ? $user_settings['passwd'] : '', 'language' => empty($user_settings['lngfile']) || empty($modSettings['userLanguage']) ? $language : $user_settings['lngfile'], 'is_guest' => $id_member == 0, 'is_admin' => in_array(1, $user_info['groups']), 'theme' => empty($user_settings['id_theme']) ? 0 : $user_settings['id_theme'], 'last_login' => empty($user_settings['last_login']) ? 0 : $user_settings['last_login'], 'ip' => $_SERVER['REMOTE_ADDR'], 'ip2' => $_SERVER['BAN_CHECK_IP'], 'posts' => empty($user_settings['posts']) ? 0 : $user_settings['posts'], 'time_format' => empty($user_settings['time_format']) ? $modSettings['time_format'] : $user_settings['time_format'], 'time_offset' => empty($user_settings['time_offset']) ? 0 : $user_settings['time_offset'], 'avatar' => array('url' => isset($user_settings['avatar']) ? $user_settings['avatar'] : '', 'filename' => empty($user_settings['filename']) ? '' : $user_settings['filename'], 'custom_dir' => !empty($user_settings['attachment_type']) && $user_settings['attachment_type'] == 1, 'id_attach' => isset($user_settings['id_attach']) ? $user_settings['id_attach'] : 0), 'smiley_set' => isset($user_settings['smiley_set']) ? $user_settings['smiley_set'] : '', 'messages' => empty($user_settings['instant_messages']) ? 0 : $user_settings['instant_messages'], 'unread_messages' => empty($user_settings['unread_messages']) ? 0 : $user_settings['unread_messages'], 'total_time_logged_in' => empty($user_settings['total_time_logged_in']) ? 0 : $user_settings['total_time_logged_in'], 'buddies' => !empty($modSettings['enable_buddylist']) && !empty($user_settings['buddy_list']) ? explode(',', $user_settings['buddy_list']) : array(), 'ignoreboards' => !empty($user_settings['ignore_boards']) && !empty($modSettings['allow_ignore_boards']) ? explode(',', $user_settings['ignore_boards']) : array(), 'ignoreusers' => !empty($user_settings['pm_ignore_list']) ? explode(',', $user_settings['pm_ignore_list']) : array(), 'warning' => isset($user_settings['warning']) ? $user_settings['warning'] : 0, 'permissions' => array(), 'awards' => isset($user_settings['awards']) ? $user_settings['awards'] : array()); $user_info['groups'] = array_unique($user_info['groups']); // Make sure that the last item in the ignore boards array is valid. If the list was too long it could have an ending comma that could cause problems. if (!empty($user_info['ignoreboards']) && empty($user_info['ignoreboards'][$tmp = count($user_info['ignoreboards']) - 1])) { unset($user_info['ignoreboards'][$tmp]); } // Do we have any languages to validate this? if (!empty($modSettings['userLanguage']) && (!empty($_GET['language']) || !empty($_SESSION['language']))) { $languages = getLanguages(); } // Allow the user to change their language if its valid. if (!empty($modSettings['userLanguage']) && !empty($_GET['language']) && isset($languages[strtr($_GET['language'], './\\:', '____')])) { $user_info['language'] = strtr($_GET['language'], './\\:', '____'); $_SESSION['language'] = $user_info['language']; } elseif (!empty($modSettings['userLanguage']) && !empty($_SESSION['language']) && isset($languages[strtr($_SESSION['language'], './\\:', '____')])) { $user_info['language'] = strtr($_SESSION['language'], './\\:', '____'); } // Just build this here, it makes it easier to change/use - administrators can see all boards. if ($user_info['is_admin']) { $user_info['query_see_board'] = '1=1'; } else { $user_info['query_see_board'] = '(FIND_IN_SET(' . implode(', b.member_groups) != 0 OR FIND_IN_SET(', $user_info['groups']) . ', b.member_groups) != 0' . (isset($user_info['mod_cache']) ? ' OR ' . $user_info['mod_cache']['mq'] : '') . ')'; } // Load the mod cache so we can know what additional boards they should see, but no sense in doing it for admins and guests if (!$user_info['is_guest'] && !$user_info['is_admin']) { if (!isset($_SESSION['mc']) || $_SESSION['mc']['time'] <= $modSettings['settings_updated']) { require_once $sourcedir . '/Subs-Auth.php'; rebuildModCache(); } else { $user_info['mod_cache'] = $_SESSION['mc']; } } // Build the list of boards they WANT to see. // This will take the place of query_see_boards in certain spots, so it better include the boards they can see also // If they aren't ignoring any boards then they want to see all the boards they can see if (empty($user_info['ignoreboards'])) { $user_info['query_wanna_see_board'] = $user_info['query_see_board']; } else { $user_info['query_wanna_see_board'] = '(' . $user_info['query_see_board'] . ' AND b.id_board NOT IN (' . implode(',', $user_info['ignoreboards']) . '))'; } }