diff options
Diffstat (limited to 'phpBB/includes')
-rw-r--r-- | phpBB/includes/acp/acp_forums.php | 3 | ||||
-rw-r--r-- | phpBB/includes/acp/acp_users.php | 5 | ||||
-rw-r--r-- | phpBB/includes/captcha/plugins/captcha_abstract.php | 8 | ||||
-rw-r--r-- | phpBB/includes/functions.php | 186 | ||||
-rw-r--r-- | phpBB/includes/functions_admin.php | 82 | ||||
-rw-r--r-- | phpBB/includes/functions_posting.php | 2 | ||||
-rw-r--r-- | phpBB/includes/functions_user.php | 38 | ||||
-rw-r--r-- | phpBB/includes/mcp/mcp_main.php | 35 | ||||
-rw-r--r-- | phpBB/includes/mcp/mcp_post.php | 2 | ||||
-rw-r--r-- | phpBB/includes/session.php | 2 | ||||
-rw-r--r-- | phpBB/includes/ucp/ucp_profile.php | 5 | ||||
-rw-r--r-- | phpBB/includes/ucp/ucp_register.php | 6 | ||||
-rw-r--r-- | phpBB/includes/ucp/ucp_remind.php | 4 |
13 files changed, 294 insertions, 84 deletions
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index f2f1bd80e2..4d9b9f01e0 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -1642,6 +1642,9 @@ class acp_forums delete_attachments('topic', $topic_ids, false); + // Delete shadow topics pointing to topics in this forum + delete_topic_shadows($forum_id); + // Before we remove anything we make sure we are able to adjust the post counts later. ;) $sql = 'SELECT poster_id FROM ' . POSTS_TABLE . ' diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 1f10893781..9e8a4c80b9 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -319,10 +319,7 @@ class acp_users $server_url = generate_board_url(); - $user_actkey = gen_rand_string(10); - $key_len = 54 - (strlen($server_url)); - $key_len = ($key_len > 6) ? $key_len : 6; - $user_actkey = substr($user_actkey, 0, $key_len); + $user_actkey = gen_rand_string(mt_rand(6, 10)); $email_template = ($user_row['user_type'] == USER_NORMAL) ? 'user_reactivate_account' : 'user_resend_inactive'; if ($user_row['user_type'] == USER_NORMAL) diff --git a/phpBB/includes/captcha/plugins/captcha_abstract.php b/phpBB/includes/captcha/plugins/captcha_abstract.php index e7b8742b05..21cacd730c 100644 --- a/phpBB/includes/captcha/plugins/captcha_abstract.php +++ b/phpBB/includes/captcha/plugins/captcha_abstract.php @@ -59,7 +59,7 @@ class phpbb_default_captcha { global $user; - $this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); + $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); $this->seed = hexdec(substr(unique_id(), 4, 10)); // compute $seed % 0x7fffffff @@ -235,7 +235,7 @@ class phpbb_default_captcha { global $db, $user; - $this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); + $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); $this->confirm_id = md5(unique_id($user->ip)); $this->seed = hexdec(substr(unique_id(), 4, 10)); $this->solved = 0; @@ -259,7 +259,7 @@ class phpbb_default_captcha { global $db, $user; - $this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); + $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); $this->seed = hexdec(substr(unique_id(), 4, 10)); $this->solved = 0; // compute $seed % 0x7fffffff @@ -281,7 +281,7 @@ class phpbb_default_captcha { global $db, $user; - $this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); + $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); $this->seed = hexdec(substr(unique_id(), 4, 10)); $this->solved = 0; // compute $seed % 0x7fffffff diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 4c461b5ee8..36b9e18176 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -195,10 +195,27 @@ function set_config_count($config_name, $increment, $is_dynamic = false) /** * Generates an alphanumeric random string of given length +* +* @return string */ function gen_rand_string($num_chars = 8) { + // [a, z] + [0, 9] = 36 + return substr(strtoupper(base_convert(unique_id(), 16, 36)), 0, $num_chars); +} + +/** +* Generates a user-friendly alphanumeric random string of given length +* We remove 0 and O so users cannot confuse those in passwords etc. +* +* @return string +*/ +function gen_rand_string_friendly($num_chars = 8) +{ $rand_str = unique_id(); + + // Remove Z and Y from the base_convert(), replace 0 with Z and O with Y + // [a, z] + [0, 9] - {z, y} = [a, z] + [0, 9] - {0, o} = 34 $rand_str = str_replace(array('0', 'O'), array('Z', 'Y'), strtoupper(base_convert($rand_str, 16, 34))); return substr($rand_str, 0, $num_chars); @@ -3445,26 +3462,110 @@ function short_ipv6($ip, $length) /** * Wrapper for php's checkdnsrr function. * -* The windows failover is from the php manual -* Please make sure to check the return value for === true and === false, since NULL could -* be returned too. +* @param string $host Fully-Qualified Domain Name +* @param string $type Resource record type to lookup +* Supported types are: MX (default), A, AAAA, NS, TXT, CNAME +* Other types may work or may not work +* +* @return mixed true if entry found, +* false if entry not found, +* null if this function is not supported by this environment * -* @return true if entry found, false if not, NULL if this function is not supported by this environment +* Since null can also be returned, you probably want to compare the result +* with === true or === false, +* +* @author bantu */ -function phpbb_checkdnsrr($host, $type = '') +function phpbb_checkdnsrr($host, $type = 'MX') { - $type = (!$type) ? 'MX' : $type; + // The dot indicates to search the DNS root (helps those having DNS prefixes on the same domain) + if (substr($host, -1) == '.') + { + $host_fqdn = $host; + $host = substr($host, 0, -1); + } + else + { + $host_fqdn = $host . '.'; + } + // $host has format some.host.example.com + // $host_fqdn has format some.host.example.com. - // Call checkdnsrr() if available. This is also the case on Windows with PHP 5.3 or later. - if (function_exists('checkdnsrr')) + // If we're looking for an A record we can use gethostbyname() + if ($type == 'A' && function_exists('gethostbyname')) { - // The dot indicates to search the DNS root (helps those having DNS prefixes on the same domain) - return checkdnsrr($host . '.', $type); + return (@gethostbyname($host_fqdn) == $host_fqdn) ? false : true; } - else if (DIRECTORY_SEPARATOR == '\\' && function_exists('exec')) + + // checkdnsrr() is available on Windows since PHP 5.3, + // but until 5.3.3 it only works for MX records + // See: http://bugs.php.net/bug.php?id=51844 + + // Call checkdnsrr() if + // we're looking for an MX record or + // we're not on Windows or + // we're running a PHP version where #51844 has been fixed + + // checkdnsrr() supports AAAA since 5.0.0 + // checkdnsrr() supports TXT since 5.2.4 + if ( + ($type == 'MX' || DIRECTORY_SEPARATOR != '\\' || version_compare(PHP_VERSION, '5.3.3', '>=')) && + ($type != 'AAAA' || version_compare(PHP_VERSION, '5.0.0', '>=')) && + ($type != 'TXT' || version_compare(PHP_VERSION, '5.2.4', '>=')) && + function_exists('checkdnsrr') + ) + { + return checkdnsrr($host_fqdn, $type); + } + + // dns_get_record() is available since PHP 5; since PHP 5.3 also on Windows, + // but on Windows it does not work reliable for AAAA records before PHP 5.3.1 + + // Call dns_get_record() if + // we're not looking for an AAAA record or + // we're not on Windows or + // we're running a PHP version where AAAA lookups work reliable + if ( + ($type != 'AAAA' || DIRECTORY_SEPARATOR != '\\' || version_compare(PHP_VERSION, '5.3.1', '>=')) && + function_exists('dns_get_record') + ) { - // @exec('nslookup -retry=1 -timout=1 -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host), $output); - @exec('nslookup -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host) . '.', $output); + // dns_get_record() expects an integer as second parameter + // We have to convert the string $type to the corresponding integer constant. + $type_constant = 'DNS_' . $type; + $type_param = (defined($type_constant)) ? constant($type_constant) : DNS_ANY; + + // dns_get_record() might throw E_WARNING and return false for records that do not exist + $resultset = @dns_get_record($host_fqdn, $type_param); + + if (empty($resultset) || !is_array($resultset)) + { + return false; + } + else if ($type_param == DNS_ANY) + { + // $resultset is a non-empty array + return true; + } + + foreach ($resultset as $result) + { + if ( + isset($result['host']) && $result['host'] == $host && + isset($result['type']) && $result['type'] == $type + ) + { + return true; + } + } + + return false; + } + + // If we're on Windows we can still try to call nslookup via exec() as a last resort + if (DIRECTORY_SEPARATOR == '\\' && function_exists('exec')) + { + @exec('nslookup -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host_fqdn), $output); // If output is empty, the nslookup failed if (empty($output)) @@ -3474,15 +3575,66 @@ function phpbb_checkdnsrr($host, $type = '') foreach ($output as $line) { - if (!trim($line)) + $line = trim($line); + + if (empty($line)) { continue; } - // Valid records begin with host name: - if (strpos($line, $host) === 0) + // Squash tabs and multiple whitespaces to a single whitespace. + $line = preg_replace('/\s+/', ' ', $line); + + switch ($type) { - return true; + case 'MX': + if (stripos($line, "$host MX") === 0) + { + return true; + } + break; + + case 'NS': + if (stripos($line, "$host nameserver") === 0) + { + return true; + } + break; + + case 'TXT': + if (stripos($line, "$host text") === 0) + { + return true; + } + break; + + case 'CNAME': + if (stripos($line, "$host canonical name") === 0) + { + return true; + } + + default: + case 'A': + case 'AAAA': + if (!empty($host_matches)) + { + // Second line + if (stripos($line, "Address: ") === 0) + { + return true; + } + else + { + $host_matches = false; + } + } + else if (stripos($line, "Name: $host") === 0) + { + // First line + $host_matches = true; + } + break; } } diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 89892feb30..3178d35c34 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -1125,53 +1125,65 @@ function delete_attachments($mode, $ids, $resync = true) } /** -* Remove topic shadows +* Deletes shadow topics pointing to a specified forum. +* +* @param int $forum_id The forum id +* @param string $sql_more Additional WHERE statement, e.g. t.topic_time < (time() - 1234) +* @param bool $auto_sync Will call sync() if this is true +* +* @return array Array with affected forums +* +* @author bantu */ -function delete_topic_shadows($max_age, $forum_id = '', $auto_sync = true) +function delete_topic_shadows($forum_id, $sql_more = '', $auto_sync = true) { - $where = (is_array($forum_id)) ? 'AND ' . $db->sql_in_set('t.forum_id', array_map('intval', $forum_id)) : (($forum_id) ? 'AND t.forum_id = ' . (int) $forum_id : ''); + global $db; - switch ($db->sql_layer) + if (!$forum_id) { - case 'mysql4': - case 'mysqli': - $sql = 'DELETE t.* - FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2 - WHERE t.topic_moved_id = t2.topic_id - AND t.topic_time < ' . (time() - $max_age) - . $where; - $db->sql_query($sql); - break; + // Nothing to do. + return; + } - default: - $sql = 'SELECT t.topic_id - FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2 - WHERE t.topic_moved_id = t2.topic_id - AND t.topic_time < ' . (time() - $max_age) - . $where; - $result = $db->sql_query($sql); + // Set of affected forums we have to resync + $sync_forum_ids = array(); - $topic_ids = array(); - while ($row = $db->sql_fetchrow($result)) - { - $topic_ids[] = $row['topic_id']; - } - $db->sql_freeresult($result); + // Amount of topics we select and delete at once. + $batch_size = 500; - if (sizeof($topic_ids)) - { - $sql = 'DELETE FROM ' . TOPICS_TABLE . ' - WHERE ' . $db->sql_in_set('topic_id', $topic_ids); - $db->sql_query($sql); - } - break; + do + { + $sql = 'SELECT t2.forum_id, t2.topic_id + FROM ' . TOPICS_TABLE . ' t2, ' . TOPICS_TABLE . ' t + WHERE t2.topic_moved_id = t.topic_id + AND t.forum_id = ' . (int) $forum_id . ' + ' . (($sql_more) ? 'AND ' . $sql_more : ''); + $result = $db->sql_query_limit($sql, $batch_size); + + $topic_ids = array(); + while ($row = $db->sql_fetchrow($result)) + { + $topic_ids[] = (int) $row['topic_id']; + + $sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id']; + } + $db->sql_freeresult($result); + + if (!empty($topic_ids)) + { + $sql = 'DELETE FROM ' . TOPICS_TABLE . ' + WHERE ' . $db->sql_in_set('topic_id', $topic_ids); + $db->sql_query($sql); + } } + while (sizeof($topic_ids) == $batch_size); if ($auto_sync) { - $where_type = ($forum_id) ? 'forum_id' : ''; - sync('forum', $where_type, $forum_id, true, true); + sync('forum', 'forum_id', $sync_forum_ids, true, true); } + + return $sync_forum_ids; } /** diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index f6f90575d4..5e25648eb8 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -2537,7 +2537,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u if ($mode == 'post' || $mode == 'reply' || $mode == 'quote') { // Mark this topic as posted to - markread('post', $data['forum_id'], $data['topic_id'], $data['post_time']); + markread('post', $data['forum_id'], $data['topic_id']); } // Mark this topic as read diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 0b26f28864..d3594196b7 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -766,7 +766,8 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas if (sizeof($ban_other) == 3 && ((int)$ban_other[0] < 9999) && (strlen($ban_other[0]) == 4) && (strlen($ban_other[1]) == 2) && (strlen($ban_other[2]) == 2)) { - $ban_end = max($current_time, gmmktime(0, 0, 0, (int)$ban_other[1], (int)$ban_other[2], (int)$ban_other[0])); + $time_offset = (isset($user->timezone) && isset($user->dst)) ? (int) $user->timezone + (int) $user->dst : 0; + $ban_end = max($current_time, gmmktime(0, 0, 0, (int)$ban_other[1], (int)$ban_other[2], (int)$ban_other[0]) - $time_offset); } else { @@ -1229,22 +1230,39 @@ function user_unban($mode, $ban) } /** -* Whois facility +* Internet Protocol Address Whois +* RFC3912: WHOIS Protocol Specification * -* @link http://tools.ietf.org/html/rfc3912 RFC3912: WHOIS Protocol Specification +* @param string $ip Ip address, either IPv4 or IPv6. +* +* @return string Empty string if not a valid ip address. +* Otherwise make_clickable()'ed whois result. */ function user_ipwhois($ip) { - $ipwhois = ''; + if (empty($ip)) + { + return ''; + } - // Check IP - // Only supporting IPv4 at the moment... - if (empty($ip) || !preg_match(get_preg_expression('ipv4'), $ip)) + if (preg_match(get_preg_expression('ipv4'), $ip)) + { + // IPv4 address + $whois_host = 'whois.arin.net.'; + } + else if (preg_match(get_preg_expression('ipv6'), $ip)) + { + // IPv6 address + $whois_host = 'whois.sixxs.net.'; + } + else { return ''; } - if (($fsk = @fsockopen('whois.arin.net', 43))) + $ipwhois = ''; + + if (($fsk = @fsockopen($whois_host, 43))) { // CRLF as per RFC3912 fputs($fsk, "$ip\r\n"); @@ -1257,7 +1275,7 @@ function user_ipwhois($ip) $match = array(); - // Test for referrals from ARIN to other whois databases, roll on rwhois + // Test for referrals from $whois_host to other whois databases, roll on rwhois if (preg_match('#ReferralServer: whois://(.+)#im', $ipwhois, $match)) { if (strpos($match[1], ':') !== false) @@ -1285,7 +1303,7 @@ function user_ipwhois($ip) @fclose($fsk); } - // Use the result from ARIN if we don't get any result here + // Use the result from $whois_host if we don't get any result here $ipwhois = (empty($buffer)) ? $ipwhois : $buffer; } diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index 80c3559649..d5551f5114 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -1048,6 +1048,35 @@ function mcp_fork_topic($topic_ids) $total_posts = 0; $new_topic_id_list = array(); + if ($topic_data['enable_indexing']) + { + // Select the search method and do some additional checks to ensure it can actually be utilised + $search_type = basename($config['search_type']); + + if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) + { + trigger_error('NO_SUCH_SEARCH_MODULE'); + } + + if (!class_exists($search_type)) + { + include("{$phpbb_root_path}includes/search/$search_type.$phpEx"); + } + + $error = false; + $search = new $search_type($error); + $search_mode = 'post'; + + if ($error) + { + trigger_error($error); + } + } + else + { + $search_type = false; + } + foreach ($topic_data as $topic_id => $topic_row) { $sql_ary = array( @@ -1158,6 +1187,12 @@ function mcp_fork_topic($topic_ids) // Copy whether the topic is dotted markread('post', $to_forum_id, $new_topic_id, 0, $row['poster_id']); + if ($search_type) + { + $search->index($search_mode, $sql_ary['post_id'], $sql_ary['post_text'], $sql_ary['post_subject'], $sql_ary['poster_id'], ($topic_row['topic_type'] == POST_GLOBAL) ? 0 : $to_forum_id); + $search_mode = 'reply'; // After one we index replies + } + // Copy Attachments if ($row['post_attachment']) { diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php index 1fbedbac4f..7098b4bbce 100644 --- a/phpBB/includes/mcp/mcp_post.php +++ b/phpBB/includes/mcp/mcp_post.php @@ -176,7 +176,7 @@ function mcp_post_details($id, $mode, $action) } $template->assign_vars(array( - 'U_MCP_ACTION' => "$url&i=main&quickmod=1", // Use this for mode paramaters + 'U_MCP_ACTION' => "$url&i=main&quickmod=1&mode=post_details", // Use this for mode paramaters 'U_POST_ACTION' => "$url&i=$id&mode=post_details", // Use this for action parameters 'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&p=$post_id&f={$post_info['forum_id']}"), diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index e157053e61..79023cc7bc 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -1831,7 +1831,7 @@ class user extends session // Is load exceeded? if ($config['limit_load'] && $this->load !== false) { - if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN')) + if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN') && !defined('IN_ADMIN')) { // Set board disabled to true to let the admins/mods get the proper notification $config['board_disable'] = '1'; diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 363a4803b6..4fd25b7d1c 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -141,10 +141,7 @@ class ucp_profile $server_url = generate_board_url(); - $user_actkey = gen_rand_string(10); - $key_len = 54 - (strlen($server_url)); - $key_len = ($key_len > 6) ? $key_len : 6; - $user_actkey = substr($user_actkey, 0, $key_len); + $user_actkey = gen_rand_string(mt_rand(6, 10)); $messenger = new messenger(false); diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 9656a4a3af..7fd99da55a 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -286,11 +286,7 @@ class ucp_register $config['require_activation'] == USER_ACTIVATION_SELF || $config['require_activation'] == USER_ACTIVATION_ADMIN) && $config['email_enable']) { - $user_actkey = gen_rand_string(10); - $key_len = 54 - (strlen($server_url)); - $key_len = ($key_len < 6) ? 6 : $key_len; - $user_actkey = substr($user_actkey, 0, $key_len); - + $user_actkey = gen_rand_string(mt_rand(6, 10)); $user_type = USER_INACTIVE; $user_inactive_reason = INACTIVE_REGISTER; $user_inactive_time = time(); diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index f9b792de20..cb89ad99be 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -79,10 +79,10 @@ class ucp_remind // Make password at least 8 characters long, make it longer if admin wants to. // gen_rand_string() however has a limit of 12 or 13. - $user_password = gen_rand_string(max(8, rand((int) $config['min_pass_chars'], (int) $config['max_pass_chars']))); + $user_password = gen_rand_string_friendly(max(8, mt_rand((int) $config['min_pass_chars'], (int) $config['max_pass_chars']))); // For the activation key a random length between 6 and 10 will do. - $user_actkey = gen_rand_string(rand(6, 10)); + $user_actkey = gen_rand_string(mt_rand(6, 10)); $sql = 'UPDATE ' . USERS_TABLE . " SET user_newpasswd = '" . $db->sql_escape(phpbb_hash($user_password)) . "', user_actkey = '" . $db->sql_escape($user_actkey) . "' |