phpBB

Code Changes

File: includes/session.php

  Unmodified   Added   Modified   Removed
Line 83Line 83
		$query_string = trim(implode('&', $use_args));

// basenamed page name (for example: index.php)

		$query_string = trim(implode('&', $use_args));

// basenamed page name (for example: index.php)

		$page_name = basename($script_name);

		$page_name = (substr($script_name, -1, 1) == '/') ? '' : basename($script_name);

		$page_name = urlencode(htmlspecialchars($page_name));

// current directory within the phpBB root (for example: adm)

		$page_name = urlencode(htmlspecialchars($page_name));

// current directory within the phpBB root (for example: adm)

Line 120Line 120

$script_path .= (substr($script_path, -1, 1) == '/') ? '' : '/';
$root_script_path .= (substr($root_script_path, -1, 1) == '/') ? '' : '/';


$script_path .= (substr($script_path, -1, 1) == '/') ? '' : '/';
$root_script_path .= (substr($root_script_path, -1, 1) == '/') ? '' : '/';

 

$forum_id = (isset($_REQUEST['f']) && $_REQUEST['f'] > 0 && $_REQUEST['f'] < 16777215) ? (int) $_REQUEST['f'] : 0;


$page_array += array(
'page_name' => $page_name,


$page_array += array(
'page_name' => $page_name,

Line 130Line 132
			'root_script_path'	=> str_replace(' ', '%20', htmlspecialchars($root_script_path)),

'page' => $page,

			'root_script_path'	=> str_replace(' ', '%20', htmlspecialchars($root_script_path)),

'page' => $page,

			'forum'				=> (isset($_REQUEST['f']) && $_REQUEST['f'] > 0) ? (int) $_REQUEST['f'] : 0,

			'forum'				=> $forum_id,

		);

return $page_array;

		);

return $page_array;

Line 213Line 215
		$this->update_session_page	= $update_session_page;
$this->browser = (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : '';
$this->referer = (!empty($_SERVER['HTTP_REFERER'])) ? htmlspecialchars((string) $_SERVER['HTTP_REFERER']) : '';

		$this->update_session_page	= $update_session_page;
$this->browser = (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : '';
$this->referer = (!empty($_SERVER['HTTP_REFERER'])) ? htmlspecialchars((string) $_SERVER['HTTP_REFERER']) : '';

		$this->forwarded_for		= (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? (string) $_SERVER['HTTP_X_FORWARDED_FOR'] : '';

		$this->forwarded_for		= (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? htmlspecialchars((string) $_SERVER['HTTP_X_FORWARDED_FOR']) : '';


$this->host = $this->extract_current_hostname();
$this->page = $this->extract_current_page($phpbb_root_path);


$this->host = $this->extract_current_hostname();
$this->page = $this->extract_current_page($phpbb_root_path);

Line 221Line 223
		// if the forwarded for header shall be checked we have to validate its contents
if ($config['forwarded_for_check'])
{

		// if the forwarded for header shall be checked we have to validate its contents
if ($config['forwarded_for_check'])
{

			$this->forwarded_for = preg_replace('#, +#', ', ', $this->forwarded_for);

			$this->forwarded_for = preg_replace('# {2,}#', ' ', str_replace(',', ' ', $this->forwarded_for));


// split the list of IPs


// split the list of IPs

			$ips = explode(', ', $this->forwarded_for);

			$ips = explode(' ', $this->forwarded_for);

			foreach ($ips as $ip)
{
// check IPv4 first, the IPv6 is hopefully only going to be used very seldomly

			foreach ($ips as $ip)
{
// check IPv4 first, the IPv6 is hopefully only going to be used very seldomly

Line 267Line 269

// Why no forwarded_for et al? Well, too easily spoofed. With the results of my recent requests
// it's pretty clear that in the majority of cases you'll at least be left with a proxy/cache ip.


// Why no forwarded_for et al? Well, too easily spoofed. With the results of my recent requests
// it's pretty clear that in the majority of cases you'll at least be left with a proxy/cache ip.

		$this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';






































		$this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? (string) $_SERVER['REMOTE_ADDR'] : '';
$this->ip = preg_replace('# {2,}#', ' ', str_replace(',', ' ', $this->ip));

// split the list of IPs
$ips = explode(' ', trim($this->ip));

// Default IP if REMOTE_ADDR is invalid
$this->ip = '127.0.0.1';

foreach ($ips as $ip)
{
if (preg_match(get_preg_expression('ipv4'), $ip))
{
$this->ip = $ip;
}
else if (preg_match(get_preg_expression('ipv6'), $ip))
{
// Quick check for IPv4-mapped address in IPv6
if (stripos($ip, '::ffff:') === 0)
{
$ipv4 = substr($ip, 7);

if (preg_match(get_preg_expression('ipv4'), $ipv4))
{
$ip = $ipv4;
}
}

$this->ip = $ip;
}
else
{
// We want to use the last valid address in the chain
// Leave foreach loop when address is invalid
break;
}
}


		$this->load = false;

// Load limit check (if applicable)

		$this->load = false;

// Load limit check (if applicable)

Line 285Line 324
			}
}


			}
}


		// Is session_id is set or session_id is set and matches the url param if required
if (!empty($this->session_id) && (!defined('NEED_SID') || (isset($_GET['sid']) && $this->session_id === $_GET['sid'])))








		// if no session id is set, redirect to index.php
if (defined('NEED_SID') && (!isset($_GET['sid']) || $this->session_id !== $_GET['sid']))
{
send_status_line(401, 'Unauthorized');
redirect(append_sid("{$phpbb_root_path}index.$phpEx"));
}

// if session id is set
if (!empty($this->session_id))

		{
$sql = 'SELECT u.*, s.*
FROM ' . SESSIONS_TABLE . ' s, ' . USERS_TABLE . " u

		{
$sql = 'SELECT u.*, s.*
FROM ' . SESSIONS_TABLE . ' s, ' . USERS_TABLE . " u

Line 395Line 441
								$sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE session_id = '" . $db->sql_escape($this->session_id) . "'";
$db->sql_query($sql);

								$sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE session_id = '" . $db->sql_escape($this->session_id) . "'";
$db->sql_query($sql);

 
							}

if ($this->data['user_id'] != ANONYMOUS && !empty($config['new_member_post_limit']) && $this->data['user_new'] && $config['new_member_post_limit'] <= $this->data['user_posts'])
{
$this->leave_newly_registered();

							}
}


							}
}


Line 480Line 531

foreach (explode(',', $row['bot_ip']) as $bot_ip)
{


foreach (explode(',', $row['bot_ip']) as $bot_ip)
{

 
					$bot_ip = trim($bot_ip);

if (!$bot_ip)
{
continue;
}


					if (strpos($this->ip, $bot_ip) === 0)
{
$bot = (int) $row['user_id'];

					if (strpos($this->ip, $bot_ip) === 0)
{
$bot = (int) $row['user_id'];

Line 500Line 558
		$method = 'autologin_' . $method;
if (function_exists($method))
{

		$method = 'autologin_' . $method;
if (function_exists($method))
{

			$this->data = $method();






			$user_data = $method();

if ($user_id === false || (isset($user_data['user_id']) && $user_id == $user_data['user_id']))
{
$this->data = $user_data;
}


if (sizeof($this->data))
{


if (sizeof($this->data))
{

Line 520Line 583
					AND k.user_id = u.user_id
AND k.key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'";
$result = $db->sql_query($sql);

					AND k.user_id = u.user_id
AND k.key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'";
$result = $db->sql_query($sql);

			$this->data = $db->sql_fetchrow($result);
$db->sql_freeresult($result);




			$user_data = $db->sql_fetchrow($result);

if ($user_id === false || (isset($user_data['user_id']) && $user_id == $user_data['user_id']))
{
$this->data = $user_data;

			$bot = false;
}

			$bot = false;
}

		else if ($user_id !== false && !sizeof($this->data))






$db->sql_freeresult($result);
}

if ($user_id !== false && !sizeof($this->data))

		{
$this->cookie_data['k'] = '';
$this->cookie_data['u'] = $user_id;

		{
$this->cookie_data['k'] = '';
$this->cookie_data['u'] = $user_id;

Line 537Line 607
			$this->data = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$bot = false;

			$this->data = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$bot = false;

 
		}

// Bot user, if they have a SID in the Request URI we need to get rid of it
// otherwise they'll index this page with the SID, duplicate content oh my!
if ($bot && isset($_GET['sid']))
{
send_status_line(301, 'Moved Permanently');
redirect(build_url(array('sid')));

		}

// If no data was returned one or more of the following occurred:

		}

// If no data was returned one or more of the following occurred:

Line 594Line 672
			}
else
{

			}
else
{

				$ips = explode(', ', $this->forwarded_for);

				$ips = explode(' ', $this->forwarded_for);

				$ips[] = $this->ip;
$this->check_ban($this->data['user_id'], $ips);
}

				$ips[] = $this->ip;
$this->check_ban($this->data['user_id'], $ips);
}

Line 709Line 787

if ((int) $row['sessions'] > (int) $config['active_sessions'])
{


if ((int) $row['sessions'] > (int) $config['active_sessions'])
{

					header('HTTP/1.1 503 Service Unavailable');

					send_status_line(503, 'Service Unavailable');

					trigger_error('BOARD_UNAVAILABLE');
}
}

					trigger_error('BOARD_UNAVAILABLE');
}
}

Line 718Line 796
		// Since we re-create the session id here, the inserted row must be unique. Therefore, we display potential errors.
// Commented out because it will not allow forums to update correctly
// $db->sql_return_on_error(false);

		// Since we re-create the session id here, the inserted row must be unique. Therefore, we display potential errors.
// Commented out because it will not allow forums to update correctly
// $db->sql_return_on_error(false);

 

// Something quite important: session_page always holds the *last* page visited, except for the *first* visit.
// We are not able to simply have an empty session_page btw, therefore we need to tell phpBB how to detect this special case.
// If the session id is empty, we have a completely new one and will set an "identifier" here. This identifier is able to be checked later.
if (empty($this->data['session_id']))
{
// This is a temporary variable, only set for the very first visit
$this->data['session_created'] = true;
}


$this->session_id = $this->data['session_id'] = md5(unique_id());



$this->session_id = $this->data['session_id'] = md5(unique_id());


Line 875Line 962
	*/
function session_gc()
{

	*/
function session_gc()
{

		global $db, $config;

		global $db, $config, $phpbb_root_path, $phpEx;


$batch_size = 10;



$batch_size = 10;


Line 932Line 1019
				$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
WHERE last_login < ' . (time() - (86400 * (int) $config['max_autologin_time']));
$db->sql_query($sql);

				$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
WHERE last_login < ' . (time() - (86400 * (int) $config['max_autologin_time']));
$db->sql_query($sql);

			}
$this->confirm_gc();
}

return;

 
	}


	}


	function confirm_gc($type = 0)


			// only called from CRON; should be a safe workaround until the infrastructure gets going
if (!class_exists('phpbb_captcha_factory'))

	{

	{

		global $db, $config;

$sql = 'SELECT DISTINCT c.session_id
FROM ' . CONFIRM_TABLE . ' c
LEFT JOIN ' . SESSIONS_TABLE . ' s ON (c.session_id = s.session_id)
WHERE s.session_id IS NULL' .
((empty($type)) ? '' : ' AND c.confirm_type = ' . (int) $type);
$result = $db->sql_query($sql);

if ($row = $db->sql_fetchrow($result))
{
$sql_in = array();
do
{
$sql_in[] = (string) $row['session_id'];

				include($phpbb_root_path . "includes/captcha/captcha_factory." . $phpEx);















			}

			}

			while ($row = $db->sql_fetchrow($result));

			phpbb_captcha_factory::garbage_collect($config['captcha_plugin']);





			if (sizeof($sql_in))
{
$sql = 'DELETE FROM ' . CONFIRM_TABLE . '
WHERE ' . $db->sql_in_set('session_id', $sql_in);

			$sql = 'DELETE FROM ' . LOGIN_ATTEMPT_TABLE . '
WHERE attempt_time < ' . (time() - (int) $config['ip_login_limit_time']);



				$db->sql_query($sql);
}

				$db->sql_query($sql);
}

 

return;

		}

		}

		$db->sql_freeresult($result);
}


 

/**
* Sets a cookie


/**
* Sets a cookie

Line 985Line 1051

$name_data = rawurlencode($config['cookie_name'] . '_' . $name) . '=' . rawurlencode($cookiedata);
$expire = gmdate('D, d-M-Y H:i:s \\G\\M\\T', $cookietime);


$name_data = rawurlencode($config['cookie_name'] . '_' . $name) . '=' . rawurlencode($cookiedata);
$expire = gmdate('D, d-M-Y H:i:s \\G\\M\\T', $cookietime);

		$domain = (!$config['cookie_domain'] || $config['cookie_domain'] == 'localhost' || $config['cookie_domain'] == '127.0.0.1') ? '' : '; domain=' . $config['cookie_domain'];

		$domain = (!$config['cookie_domain'] || $config['cookie_domain'] == '127.0.0.1' || strpos($config['cookie_domain'], '.') === false) ? '' : '; domain=' . $config['cookie_domain'];


header('Set-Cookie: ' . $name_data . (($cookietime) ? '; expires=' . $expire : '') . '; path=' . $config['cookie_path'] . $domain . ((!$config['cookie_secure']) ? '' : '; secure') . '; HttpOnly', false);
}


header('Set-Cookie: ' . $name_data . (($cookietime) ? '; expires=' . $expire : '') . '; path=' . $config['cookie_path'] . $domain . ((!$config['cookie_secure']) ? '' : '; secure') . '; HttpOnly', false);
}

Line 1201Line 1267
		if ($ip === false)
{
$ip = $this->ip;

		if ($ip === false)
{
$ip = $this->ip;

 
		}

// Neither Spamhaus nor Spamcop supports IPv6 addresses.
if (strpos($ip, ':') !== false)
{
return false;

		}

$dnsbl_check = array(

		}

$dnsbl_check = array(

			'sbl-xbl.spamhaus.org'	=> 'http://www.spamhaus.org/query/bl?ip=',

			'sbl.spamhaus.org'	=> 'http://www.spamhaus.org/query/bl?ip=',

		);

if ($mode == 'register')

		);

if ($mode == 'register')

Line 1338Line 1410
	{
global $config, $db;


	{
global $config, $db;


		$user_id = ($user_id === false) ? $this->data['user_id'] : $user_id;

		$user_id = ($user_id === false) ? (int) $this->data['user_id'] : (int) $user_id;


$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
WHERE user_id = ' . (int) $user_id;
$db->sql_query($sql);


$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
WHERE user_id = ' . (int) $user_id;
$db->sql_query($sql);

 

// If the user is logged in, update last visit info first before deleting sessions
$sql = 'SELECT session_time, session_page
FROM ' . SESSIONS_TABLE . '
WHERE session_user_id = ' . (int) $user_id . '
ORDER BY session_time DESC';
$result = $db->sql_query_limit($sql, 1);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);

if ($row)
{
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_lastvisit = ' . (int) $row['session_time'] . ", user_lastpage = '" . $db->sql_escape($row['session_page']) . "'
WHERE user_id = " . (int) $user_id;
$db->sql_query($sql);
}


// Let's also clear any current sessions for the specified user_id
// If it's the current user then we'll leave this session intact
$sql_where = 'session_user_id = ' . (int) $user_id;


// Let's also clear any current sessions for the specified user_id
// If it's the current user then we'll leave this session intact
$sql_where = 'session_user_id = ' . (int) $user_id;

		$sql_where .= ($user_id === $this->data['user_id']) ? " AND session_id <> '" . $db->sql_escape($this->session_id) . "'" : '';

		$sql_where .= ($user_id === (int) $this->data['user_id']) ? " AND session_id <> '" . $db->sql_escape($this->session_id) . "'" : '';


$sql = 'DELETE FROM ' . SESSIONS_TABLE . "
WHERE $sql_where";


$sql = 'DELETE FROM ' . SESSIONS_TABLE . "
WHERE $sql_where";

Line 1355Line 1444

// We're changing the password of the current user and they have a key
// Lets regenerate it to be safe


// We're changing the password of the current user and they have a key
// Lets regenerate it to be safe

		if ($user_id === $this->data['user_id'] && $this->cookie_data['k'])

		if ($user_id === (int) $this->data['user_id'] && $this->cookie_data['k'])

		{
$this->set_login_key($user_id);
}

		{
$this->set_login_key($user_id);
}

Line 1368Line 1457
	*/
function validate_referer($check_script_path = false)
{

	*/
function validate_referer($check_script_path = false)
{

 
		global $config;


		// no referer - nothing to validate, user's fault for turning it off (we only check on POST; so meta can't be the reason)
if (empty($this->referer) || empty($this->host))
{

		// no referer - nothing to validate, user's fault for turning it off (we only check on POST; so meta can't be the reason)
if (empty($this->referer) || empty($this->host))
{

Line 1377Line 1468
		$host = htmlspecialchars($this->host);
$ref = substr($this->referer, strpos($this->referer, '://') + 3);


		$host = htmlspecialchars($this->host);
$ref = substr($this->referer, strpos($this->referer, '://') + 3);


		if (!(stripos($ref, $host) === 0))

		if (!(stripos($ref, $host) === 0) && (!$config['force_server_vars'] || !(stripos($ref, $config['server_name']) === 0)))

		{
return false;
}

		{
return false;
}

Line 1435Line 1526
	var $img_lang;
var $img_array = array();


	var $img_lang;
var $img_array = array();


	// Able to add new option (id 7)
var $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'popuppm' => 10);
var $keyvalues = array();

	// Able to add new options (up to id 31)
var $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'popuppm' => 10, 'sig_bbcode' => 15, 'sig_smilies' => 16, 'sig_links' => 17);



/**
* Constructor to set the lang path


/**
* Constructor to set the lang path

Line 1527Line 1617
		// We include common language file here to not load it every time a custom language file is included
$lang = &$this->lang;


		// We include common language file here to not load it every time a custom language file is included
$lang = &$this->lang;


		if ((@include $this->lang_path . $this->lang_name . "/common.$phpEx") === false)




		// Do not suppress error if in DEBUG_EXTRA mode
$include_result = (defined('DEBUG_EXTRA')) ? (include $this->lang_path . $this->lang_name . "/common.$phpEx") : (@include $this->lang_path . $this->lang_name . "/common.$phpEx");

if ($include_result === false)

		{
die('Language file ' . $this->lang_path . $this->lang_name . "/common.$phpEx" . " couldn't be opened.");
}

		{
die('Language file ' . $this->lang_path . $this->lang_name . "/common.$phpEx" . " couldn't be opened.");
}

Line 1535Line 1628
		$this->add_lang($lang_set);
unset($lang_set);


		$this->add_lang($lang_set);
unset($lang_set);


		if (!empty($_GET['style']) && $auth->acl_get('a_styles'))

		if (!empty($_GET['style']) && $auth->acl_get('a_styles') && !defined('ADMIN_START'))

		{
global $SID, $_EXTRA_URL;


		{
global $SID, $_EXTRA_URL;


Line 1582Line 1675

if (!$this->theme)
{


if (!$this->theme)
{

			trigger_error('Could not get style data', E_USER_ERROR);

			trigger_error('NO_STYLE_DATA', E_USER_ERROR);

		}

// Now parse the cfg file and cache it

		}

// Now parse the cfg file and cache it

Line 1657Line 1750

$this->img_lang = (file_exists($phpbb_root_path . 'styles/' . $this->theme['imageset_path'] . '/imageset/' . $this->lang_name)) ? $this->lang_name : $config['default_lang'];



$this->img_lang = (file_exists($phpbb_root_path . 'styles/' . $this->theme['imageset_path'] . '/imageset/' . $this->lang_name)) ? $this->lang_name : $config['default_lang'];


		$sql = 'SELECT image_name, image_filename, image_lang, image_height, image_width


		// Same query in style.php
$sql = 'SELECT *

			FROM ' . STYLES_IMAGESET_DATA_TABLE . '
WHERE imageset_id = ' . $this->theme['imageset_id'] . "
AND image_filename <> ''

			FROM ' . STYLES_IMAGESET_DATA_TABLE . '
WHERE imageset_id = ' . $this->theme['imageset_id'] . "
AND image_filename <> ''

Line 1756Line 1850

// Disable board if the install/ directory is still present
// For the brave development army we do not care about this, else we need to comment out this everytime we develop locally


// Disable board if the install/ directory is still present
// For the brave development army we do not care about this, else we need to comment out this everytime we develop locally

		if (!defined('DEBUG_EXTRA') && !defined('ADMIN_START') && !defined('IN_INSTALL') && !defined('IN_LOGIN') && file_exists($phpbb_root_path . 'install'))

		if (!defined('DEBUG_EXTRA') && !defined('ADMIN_START') && !defined('IN_INSTALL') && !defined('IN_LOGIN') && file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install'))

		{
// Adjust the message slightly according to the permissions
if ($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))

		{
// Adjust the message slightly according to the permissions
if ($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))

Line 1773Line 1867
		// Is board disabled and user not an admin or moderator?
if ($config['board_disable'] && !defined('IN_LOGIN') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
{

		// Is board disabled and user not an admin or moderator?
if ($config['board_disable'] && !defined('IN_LOGIN') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
{

			header('HTTP/1.1 503 Service Unavailable');




			if ($this->data['is_bot'])
{
send_status_line(503, 'Service Unavailable');
}


$message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE';
trigger_error($message);


$message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE';
trigger_error($message);

Line 1782Line 1879
		// Is load exceeded?
if ($config['limit_load'] && $this->load !== false)
{

		// 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';

if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
{

			{
// Set board disabled to true to let the admins/mods get the proper notification
$config['board_disable'] = '1';

if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
{

					header('HTTP/1.1 503 Service Unavailable');




					if ($this->data['is_bot'])
{
send_status_line(503, 'Service Unavailable');
}

					trigger_error('BOARD_UNAVAILABLE');
}
}

					trigger_error('BOARD_UNAVAILABLE');
}
}

Line 1827Line 1927

// Does the user need to change their password? If so, redirect to the
// ucp profile reg_details page ... of course do not redirect if we're already in the ucp


// Does the user need to change their password? If so, redirect to the
// ucp profile reg_details page ... of course do not redirect if we're already in the ucp

		if (!defined('IN_ADMIN') && !defined('ADMIN_START') && $config['chg_passforce'] && $this->data['is_registered'] && $auth->acl_get('u_chgpasswd') && $this->data['user_passchg'] < time() - ($config['chg_passforce'] * 86400))

		if (!defined('IN_ADMIN') && !defined('ADMIN_START') && $config['chg_passforce'] && !empty($this->data['is_registered']) && $auth->acl_get('u_chgpasswd') && $this->data['user_passchg'] < time() - ($config['chg_passforce'] * 86400))

		{
if (strpos($this->page['query_string'], 'mode=reg_details') === false && $this->page['page_name'] != "ucp.$phpEx")
{

		{
if (strpos($this->page['query_string'], 'mode=reg_details') === false && $this->page['page_name'] != "ucp.$phpEx")
{

Line 1850Line 1950
	{
$args = func_get_args();
$key = $args[0];

	{
$args = func_get_args();
$key = $args[0];

 

if (is_array($key))
{
$lang = &$this->lang[array_shift($key)];

foreach ($key as $_key)
{
$lang = &$lang[$_key];
}
}
else
{
$lang = &$this->lang[$key];
}


// Return if language string does not exist


// Return if language string does not exist

		if (!isset($this->lang[$key]) || (!is_string($this->lang[$key]) && !is_array($this->lang[$key])))

		if (!isset($lang) || (!is_string($lang) && !is_array($lang)))

		{
return $key;
}

// If the language entry is a string, we simply mimic sprintf() behaviour

		{
return $key;
}

// If the language entry is a string, we simply mimic sprintf() behaviour

		if (is_string($this->lang[$key]))

		if (is_string($lang))

		{
if (sizeof($args) == 1)
{

		{
if (sizeof($args) == 1)
{

				return $this->lang[$key];

				return $lang;

			}

// Replace key with language entry and simply pass along...

			}

// Replace key with language entry and simply pass along...

			$args[0] = $this->lang[$key];

			$args[0] = $lang;

			return call_user_func_array('sprintf', $args);
}


			return call_user_func_array('sprintf', $args);
}


Line 1878Line 1992
		{
if (is_int($args[$i]))
{

		{
if (is_int($args[$i]))
{

				$numbers = array_keys($this->lang[$key]);

				$numbers = array_keys($lang);


foreach ($numbers as $num)
{


foreach ($numbers as $num)
{

Line 1889Line 2003

$key_found = $num;
}


$key_found = $num;
}

 
				break;

			}
}

// Ok, let's check if the key was found, else use the last entry (because it is mostly the plural form)
if ($key_found === false)
{

			}
}

// Ok, let's check if the key was found, else use the last entry (because it is mostly the plural form)
if ($key_found === false)
{

			$numbers = array_keys($this->lang[$key]);

			$numbers = array_keys($lang);

			$key_found = end($numbers);
}

// Use the language string we determined and pass it to sprintf()

			$key_found = end($numbers);
}

// Use the language string we determined and pass it to sprintf()

		$args[0] = $this->lang[$key][$key_found];

		$args[0] = $lang[$key_found];

		return call_user_func_array('sprintf', $args);
}


		return call_user_func_array('sprintf', $args);
}


Line 1986Line 2101
				$language_filename = $this->lang_path . $this->lang_name . '/' . (($use_help) ? 'help_' : '') . $lang_file . '.' . $phpEx;
}


				$language_filename = $this->lang_path . $this->lang_name . '/' . (($use_help) ? 'help_' : '') . $lang_file . '.' . $phpEx;
}


			if ((@include $language_filename) === false)
































			if (!file_exists($language_filename))
{
global $config;

if ($this->lang_name == 'en')
{
// The user's selected language is missing the file, the board default's language is missing the file, and the file doesn't exist in /en.
$language_filename = str_replace($this->lang_path . 'en', $this->lang_path . $this->data['user_lang'], $language_filename);
trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR);
}
else if ($this->lang_name == basename($config['default_lang']))
{
// Fall back to the English Language
$this->lang_name = 'en';
$this->set_lang($lang, $help, $lang_file, $use_db, $use_help);
}
else if ($this->lang_name == $this->data['user_lang'])
{
// Fall back to the board default language
$this->lang_name = basename($config['default_lang']);
$this->set_lang($lang, $help, $lang_file, $use_db, $use_help);
}

// Reset the lang name
$this->lang_name = (file_exists($this->lang_path . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']);
return;
}

// Do not suppress error if in DEBUG_EXTRA mode
$include_result = (defined('DEBUG_EXTRA')) ? (include $language_filename) : (@include $language_filename);

if ($include_result === false)

			{
trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR);
}

			{
trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR);
}

Line 2001Line 2147

/**
* Format user date


/**
* Format user date

 
	*
* @param int $gmepoch unix timestamp
* @param string $format date format in date() notation. | used to indicate relative dates, for example |d m Y|, h:i is translated to Today, h:i.
* @param bool $forcedate force non-relative date format.
*
* @return mixed translated date

	*/
function format_date($gmepoch, $format = false, $forcedate = false)
{
static $midnight;

	*/
function format_date($gmepoch, $format = false, $forcedate = false)
{
static $midnight;

 
		static $date_cache;





		$lang_dates = $this->lang['datetime'];

 
		$format = (!$format) ? $this->date_format : $format;

		$format = (!$format) ? $this->date_format : $format;

 
		$now = time();
$delta = $now - $gmepoch;

if (!isset($date_cache[$format]))
{
// Is the user requesting a friendly date format (i.e. 'Today 12:42')?
$date_cache[$format] = array(
'is_short' => strpos($format, '|'),
'format_short' => substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1),
'format_long' => str_replace('|', '', $format),
// Filter out values that are not strings (e.g. arrays) for strtr().
'lang' => array_filter($this->lang['datetime'], 'is_string'),
);





		// Short representation of month in format

			// Short representation of month in format? Some languages use different terms for the long and short format of May

		if ((strpos($format, '\M') === false && strpos($format, 'M') !== false) || (strpos($format, '\r') === false && strpos($format, 'r') !== false))
{

		if ((strpos($format, '\M') === false && strpos($format, 'M') !== false) || (strpos($format, '\r') === false && strpos($format, 'r') !== false))
{

			$lang_dates['May'] = $lang_dates['May_short'];


				$date_cache[$format]['lang']['May'] = $this->lang['datetime']['May_short'];
}

		}


		}


		unset($lang_dates['May_short']);


		// Zone offset
$zone_offset = $this->timezone + $this->dst;





		if (!$midnight)



		// Show date <= 1 hour ago as 'xx min ago' but not greater than 60 seconds in the future
// A small tolerence is given for times in the future but in the same minute are displayed as '< than a minute ago'
if ($delta <= 3600 && $delta > -60 && ($delta >= -5 || (($now / 60) % 60) == (($gmepoch / 60) % 60)) && $date_cache[$format]['is_short'] !== false && !$forcedate && isset($this->lang['datetime']['AGO']))

		{

		{

			list($d, $m, $y) = explode(' ', gmdate('j n Y', time() + $this->timezone + $this->dst));
$midnight = gmmktime(0, 0, 0, $m, $d, $y) - $this->timezone - $this->dst;

			return $this->lang(array('datetime', 'AGO'), max(0, (int) floor($delta / 60)));


		}


		}


		if (strpos($format, '|') === false || ($gmepoch < $midnight - 86400 && !$forcedate) || ($gmepoch > $midnight + 172800 && !$forcedate))

		if (!$midnight)

		{

		{

			return strtr(@gmdate(str_replace('|', '', $format), $gmepoch + $this->timezone + $this->dst), $lang_dates);


			list($d, $m, $y) = explode(' ', gmdate('j n Y', time() + $zone_offset));
$midnight = gmmktime(0, 0, 0, $m, $d, $y) - $zone_offset;

		}


		}


		if ($gmepoch > $midnight + 86400 && !$forcedate)

		if ($date_cache[$format]['is_short'] !== false && !$forcedate && !($gmepoch < $midnight - 86400 || $gmepoch > $midnight + 172800))

		{

		{

			$format = substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1);
return str_replace('||', $this->lang['datetime']['TOMORROW'], strtr(@gmdate($format, $gmepoch + $this->timezone + $this->dst), $lang_dates));




			$day = false;

if ($gmepoch > $midnight + 86400)
{
$day = 'TOMORROW';

		}

		}

		else if ($gmepoch > $midnight && !$forcedate)

			else if ($gmepoch > $midnight)

		{

		{

			$format = substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1);
return str_replace('||', $this->lang['datetime']['TODAY'], strtr(@gmdate($format, $gmepoch + $this->timezone + $this->dst), $lang_dates));

				$day = 'TODAY';


		}

		}

		else if ($gmepoch > $midnight - 86400 && !$forcedate)

			else if ($gmepoch > $midnight - 86400)

		{

		{

			$format = substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1);
return str_replace('||', $this->lang['datetime']['YESTERDAY'], strtr(@gmdate($format, $gmepoch + $this->timezone + $this->dst), $lang_dates));

				$day = 'YESTERDAY';


		}


		}


		return strtr(@gmdate(str_replace('|', '', $format), $gmepoch + $this->timezone + $this->dst), $lang_dates);







			if ($day !== false)
{
return str_replace('||', $this->lang['datetime'][$day], strtr(@gmdate($date_cache[$format]['format_short'], $gmepoch + $zone_offset), $date_cache[$format]['lang']));
}
}

return strtr(@gmdate($date_cache[$format]['format_long'], $gmepoch + $zone_offset), $date_cache[$format]['lang']);

	}

/**

	}

/**

Line 2114Line 2290
				return $img_data;
}


				return $img_data;
}


			$img_data['src'] = $phpbb_root_path . 'styles/' . $this->theme['imageset_path'] . '/imageset/' . ($this->img_array[$img]['image_lang'] ? $this->img_array[$img]['image_lang'] .'/' : '') . $this->img_array[$img]['image_filename'];






			// Use URL if told so
$root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_root_path;

$path = 'styles/' . rawurlencode($this->theme['imageset_path']) . '/imageset/' . ($this->img_array[$img]['image_lang'] ? $this->img_array[$img]['image_lang'] .'/' : '') . $this->img_array[$img]['image_filename'];

$img_data['src'] = $root_path . $path;

			$img_data['width'] = $this->img_array[$img]['image_width'];
$img_data['height'] = $this->img_array[$img]['image_height'];

			$img_data['width'] = $this->img_array[$img]['image_width'];
$img_data['height'] = $this->img_array[$img]['image_height'];

 

// We overwrite the width and height to the phpbb logo's width
// and height here if the contents of the site_logo file are
// really equal to the phpbb_logo
// This allows us to change the dimensions of the phpbb_logo without
// modifying the imageset.cfg and causing a conflict for everyone
// who modified it for their custom logo on updating
if ($img == 'site_logo' && file_exists($phpbb_root_path . $path))
{
global $cache;

$img_file_hashes = $cache->get('imageset_site_logo_md5');

if ($img_file_hashes === false)
{
$img_file_hashes = array();
}

$key = $this->theme['imageset_path'] . '::' . $this->img_array[$img]['image_lang'];
if (!isset($img_file_hashes[$key]))
{
$img_file_hashes[$key] = md5(file_get_contents($phpbb_root_path . $path));
$cache->put('imageset_site_logo_md5', $img_file_hashes);
}

$phpbb_logo_hash = '0c461a32cd3621643105f0d02a772c10';

if ($phpbb_logo_hash == $img_file_hashes[$key])
{
$img_data['width'] = '149';
$img_data['height'] = '52';
}
}

		}

$alt = (!empty($this->lang[$alt])) ? $this->lang[$alt] : $alt;

		}

$alt = (!empty($this->lang[$alt])) ? $this->lang[$alt] : $alt;

Line 2144Line 2358
	}

/**

	}

/**

	* Get option bit field from user options





	* Get option bit field from user options.
*
* @param int $key option key, as defined in $keyoptions property.
* @param int $data bit field value to use, or false to use $this->data['user_options']
* @return bool true if the option is set in the bit field, false otherwise

	*/
function optionget($key, $data = false)
{

	*/
function optionget($key, $data = false)
{

		if (!isset($this->keyvalues[$key]))
{
$var = ($data) ? $data : $this->data['user_options'];
$this->keyvalues[$key] = ($var & 1 << $this->keyoptions[$key]) ? true : false;
}

return $this->keyvalues[$key];

		$var = ($data !== false) ? $data : $this->data['user_options'];
return phpbb_optionget($this->keyoptions[$key], $var);






	}

/**

	}

/**

	* Set option bit field for user options










	* Set option bit field for user options.
*
* @param int $key Option key, as defined in $keyoptions property.
* @param bool $value True to set the option, false to clear the option.
* @param int $data Current bit field value, or false to use $this->data['user_options']
* @return int|bool If $data is false, the bit field is modified and
* written back to $this->data['user_options'], and
* return value is true if the bit field changed and
* false otherwise. If $data is not false, the new
* bitfield value is returned.

	*/
function optionset($key, $value, $data = false)
{

	*/
function optionset($key, $value, $data = false)
{

		$var = ($data) ? $data : $this->data['user_options'];

		$var = ($data !== false) ? $data : $this->data['user_options'];





		if ($value && !($var & 1 << $this->keyoptions[$key]))



		$new_var = phpbb_optionset($this->keyoptions[$key], $value, $var);

if ($data === false)

		{

		{

			$var += 1 << $this->keyoptions[$key];




			if ($new_var != $var)
{
$this->data['user_options'] = $new_var;
return true;

		}

		}

		else if (!$value && ($var & 1 << $this->keyoptions[$key]))

			else

		{

		{

			$var -= 1 << $this->keyoptions[$key];


				return false;
}

		}
else
{

		}
else
{

			return ($data) ? $var : false;


			return $new_var;
}

		}


		}


		if (!$data)





	/**
* Funtion to make the user leave the NEWLY_REGISTERED system group.
* @access public
*/
function leave_newly_registered()

		{

		{

			$this->data['user_options'] = $var;





















		global $db;

if (empty($this->data['user_new']))
{
return false;
}

if (!function_exists('remove_newly_registered'))
{
global $phpbb_root_path, $phpEx;

include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
}
if ($group = remove_newly_registered($this->data['user_id'], $this->data))
{
$this->data['group_id'] = $group;

}
$this->data['user_permissions'] = '';
$this->data['user_new'] = 0;


			return true;
}

			return true;
}

		else









/**
* Returns all password protected forum ids the user is currently NOT authenticated for.
*
* @return array Array of forum ids
* @access public
*/
function get_passworded_forums()

		{

		{

			return $var;


















		global $db;

$sql = 'SELECT f.forum_id, fa.user_id
FROM ' . FORUMS_TABLE . ' f
LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa
ON (fa.forum_id = f.forum_id
AND fa.session_id = '" . $db->sql_escape($this->session_id) . "')
WHERE f.forum_password <> ''";
$result = $db->sql_query($sql);

$forum_ids = array();
while ($row = $db->sql_fetchrow($result))
{
$forum_id = (int) $row['forum_id'];

if ($row['user_id'] != $this->data['user_id'])
{
$forum_ids[$forum_id] = $forum_id;

		}

		}

 
		}
$db->sql_freeresult($result);

return $forum_ids;

	}
}


	}
}