~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to www/php/phpBB3/includes/session.php

  • Committer: William Grant
  • Date: 2009-02-23 23:47:02 UTC
  • mfrom: (1099.1.211 new-dispatch)
  • Revision ID: grantw@unimelb.edu.au-20090223234702-db4b1llly46ignwo
Merge from lp:~ivle-dev/ivle/new-dispatch.

Pretty much everything changes. Reread the setup docs. Backup your databases.
Every file is now in a different installed location, the configuration system
is rewritten, the dispatch system is rewritten, URLs are different, the
database is different, worksheets and exercises are no longer on the
filesystem, we use a templating engine, jail service protocols are rewritten,
we don't repeat ourselves, we have authorization rewritten, phpBB is gone,
and probably lots of other things that I cannot remember.

This is certainly the biggest commit I have ever made, and hopefully
the largest I ever will.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
/**
3
 
*
4
 
* @package phpBB3
5
 
* @version $Id: session.php,v 1.317 2007/11/04 12:07:46 acydburn Exp $
6
 
* @copyright (c) 2005 phpBB Group
7
 
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
8
 
*
9
 
*/
10
 
 
11
 
/**
12
 
* @ignore
13
 
*/
14
 
if (!defined('IN_PHPBB'))
15
 
{
16
 
        exit;
17
 
}
18
 
 
19
 
/**
20
 
* Session class
21
 
* @package phpBB3
22
 
*/
23
 
class session
24
 
{
25
 
        var $cookie_data = array();
26
 
        var $page = array();
27
 
        var $data = array();
28
 
        var $browser = '';
29
 
        var $forwarded_for = '';
30
 
        var $host = '';
31
 
        var $session_id = '';
32
 
        var $ip = '';
33
 
        var $load = 0;
34
 
        var $time_now = 0;
35
 
        var $update_session_page = true;
36
 
 
37
 
        /**
38
 
        * Extract current session page
39
 
        *
40
 
        * @param string $root_path current root path (phpbb_root_path)
41
 
        */
42
 
        function extract_current_page($root_path)
43
 
        {
44
 
                $page_array = array();
45
 
 
46
 
                // First of all, get the request uri...
47
 
                $script_name = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : getenv('PHP_SELF');
48
 
                $args = (!empty($_SERVER['QUERY_STRING'])) ? explode('&', $_SERVER['QUERY_STRING']) : explode('&', getenv('QUERY_STRING'));
49
 
 
50
 
                // If we are unable to get the script name we use REQUEST_URI as a failover and note it within the page array for easier support...
51
 
                if (!$script_name)
52
 
                {
53
 
                        $script_name = (!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : getenv('REQUEST_URI');
54
 
                        $script_name = (($pos = strpos($script_name, '?')) !== false) ? substr($script_name, 0, $pos) : $script_name;
55
 
                        $page_array['failover'] = 1;
56
 
                }
57
 
 
58
 
                // Replace backslashes and doubled slashes (could happen on some proxy setups)
59
 
                $script_name = str_replace(array('\\', '//'), '/', $script_name);
60
 
 
61
 
                // Now, remove the sid and let us get a clean query string...
62
 
                $use_args = array();
63
 
 
64
 
                // Since some browser do not encode correctly we need to do this with some "special" characters...
65
 
                // " -> %22, ' => %27, < -> %3C, > -> %3E
66
 
                $find = array('"', "'", '<', '>');
67
 
                $replace = array('%22', '%27', '%3C', '%3E');
68
 
 
69
 
                foreach ($args as $key => $argument)
70
 
                {
71
 
                        if (strpos($argument, 'sid=') === 0 || strpos($argument, '_f_=') === 0)
72
 
                        {
73
 
                                continue;
74
 
                        }
75
 
 
76
 
                        $use_args[str_replace($find, $replace, $key)] = str_replace($find, $replace, $argument);
77
 
                }
78
 
                unset($args);
79
 
 
80
 
                // The following examples given are for an request uri of {path to the phpbb directory}/adm/index.php?i=10&b=2
81
 
 
82
 
                // The current query string
83
 
                $query_string = trim(implode('&', $use_args));
84
 
 
85
 
                // basenamed page name (for example: index.php)
86
 
                $page_name = basename($script_name);
87
 
                $page_name = urlencode(htmlspecialchars($page_name));
88
 
 
89
 
                // current directory within the phpBB root (for example: adm)
90
 
                $root_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($root_path)));
91
 
                $page_dirs = explode('/', str_replace('\\', '/', phpbb_realpath('./')));
92
 
                $intersection = array_intersect_assoc($root_dirs, $page_dirs);
93
 
 
94
 
                $root_dirs = array_diff_assoc($root_dirs, $intersection);
95
 
                $page_dirs = array_diff_assoc($page_dirs, $intersection);
96
 
 
97
 
                $page_dir = str_repeat('../', sizeof($root_dirs)) . implode('/', $page_dirs);
98
 
 
99
 
                if ($page_dir && substr($page_dir, -1, 1) == '/')
100
 
                {
101
 
                        $page_dir = substr($page_dir, 0, -1);
102
 
                }
103
 
 
104
 
                // Current page from phpBB root (for example: adm/index.php?i=10&b=2)
105
 
                $page = (($page_dir) ? $page_dir . '/' : '') . $page_name . (($query_string) ? "?$query_string" : '');
106
 
 
107
 
                // The script path from the webroot to the current directory (for example: /phpBB3/adm/) : always prefixed with / and ends in /
108
 
                $script_path = trim(str_replace('\\', '/', dirname($script_name)));
109
 
 
110
 
                // The script path from the webroot to the phpBB root (for example: /phpBB3/)
111
 
                $script_dirs = explode('/', $script_path);
112
 
                array_splice($script_dirs, -sizeof($page_dirs));
113
 
                $root_script_path = implode('/', $script_dirs) . (sizeof($root_dirs) ? '/' . implode('/', $root_dirs) : '');
114
 
 
115
 
                // We are on the base level (phpBB root == webroot), lets adjust the variables a bit...
116
 
                if (!$root_script_path)
117
 
                {
118
 
                        $root_script_path = ($page_dir) ? str_replace($page_dir, '', $script_path) : $script_path;
119
 
                }
120
 
 
121
 
                $script_path .= (substr($script_path, -1, 1) == '/') ? '' : '/';
122
 
                $root_script_path .= (substr($root_script_path, -1, 1) == '/') ? '' : '/';
123
 
 
124
 
                $page_array += array(
125
 
                        'page_name'                     => $page_name,
126
 
                        'page_dir'                      => $page_dir,
127
 
 
128
 
                        'query_string'          => $query_string,
129
 
                        'script_path'           => str_replace(' ', '%20', htmlspecialchars($script_path)),
130
 
                        'root_script_path'      => str_replace(' ', '%20', htmlspecialchars($root_script_path)),
131
 
 
132
 
                        'page'                          => $page
133
 
                );
134
 
 
135
 
                return $page_array;
136
 
        }
137
 
 
138
 
        /**
139
 
        * Start session management
140
 
        *
141
 
        * This is where all session activity begins. We gather various pieces of
142
 
        * information from the client and server. We test to see if a session already
143
 
        * exists. If it does, fine and dandy. If it doesn't we'll go on to create a
144
 
        * new one ... pretty logical heh? We also examine the system load (if we're
145
 
        * running on a system which makes such information readily available) and
146
 
        * halt if it's above an admin definable limit.
147
 
        *
148
 
        * @param bool $update_session_page if true the session page gets updated.
149
 
        *                       This can be set to circumvent certain scripts to update the users last visited page.
150
 
        */
151
 
        function session_begin($update_session_page = true)
152
 
        {
153
 
                global $phpEx, $SID, $_SID, $_EXTRA_URL, $db, $config, $phpbb_root_path;
154
 
 
155
 
                // Give us some basic information
156
 
                $this->time_now                         = time();
157
 
                $this->cookie_data                      = array('u' => 0, 'k' => '');
158
 
                $this->update_session_page      = $update_session_page;
159
 
                $this->browser                          = (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : '';
160
 
                $this->forwarded_for            = (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? (string) $_SERVER['HTTP_X_FORWARDED_FOR'] : '';
161
 
                $this->host                                     = (!empty($_SERVER['HTTP_HOST'])) ? (string) $_SERVER['HTTP_HOST'] : 'localhost';
162
 
                $this->page                                     = $this->extract_current_page($phpbb_root_path);
163
 
 
164
 
                // if the forwarded for header shall be checked we have to validate its contents
165
 
                if ($config['forwarded_for_check'])
166
 
                {
167
 
                        $this->forwarded_for = preg_replace('#, +#', ', ', $this->forwarded_for);
168
 
 
169
 
                        // split the list of IPs
170
 
                        $ips = explode(', ', $this->forwarded_for);
171
 
                        foreach ($ips as $ip)
172
 
                        {
173
 
                                // check IPv4 first, the IPv6 is hopefully only going to be used very seldomly
174
 
                                if (!empty($ip) && !preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip))
175
 
                                {
176
 
                                        // contains invalid data, don't use the forwarded for header
177
 
                                        $this->forwarded_for = '';
178
 
                                        break;
179
 
                                }
180
 
                        }
181
 
                }
182
 
 
183
 
                // Add forum to the page for tracking online users - also adding a "x" to the end to properly identify the number
184
 
                $this->page['page'] .= (isset($_REQUEST['f'])) ? ((strpos($this->page['page'], '?') !== false) ? '&' : '?') . '_f_=' . (int) $_REQUEST['f'] . 'x' : '';
185
 
 
186
 
        
187
 
        if (isset($_COOKIE[$config['cookie_name'] . '_sid']) || 
188
 
        isset($_COOKIE[$config['cookie_name'] . '_u']))
189
 
        {
190
 
          $this->cookie_data['u'] = request_var($config['cookie_name'] . '_u', 0, 
191
 
          false, true);
192
 
          $this->cookie_data['k'] = request_var($config['cookie_name'] . '_k', '', 
193
 
          false, true);
194
 
          $this->session_id             = request_var($config['cookie_name'] . '_sid', '', 
195
 
          false, true);
196
 
 
197
 
          $SID = (defined('NEED_SID')) ? '?sid=' . $this->session_id : '?sid=';
198
 
          $_SID = (defined('NEED_SID')) ? $this->session_id : '';
199
 
 
200
 
          if (empty($this->session_id))
201
 
          {
202
 
                $this->session_id = $_SID = request_var('sid', '');
203
 
                $SID = '?sid=' . $this->session_id;
204
 
                $this->cookie_data = array('u' => 0, 'k' => '');
205
 
          }
206
 
        }
207
 
        else
208
 
        {
209
 
          $this->session_id = $_SID = request_var('sid', '');
210
 
          $SID = '?sid=' . $this->session_id;
211
 
        }
212
 
 
213
 
                $_EXTRA_URL = array();
214
 
 
215
 
                // Why no forwarded_for et al? Well, too easily spoofed. With the results of my recent requests
216
 
                // it's pretty clear that in the majority of cases you'll at least be left with a proxy/cache ip.
217
 
                $this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';
218
 
                $this->load = false;
219
 
 
220
 
                // Load limit check (if applicable)
221
 
                if ($config['limit_load'] || $config['limit_search_load'])
222
 
                {
223
 
                        if ($load = @file_get_contents('/proc/loadavg'))
224
 
                        {
225
 
                                $this->load = array_slice(explode(' ', $load), 0, 1);
226
 
                                $this->load = floatval($this->load[0]);
227
 
                        }
228
 
                        else
229
 
                        {
230
 
                                set_config('limit_load', '0');
231
 
                                set_config('limit_search_load', '0');
232
 
                        }
233
 
                }
234
 
 
235
 
                // Is session_id is set or session_id is set and matches the url param if required
236
 
                if (!empty($this->session_id) && (!defined('NEED_SID') || (isset($_GET['sid']) && $this->session_id === $_GET['sid'])))
237
 
                {
238
 
                        $sql = 'SELECT u.*, s.*
239
 
                                FROM ' . SESSIONS_TABLE . ' s, ' . USERS_TABLE . " u
240
 
                                WHERE s.session_id = '" . $db->sql_escape($this->session_id) . "'
241
 
                                        AND u.user_id = s.session_user_id";
242
 
          $result = $db->sql_query($sql);
243
 
                        $this->data = $db->sql_fetchrow($result);
244
 
                        $db->sql_freeresult($result);
245
 
 
246
 
          // IVLE
247
 
          $ivle_userid = $this->ivle_auth();
248
 
          if ($ivle_userid and $ivle_userid != $this->data['user_id']) {
249
 
                #$this->session_kill();
250
 
                #trigger_error($ivle_userid);
251
 
                return $this->session_create($ivle_userid);
252
 
          }
253
 
 
254
 
                        // Did the session exist in the DB?
255
 
                        if (isset($this->data['user_id']))
256
 
                        {
257
 
                                // Validate IP length according to admin ... enforces an IP
258
 
                                // check on bots if admin requires this
259
 
                                // $quadcheck = ($config['ip_check_bot'] && $this->data['user_type'] & USER_BOT) ? 4 : $config['ip_check'];
260
 
 
261
 
                                if (strpos($this->ip, ':') !== false && strpos($this->data['session_ip'], ':') !== false)
262
 
                                {
263
 
                                        $s_ip = short_ipv6($this->data['session_ip'], $config['ip_check']);
264
 
                                        $u_ip = short_ipv6($this->ip, $config['ip_check']);
265
 
                                }
266
 
                                else
267
 
                                {
268
 
                                        $s_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, $config['ip_check']));
269
 
                                        $u_ip = implode('.', array_slice(explode('.', $this->ip), 0, $config['ip_check']));
270
 
                                }
271
 
 
272
 
                                $s_browser = ($config['browser_check']) ? strtolower(substr($this->data['session_browser'], 0, 149)) : '';
273
 
                                $u_browser = ($config['browser_check']) ? strtolower(substr($this->browser, 0, 149)) : '';
274
 
 
275
 
                                $s_forwarded_for = ($config['forwarded_for_check']) ? substr($this->data['session_forwarded_for'], 0, 254) : '';
276
 
                                $u_forwarded_for = ($config['forwarded_for_check']) ? substr($this->forwarded_for, 0, 254) : '';
277
 
 
278
 
                                if ($u_ip === $s_ip && $s_browser === $u_browser && $s_forwarded_for === $u_forwarded_for)
279
 
                                {
280
 
                                        $session_expired = false;
281
 
 
282
 
                                        // Check whether the session is still valid if we have one
283
 
                                        $method = basename(trim($config['auth_method']));
284
 
                                        include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
285
 
 
286
 
                                        $method = 'validate_session_' . $method;
287
 
                                        if (function_exists($method))
288
 
                                        {
289
 
                                                if (!$method($this->data))
290
 
                                                {
291
 
                                                        $session_expired = true;
292
 
                                                }
293
 
                                        }
294
 
 
295
 
                                        if (!$session_expired)
296
 
                                        {
297
 
                                                // Check the session length timeframe if autologin is not enabled.
298
 
                                                // Else check the autologin length... and also removing those having autologin enabled but no longer allowed board-wide.
299
 
                                                if (!$this->data['session_autologin'])
300
 
                                                {
301
 
                                                        if ($this->data['session_time'] < $this->time_now - ($config['session_length'] + 60))
302
 
                                                        {
303
 
                                                                $session_expired = true;
304
 
                                                        }
305
 
                                                }
306
 
                                                else if (!$config['allow_autologin'] || ($config['max_autologin_time'] && $this->data['session_time'] < $this->time_now - (86400 * (int) $config['max_autologin_time']) + 60))
307
 
                                                {
308
 
                                                        $session_expired = true;
309
 
                                                }
310
 
                                        }
311
 
 
312
 
                                        if (!$session_expired)
313
 
                                        {
314
 
                                                // Only update session DB a minute or so after last update or if page changes
315
 
                                                if ($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page']))
316
 
                                                {
317
 
                                                        $sql_ary = array('session_time' => $this->time_now);
318
 
 
319
 
                                                        if ($this->update_session_page)
320
 
                                                        {
321
 
                                                                $sql_ary['session_page'] = substr($this->page['page'], 0, 199);
322
 
                                                        }
323
 
 
324
 
                                                        $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
325
 
                                                                WHERE session_id = '" . $db->sql_escape($this->session_id) . "'";
326
 
                                                        $db->sql_query($sql);
327
 
                                                }
328
 
 
329
 
                                                $this->data['is_registered'] = ($this->data['user_id'] != ANONYMOUS && ($this->data['user_type'] == USER_NORMAL || $this->data['user_type'] == USER_FOUNDER)) ? true : false;
330
 
                                                $this->data['is_bot'] = (!$this->data['is_registered'] && $this->data['user_id'] != ANONYMOUS) ? true : false;
331
 
                                                $this->data['user_lang'] = basename($this->data['user_lang']);
332
 
 
333
 
                                                return true;
334
 
                                        }
335
 
                                }
336
 
                                else
337
 
                                {
338
 
                                        // Added logging temporarly to help debug bugs...
339
 
                                        if (defined('DEBUG_EXTRA') && $this->data['user_id'] != ANONYMOUS)
340
 
                                        {
341
 
                                                add_log('critical', 'LOG_IP_BROWSER_FORWARDED_CHECK', $u_ip, $s_ip, $u_browser, $s_browser, htmlspecialchars($u_forwarded_for), htmlspecialchars($s_forwarded_for));
342
 
                                        }
343
 
                                }
344
 
                        }
345
 
                }
346
 
 
347
 
                // If we reach here then no (valid) session exists. So we'll create a new one
348
 
                return $this->session_create();
349
 
        }
350
 
 
351
 
        /**
352
 
        * Create a new session
353
 
        *
354
 
        * If upon trying to start a session we discover there is nothing existing we
355
 
        * jump here. Additionally this method is called directly during login to regenerate
356
 
        * the session for the specific user. In this method we carry out a number of tasks;
357
 
        * garbage collection, (search)bot checking, banned user comparison. Basically
358
 
        * though this method will result in a new session for a specific user.
359
 
        */
360
 
        function session_create($user_id = false, $set_admin = false, $persist_login = false, $viewonline = true)
361
 
        {
362
 
                global $SID, $_SID, $db, $config, $cache, $phpbb_root_path, $phpEx;
363
 
 
364
 
                $this->data = array();
365
 
 
366
 
                /* Garbage collection ... remove old sessions updating user information
367
 
                // if necessary. It means (potentially) 11 queries but only infrequently
368
 
                if ($this->time_now > $config['session_last_gc'] + $config['session_gc'])
369
 
                {
370
 
                        $this->session_gc();
371
 
                }*/
372
 
                
373
 
                // Do we allow autologin on this board? No? Then override anything
374
 
                // that may be requested here
375
 
                if (!$config['allow_autologin'])
376
 
                {
377
 
                        $this->cookie_data['k'] = $persist_login = false;
378
 
                }
379
 
 
380
 
                /**
381
 
                * Here we do a bot check, oh er saucy! No, not that kind of bot
382
 
                * check. We loop through the list of bots defined by the admin and
383
 
                * see if we have any useragent and/or IP matches. If we do, this is a
384
 
                * bot, act accordingly
385
 
                */
386
 
                $bot = false;
387
 
                $active_bots = $cache->obtain_bots();
388
 
 
389
 
                foreach ($active_bots as $row)
390
 
                {
391
 
                        if ($row['bot_agent'] && preg_match('#' . str_replace('\*', '.*?', preg_quote($row['bot_agent'], '#')) . '#i', $this->browser))
392
 
                        {
393
 
                                $bot = $row['user_id'];
394
 
                        }
395
 
 
396
 
                        // If ip is supplied, we will make sure the ip is matching too...
397
 
                        if ($row['bot_ip'] && ($bot || !$row['bot_agent']))
398
 
                        {
399
 
                                // Set bot to false, then we only have to set it to true if it is matching
400
 
                                $bot = false;
401
 
 
402
 
                                foreach (explode(',', $row['bot_ip']) as $bot_ip)
403
 
                                {
404
 
                                        if (strpos($this->ip, $bot_ip) === 0)
405
 
                                        {
406
 
                                                $bot = (int) $row['user_id'];
407
 
                                                break;
408
 
                                        }
409
 
                                }
410
 
                        }
411
 
 
412
 
                        if ($bot)
413
 
                        {
414
 
                                break;
415
 
                        }
416
 
                }
417
 
 
418
 
                $method = basename(trim($config['auth_method']));
419
 
                include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
420
 
 
421
 
                $method = 'autologin_' . $method;
422
 
                if (function_exists($method))
423
 
                {
424
 
                        $this->data = $method();
425
 
 
426
 
                        if (sizeof($this->data))
427
 
                        {
428
 
                                $this->cookie_data['k'] = '';
429
 
                                $this->cookie_data['u'] = $this->data['user_id'];
430
 
                        }
431
 
                }
432
 
 
433
 
                // If we're presented with an autologin key we'll join against it.
434
 
                // Else if we've been passed a user_id we'll grab data based on that
435
 
                if (isset($this->cookie_data['k']) && $this->cookie_data['k'] && $this->cookie_data['u'] && !sizeof($this->data))
436
 
                {
437
 
                        $sql = 'SELECT u.*
438
 
                                FROM ' . USERS_TABLE . ' u, ' . SESSIONS_KEYS_TABLE . ' k
439
 
                                WHERE u.user_id = ' . (int) $this->cookie_data['u'] . '
440
 
                                        AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ")
441
 
                                        AND k.user_id = u.user_id
442
 
                                        AND k.key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'";
443
 
                        $result = $db->sql_query($sql);
444
 
                        $this->data = $db->sql_fetchrow($result);
445
 
                        $db->sql_freeresult($result);
446
 
                        $bot = false;
447
 
                }
448
 
                else if ($user_id !== false && !sizeof($this->data))
449
 
                {
450
 
                        $this->cookie_data['k'] = '';
451
 
                        $this->cookie_data['u'] = $user_id;
452
 
 
453
 
                        $sql = 'SELECT *
454
 
                                FROM ' . USERS_TABLE . '
455
 
                                WHERE user_id = ' . (int) $this->cookie_data['u'] . '
456
 
                                        AND user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')';
457
 
                        $result = $db->sql_query($sql);
458
 
                        $this->data = $db->sql_fetchrow($result);
459
 
                        $db->sql_freeresult($result);
460
 
                        $bot = false;
461
 
                }
462
 
 
463
 
                // If no data was returned one or more of the following occurred:
464
 
                // Key didn't match one in the DB
465
 
                // User does not exist
466
 
                // User is inactive
467
 
                // User is bot
468
 
                if (!sizeof($this->data) || !is_array($this->data))
469
 
                {
470
 
                        $this->cookie_data['k'] = '';
471
 
                        $this->cookie_data['u'] = ($bot) ? $bot : ANONYMOUS;
472
 
 
473
 
                        if (!$bot)
474
 
                        {
475
 
                                $sql = 'SELECT *
476
 
                                        FROM ' . USERS_TABLE . '
477
 
                                        WHERE user_id = ' . (int) $this->cookie_data['u'];
478
 
                        }
479
 
                        else
480
 
                        {
481
 
                                // We give bots always the same session if it is not yet expired.
482
 
                                $sql = 'SELECT u.*, s.*
483
 
                                        FROM ' . USERS_TABLE . ' u
484
 
                                        LEFT JOIN ' . SESSIONS_TABLE . ' s ON (s.session_user_id = u.user_id)
485
 
                                        WHERE u.user_id = ' . (int) $bot;
486
 
                        }
487
 
 
488
 
                        $result = $db->sql_query($sql);
489
 
                        $this->data = $db->sql_fetchrow($result);
490
 
                        $db->sql_freeresult($result);
491
 
                }
492
 
 
493
 
                if ($this->data['user_id'] != ANONYMOUS && !$bot)
494
 
                {
495
 
                        $this->data['session_last_visit'] = (isset($this->data['session_time']) && $this->data['session_time']) ? $this->data['session_time'] : (($this->data['user_lastvisit']) ? $this->data['user_lastvisit'] : time());
496
 
                }
497
 
                else
498
 
                {
499
 
                        $this->data['session_last_visit'] = $this->time_now;
500
 
                }
501
 
 
502
 
                // Force user id to be integer...
503
 
                $this->data['user_id'] = (int) $this->data['user_id'];
504
 
 
505
 
                // At this stage we should have a filled data array, defined cookie u and k data.
506
 
                // data array should contain recent session info if we're a real user and a recent
507
 
                // session exists in which case session_id will also be set
508
 
 
509
 
                // Is user banned? Are they excluded? Won't return on ban, exists within method
510
 
                if ($this->data['user_type'] != USER_FOUNDER)
511
 
                {
512
 
                        if (!$config['forwarded_for_check'])
513
 
                        {
514
 
                                $this->check_ban($this->data['user_id'], $this->ip);
515
 
                        }
516
 
                        else
517
 
                        {
518
 
                                $ips = explode(', ', $this->forwarded_for);
519
 
                                $ips[] = $this->ip;
520
 
                                $this->check_ban($this->data['user_id'], $ips);
521
 
                        }
522
 
                }
523
 
 
524
 
                $this->data['is_registered'] = (!$bot && $this->data['user_id'] != ANONYMOUS && ($this->data['user_type'] == USER_NORMAL || $this->data['user_type'] == USER_FOUNDER)) ? true : false;
525
 
                $this->data['is_bot'] = ($bot) ? true : false;
526
 
 
527
 
                // If our friend is a bot, we re-assign a previously assigned session
528
 
                if ($this->data['is_bot'] && $bot == $this->data['user_id'] && $this->data['session_id'])
529
 
                {
530
 
                        // Only assign the current session if the ip, browser and forwarded_for match...
531
 
                        if (strpos($this->ip, ':') !== false && strpos($this->data['session_ip'], ':') !== false)
532
 
                        {
533
 
                                $s_ip = short_ipv6($this->data['session_ip'], $config['ip_check']);
534
 
                                $u_ip = short_ipv6($this->ip, $config['ip_check']);
535
 
                        }
536
 
                        else
537
 
                        {
538
 
                                $s_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, $config['ip_check']));
539
 
                                $u_ip = implode('.', array_slice(explode('.', $this->ip), 0, $config['ip_check']));
540
 
                        }
541
 
 
542
 
                        $s_browser = ($config['browser_check']) ? strtolower(substr($this->data['session_browser'], 0, 149)) : '';
543
 
                        $u_browser = ($config['browser_check']) ? strtolower(substr($this->browser, 0, 149)) : '';
544
 
 
545
 
                        $s_forwarded_for = ($config['forwarded_for_check']) ? substr($this->data['session_forwarded_for'], 0, 254) : '';
546
 
                        $u_forwarded_for = ($config['forwarded_for_check']) ? substr($this->forwarded_for, 0, 254) : '';
547
 
 
548
 
                        if ($u_ip === $s_ip && $s_browser === $u_browser && $s_forwarded_for === $u_forwarded_for)
549
 
                        {
550
 
                                $this->session_id = $this->data['session_id'];
551
 
 
552
 
                                // Only update session DB a minute or so after last update or if page changes
553
 
                                if ($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page']))
554
 
                                {
555
 
                                        $this->data['session_time'] = $this->data['session_last_visit'] = $this->time_now;
556
 
 
557
 
                                        $sql_ary = array('session_time' => $this->time_now, 'session_last_visit' => $this->time_now, 'session_admin' => 0);
558
 
 
559
 
                                        if ($this->update_session_page)
560
 
                                        {
561
 
                                                $sql_ary['session_page'] = substr($this->page['page'], 0, 199);
562
 
                                        }
563
 
 
564
 
                                        $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
565
 
                                                WHERE session_id = '" . $db->sql_escape($this->session_id) . "'";
566
 
                                        $db->sql_query($sql);
567
 
 
568
 
                                        // Update the last visit time
569
 
                                        $sql = 'UPDATE ' . USERS_TABLE . '
570
 
                                                SET user_lastvisit = ' . (int) $this->data['session_time'] . '
571
 
                                                WHERE user_id = ' . (int) $this->data['user_id'];
572
 
                                        $db->sql_query($sql);
573
 
                                }
574
 
 
575
 
                                $SID = '?sid=';
576
 
                                $_SID = '';
577
 
                                return true;
578
 
                        }
579
 
                        else
580
 
                        {
581
 
                                // If the ip and browser does not match make sure we only have one bot assigned to one session
582
 
                                $db->sql_query('DELETE FROM ' . SESSIONS_TABLE . ' WHERE session_user_id = ' . $this->data['user_id']);
583
 
                        }
584
 
                }
585
 
 
586
 
                $session_autologin = (($this->cookie_data['k'] || $persist_login) && $this->data['is_registered']) ? true : false;
587
 
                $set_admin = ($set_admin && $this->data['is_registered']) ? true : false;
588
 
 
589
 
                // Create or update the session
590
 
                $sql_ary = array(
591
 
                        'session_user_id'               => (int) $this->data['user_id'],
592
 
                        'session_start'                 => (int) $this->time_now,
593
 
                        'session_last_visit'    => (int) $this->data['session_last_visit'],
594
 
                        'session_time'                  => (int) $this->time_now,
595
 
                        'session_browser'               => (string) substr($this->browser, 0, 149),
596
 
                        'session_forwarded_for' => (string) $this->forwarded_for,
597
 
                        'session_ip'                    => (string) $this->ip,
598
 
                        'session_autologin'             => ($session_autologin) ? 1 : 0,
599
 
                        'session_admin'                 => ($set_admin) ? 1 : 0,
600
 
                        'session_viewonline'    => ($viewonline) ? 1 : 0,
601
 
                );
602
 
 
603
 
                if ($this->update_session_page)
604
 
                {
605
 
                        $sql_ary['session_page'] = (string) substr($this->page['page'], 0, 199);
606
 
                }
607
 
 
608
 
                $db->sql_return_on_error(true);
609
 
 
610
 
                $sql = 'DELETE
611
 
                        FROM ' . SESSIONS_TABLE . '
612
 
                        WHERE session_id = \'' . $db->sql_escape($this->session_id) . '\'
613
 
                                AND session_user_id = ' . ANONYMOUS;
614
 
 
615
 
                if (!defined('IN_ERROR_HANDLER') && (!$this->session_id || !$db->sql_query($sql) || !$db->sql_affectedrows()))
616
 
                {
617
 
                        // Limit new sessions in 1 minute period (if required)
618
 
                        if (empty($this->data['session_time']) && $config['active_sessions'])
619
 
                        {
620
 
                                $sql = 'SELECT COUNT(session_id) AS sessions
621
 
                                        FROM ' . SESSIONS_TABLE . '
622
 
                                        WHERE session_time >= ' . ($this->time_now - 60);
623
 
                                $result = $db->sql_query($sql);
624
 
                                $row = $db->sql_fetchrow($result);
625
 
                                $db->sql_freeresult($result);
626
 
 
627
 
                                if ((int) $row['sessions'] > (int) $config['active_sessions'])
628
 
                                {
629
 
                                        header('HTTP/1.1 503 Service Unavailable');
630
 
                                        trigger_error('BOARD_UNAVAILABLE');
631
 
                                }
632
 
                        }
633
 
                }
634
 
 
635
 
                $this->session_id = $this->data['session_id'] = md5(unique_id());
636
 
 
637
 
                $sql_ary['session_id'] = (string) $this->session_id;
638
 
                $sql_ary['session_page'] = (string) substr($this->page['page'], 0, 199);
639
 
 
640
 
                $sql = 'INSERT INTO ' . SESSIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
641
 
                $db->sql_query($sql);
642
 
 
643
 
                $db->sql_return_on_error(false);
644
 
 
645
 
                // Regenerate autologin/persistent login key
646
 
                if ($session_autologin)
647
 
                {
648
 
                        $this->set_login_key();
649
 
                }
650
 
 
651
 
                // refresh data
652
 
                $SID = '?sid=' . $this->session_id;
653
 
                $_SID = $this->session_id;
654
 
                $this->data = array_merge($this->data, $sql_ary);
655
 
 
656
 
                if (!$bot)
657
 
                {
658
 
                        $cookie_expire = $this->time_now + (($config['max_autologin_time']) ? 86400 * (int) $config['max_autologin_time'] : 31536000);
659
 
 
660
 
                        $this->set_cookie('u', $this->cookie_data['u'], $cookie_expire);
661
 
                        $this->set_cookie('k', $this->cookie_data['k'], $cookie_expire);
662
 
                        $this->set_cookie('sid', $this->session_id, $cookie_expire);
663
 
 
664
 
                        unset($cookie_expire);
665
 
                        
666
 
                        $sql = 'SELECT COUNT(session_id) AS sessions
667
 
                                        FROM ' . SESSIONS_TABLE . '
668
 
                                        WHERE session_user_id = ' . (int) $this->data['user_id'] . '
669
 
                                        AND session_time >= ' . ($this->time_now - $config['form_token_lifetime']);
670
 
                        $result = $db->sql_query($sql);
671
 
                        $row = $db->sql_fetchrow($result);
672
 
                        $db->sql_freeresult($result);
673
 
 
674
 
                        if ((int) $row['sessions'] <= 1 || empty($this->data['user_form_salt']))
675
 
                        {
676
 
                                $this->data['user_form_salt'] = unique_id();
677
 
                                // Update the form key
678
 
                                $sql = 'UPDATE ' . USERS_TABLE . '
679
 
                                        SET user_form_salt = \'' . $db->sql_escape($this->data['user_form_salt']) . '\'
680
 
                                        WHERE user_id = ' . (int) $this->data['user_id'];
681
 
                                $db->sql_query($sql);
682
 
                        }
683
 
                }
684
 
                else
685
 
                {
686
 
                        $this->data['session_time'] = $this->data['session_last_visit'] = $this->time_now;
687
 
 
688
 
                        // Update the last visit time
689
 
                        $sql = 'UPDATE ' . USERS_TABLE . '
690
 
                                SET user_lastvisit = ' . (int) $this->data['session_time'] . '
691
 
                                WHERE user_id = ' . (int) $this->data['user_id'];
692
 
                        $db->sql_query($sql);
693
 
 
694
 
                        $SID = '?sid=';
695
 
                        $_SID = '';
696
 
                }
697
 
 
698
 
                return true;
699
 
        }
700
 
 
701
 
        /**
702
 
        * Kills a session
703
 
        *
704
 
        * This method does what it says on the tin. It will delete a pre-existing session.
705
 
        * It resets cookie information (destroying any autologin key within that cookie data)
706
 
        * and update the users information from the relevant session data. It will then
707
 
        * grab guest user information.
708
 
        */
709
 
        function session_kill($new_session = true)
710
 
        {
711
 
                global $SID, $_SID, $db, $config, $phpbb_root_path, $phpEx;
712
 
 
713
 
                $sql = 'DELETE FROM ' . SESSIONS_TABLE . "
714
 
                        WHERE session_id = '" . $db->sql_escape($this->session_id) . "'
715
 
                                AND session_user_id = " . (int) $this->data['user_id'];
716
 
                $db->sql_query($sql);
717
 
 
718
 
                // Allow connecting logout with external auth method logout
719
 
                $method = basename(trim($config['auth_method']));
720
 
                include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
721
 
 
722
 
                $method = 'logout_' . $method;
723
 
                if (function_exists($method))
724
 
                {
725
 
                        $method($this->data, $new_session);
726
 
                }
727
 
 
728
 
                if ($this->data['user_id'] != ANONYMOUS)
729
 
                {
730
 
                        // Delete existing session, update last visit info first!
731
 
                        if (!isset($this->data['session_time']))
732
 
                        {
733
 
                                $this->data['session_time'] = time();
734
 
                        }
735
 
 
736
 
                        $sql = 'UPDATE ' . USERS_TABLE . '
737
 
                                SET user_lastvisit = ' . (int) $this->data['session_time'] . '
738
 
                                WHERE user_id = ' . (int) $this->data['user_id'];
739
 
                        $db->sql_query($sql);
740
 
 
741
 
                        if ($this->cookie_data['k'])
742
 
                        {
743
 
                                $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
744
 
                                        WHERE user_id = ' . (int) $this->data['user_id'] . "
745
 
                                                AND key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'";
746
 
                                $db->sql_query($sql);
747
 
                        }
748
 
 
749
 
                        // Reset the data array
750
 
                        $this->data = array();
751
 
 
752
 
                        $sql = 'SELECT *
753
 
                                FROM ' . USERS_TABLE . '
754
 
                                WHERE user_id = ' . ANONYMOUS;
755
 
                        $result = $db->sql_query($sql);
756
 
                        $this->data = $db->sql_fetchrow($result);
757
 
                        $db->sql_freeresult($result);
758
 
                }
759
 
 
760
 
                $cookie_expire = $this->time_now - 31536000;
761
 
                $this->set_cookie('u', '', $cookie_expire);
762
 
                $this->set_cookie('k', '', $cookie_expire);
763
 
                $this->set_cookie('sid', '', $cookie_expire);
764
 
                unset($cookie_expire);
765
 
 
766
 
                $SID = '?sid=';
767
 
                $this->session_id = $_SID = '';
768
 
 
769
 
                // To make sure a valid session is created we create one for the anonymous user
770
 
                if ($new_session)
771
 
                {
772
 
                        $this->session_create(ANONYMOUS);
773
 
                }
774
 
 
775
 
                return true;
776
 
        }
777
 
 
778
 
        /**
779
 
        * Session garbage collection
780
 
        *
781
 
        * This looks a lot more complex than it really is. Effectively we are
782
 
        * deleting any sessions older than an admin definable limit. Due to the
783
 
        * way in which we maintain session data we have to ensure we update user
784
 
        * data before those sessions are destroyed. In addition this method
785
 
        * removes autologin key information that is older than an admin defined
786
 
        * limit.
787
 
        */
788
 
        function session_gc()
789
 
        {
790
 
                global $db, $config;
791
 
 
792
 
                $batch_size = 10;
793
 
                
794
 
                if (!$this->time_now)
795
 
                {
796
 
                        $this->time_now = time();
797
 
                }
798
 
 
799
 
                // Firstly, delete guest sessions
800
 
                $sql = 'DELETE FROM ' . SESSIONS_TABLE . '
801
 
                        WHERE session_user_id = ' . ANONYMOUS . '
802
 
                                AND session_time < ' . (int) ($this->time_now - $config['session_length']);
803
 
                $db->sql_query($sql);
804
 
 
805
 
                // Get expired sessions, only most recent for each user
806
 
                $sql = 'SELECT session_user_id, session_page, MAX(session_time) AS recent_time
807
 
                        FROM ' . SESSIONS_TABLE . '
808
 
                        WHERE session_time < ' . ($this->time_now - $config['session_length']) . '
809
 
                        GROUP BY session_user_id, session_page';
810
 
                $result = $db->sql_query_limit($sql, $batch_size);
811
 
 
812
 
                $del_user_id = array();
813
 
                $del_sessions = 0;
814
 
 
815
 
                while ($row = $db->sql_fetchrow($result))
816
 
                {
817
 
                        $sql = 'UPDATE ' . USERS_TABLE . '
818
 
                                SET user_lastvisit = ' . (int) $row['recent_time'] . ", user_lastpage = '" . $db->sql_escape($row['session_page']) . "'
819
 
                                WHERE user_id = " . (int) $row['session_user_id'];
820
 
                        $db->sql_query($sql);
821
 
 
822
 
                        $del_user_id[] = (int) $row['session_user_id'];
823
 
                        $del_sessions++;
824
 
                }
825
 
                $db->sql_freeresult($result);
826
 
 
827
 
                if (sizeof($del_user_id))
828
 
                {
829
 
                        // Delete expired sessions
830
 
                        $sql = 'DELETE FROM ' . SESSIONS_TABLE . '
831
 
                                WHERE ' . $db->sql_in_set('session_user_id', $del_user_id) . '
832
 
                                        AND session_time < ' . ($this->time_now - $config['session_length']);
833
 
                        $db->sql_query($sql);
834
 
                }
835
 
 
836
 
                if ($del_sessions < $batch_size)
837
 
                {
838
 
                        // Less than 10 users, update gc timer ... else we want gc
839
 
                        // called again to delete other sessions
840
 
                        set_config('session_last_gc', $this->time_now, true);
841
 
                        
842
 
                        if ($config['max_autologin_time'])
843
 
                        {
844
 
                                $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
845
 
                                        WHERE last_login < ' . (time() - (86400 * (int) $config['max_autologin_time']));
846
 
                                $db->sql_query($sql);
847
 
                        }
848
 
                        $this->confirm_gc();
849
 
                }
850
 
                
851
 
                return;
852
 
        }
853
 
        
854
 
        function confirm_gc($type = 0)
855
 
        {
856
 
                global $db, $config;
857
 
                
858
 
                $sql = 'SELECT DISTINCT c.session_id
859
 
                                FROM ' . CONFIRM_TABLE . ' c
860
 
                                LEFT JOIN ' . SESSIONS_TABLE . ' s ON (c.session_id = s.session_id)
861
 
                                WHERE s.session_id IS NULL' .
862
 
                                        ((empty($type)) ? '' : ' AND c.confirm_type = ' . (int) $type);
863
 
                $result = $db->sql_query($sql);
864
 
 
865
 
                if ($row = $db->sql_fetchrow($result))
866
 
                {
867
 
                        $sql_in = array();
868
 
                        do
869
 
                        {
870
 
                                $sql_in[] = (string) $row['session_id'];
871
 
                        }
872
 
                        while ($row = $db->sql_fetchrow($result));
873
 
 
874
 
                        if (sizeof($sql_in))
875
 
                        {
876
 
                                $sql = 'DELETE FROM ' . CONFIRM_TABLE . '
877
 
                                        WHERE ' . $db->sql_in_set('session_id', $sql_in);
878
 
                                $db->sql_query($sql);
879
 
                        }
880
 
                }
881
 
                $db->sql_freeresult($result);
882
 
        }
883
 
        
884
 
        
885
 
        /**
886
 
        * Sets a cookie
887
 
        *
888
 
        * Sets a cookie of the given name with the specified data for the given length of time.
889
 
        */
890
 
        function set_cookie($name, $cookiedata, $cookietime)
891
 
        {
892
 
                global $config;
893
 
 
894
 
                $name_data = rawurlencode($config['cookie_name'] . '_' . $name) . '=' . rawurlencode($cookiedata);
895
 
                $expire = gmdate('D, d-M-Y H:i:s \\G\\M\\T', $cookietime);
896
 
                $domain = (!$config['cookie_domain'] || $config['cookie_domain'] == 'localhost' || $config['cookie_domain'] == '127.0.0.1') ? '' : '; domain=' . $config['cookie_domain'];
897
 
 
898
 
                header('Set-Cookie: ' . $name_data . '; expires=' . $expire . '; path=' . $config['cookie_path'] . $domain . ((!$config['cookie_secure']) ? '' : '; secure') . '; HttpOnly', false);
899
 
        }
900
 
 
901
 
        /**
902
 
        * Check for banned user
903
 
        *
904
 
        * Checks whether the supplied user is banned by id, ip or email. If no parameters
905
 
        * are passed to the method pre-existing session data is used. If $return is false
906
 
        * this routine does not return on finding a banned user, it outputs a relevant
907
 
        * message and stops execution.
908
 
        *
909
 
        * @param string|array   $user_ips       Can contain a string with one IP or an array of multiple IPs
910
 
        */
911
 
        function check_ban($user_id = false, $user_ips = false, $user_email = false, $return = false)
912
 
        {
913
 
                global $config, $db;
914
 
 
915
 
                if (defined('IN_CHECK_BAN'))
916
 
                {
917
 
                        return;
918
 
                }
919
 
 
920
 
                $banned = false;
921
 
                $cache_ttl = 3600;
922
 
                $where_sql = array();
923
 
 
924
 
                $sql = 'SELECT ban_ip, ban_userid, ban_email, ban_exclude, ban_give_reason, ban_end
925
 
                        FROM ' . BANLIST_TABLE . '
926
 
                        WHERE ';
927
 
 
928
 
                // Determine which entries to check, only return those
929
 
                if ($user_email === false)
930
 
                {
931
 
                        $where_sql[] = "ban_email = ''";
932
 
                }
933
 
 
934
 
                if ($user_ips === false)
935
 
                {
936
 
                        $where_sql[] = "(ban_ip = '' OR ban_exclude = 1)";
937
 
                }
938
 
 
939
 
                if ($user_id === false)
940
 
                {
941
 
                        $where_sql[] = '(ban_userid = 0 OR ban_exclude = 1)';
942
 
                }
943
 
                else
944
 
                {
945
 
                        $cache_ttl = ($user_id == ANONYMOUS) ? 3600 : 0;
946
 
                        $_sql = '(ban_userid = ' . $user_id;
947
 
 
948
 
                        if ($user_email !== false)
949
 
                        {
950
 
                                $_sql .= " OR ban_email <> ''";
951
 
                        }
952
 
 
953
 
                        if ($user_ips !== false)
954
 
                        {
955
 
                                $_sql .= " OR ban_ip <> ''";
956
 
                        }
957
 
 
958
 
                        $_sql .= ')';
959
 
 
960
 
                        $where_sql[] = $_sql;
961
 
                }
962
 
 
963
 
                $sql .= (sizeof($where_sql)) ? implode(' AND ', $where_sql) : '';
964
 
                $result = $db->sql_query($sql, $cache_ttl);
965
 
 
966
 
                $ban_triggered_by = 'user';
967
 
                while ($row = $db->sql_fetchrow($result))
968
 
                {
969
 
                        if ($row['ban_end'] && $row['ban_end'] < time())
970
 
                        {
971
 
                                continue;
972
 
                        }
973
 
 
974
 
                        $ip_banned = false;
975
 
                        if (!empty($row['ban_ip']))
976
 
                        {
977
 
                                if (!is_array($user_ips))
978
 
                                {
979
 
                                        $ip_banned = preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_ip'], '#')) . '$#i', $user_ips);
980
 
                                }
981
 
                                else
982
 
                                {
983
 
                                        foreach ($user_ips as $user_ip)
984
 
                                        {
985
 
                                                if (preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_ip'], '#')) . '$#i', $user_ip))
986
 
                                                {
987
 
                                                        $ip_banned = true;
988
 
                                                        break;
989
 
                                                }
990
 
                                        }
991
 
                                }
992
 
                        }
993
 
 
994
 
                        if ((!empty($row['ban_userid']) && intval($row['ban_userid']) == $user_id) ||
995
 
                                $ip_banned ||
996
 
                                (!empty($row['ban_email']) && preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_email'], '#')) . '$#i', $user_email)))
997
 
                        {
998
 
                                if (!empty($row['ban_exclude']))
999
 
                                {
1000
 
                                        $banned = false;
1001
 
                                        break;
1002
 
                                }
1003
 
                                else
1004
 
                                {
1005
 
                                        $banned = true;
1006
 
                                        $ban_row = $row;
1007
 
 
1008
 
                                        if (!empty($row['ban_userid']) && intval($row['ban_userid']) == $user_id)
1009
 
                                        {
1010
 
                                                $ban_triggered_by = 'user';
1011
 
                                        }
1012
 
                                        else if ($ip_banned)
1013
 
                                        {
1014
 
                                                $ban_triggered_by = 'ip';
1015
 
                                        }
1016
 
                                        else
1017
 
                                        {
1018
 
                                                $ban_triggered_by = 'email';
1019
 
                                        }
1020
 
 
1021
 
                                        // Don't break. Check if there is an exclude rule for this user
1022
 
                                }
1023
 
                        }
1024
 
                }
1025
 
                $db->sql_freeresult($result);
1026
 
 
1027
 
                if ($banned && !$return)
1028
 
                {
1029
 
                        global $template;
1030
 
 
1031
 
                        // If the session is empty we need to create a valid one...
1032
 
                        if (empty($this->session_id))
1033
 
                        {
1034
 
                                // This seems to be no longer needed? - #14971
1035
 
                                //$this->session_create(ANONYMOUS);
1036
 
                        }
1037
 
 
1038
 
                        // Initiate environment ... since it won't be set at this stage
1039
 
                        $this->setup();
1040
 
 
1041
 
                        // Logout the user, banned users are unable to use the normal 'logout' link
1042
 
                        if ($this->data['user_id'] != ANONYMOUS)
1043
 
                        {
1044
 
                                $this->session_kill();
1045
 
                        }
1046
 
 
1047
 
                        // We show a login box here to allow founders accessing the board if banned by IP
1048
 
                        if (defined('IN_LOGIN') && $this->data['user_id'] == ANONYMOUS)
1049
 
                        {
1050
 
                                global $phpEx;
1051
 
 
1052
 
                                $this->setup('ucp');
1053
 
                                $this->data['is_registered'] = $this->data['is_bot'] = false;
1054
 
 
1055
 
                                // Set as a precaution to allow login_box() handling this case correctly as well as this function not being executed again.
1056
 
                                define('IN_CHECK_BAN', 1);
1057
 
 
1058
 
                                login_box("index.$phpEx");
1059
 
 
1060
 
                                // The false here is needed, else the user is able to circumvent the ban.
1061
 
                                $this->session_kill(false);
1062
 
                        }
1063
 
 
1064
 
                        // Ok, we catch the case of an empty session id for the anonymous user...
1065
 
                        // This can happen if the user is logging in, banned by username and the login_box() being called "again".
1066
 
                        if (empty($this->session_id) && defined('IN_CHECK_BAN'))
1067
 
                        {
1068
 
                                $this->session_create(ANONYMOUS);
1069
 
                        }
1070
 
 
1071
 
 
1072
 
                        // Determine which message to output
1073
 
                        $till_date = ($ban_row['ban_end']) ? $this->format_date($ban_row['ban_end']) : '';
1074
 
                        $message = ($ban_row['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM';
1075
 
 
1076
 
                        $message = sprintf($this->lang[$message], $till_date, '<a href="mailto:' . $config['board_contact'] . '">', '</a>');
1077
 
                        $message .= ($ban_row['ban_give_reason']) ? '<br /><br />' . sprintf($this->lang['BOARD_BAN_REASON'], $ban_row['ban_give_reason']) : '';
1078
 
                        $message .= '<br /><br /><em>' . $this->lang['BAN_TRIGGERED_BY_' . strtoupper($ban_triggered_by)] . '</em>';
1079
 
 
1080
 
                        // To circumvent session_begin returning a valid value and the check_ban() not called on second page view, we kill the session again
1081
 
                        $this->session_kill(false);
1082
 
 
1083
 
                        trigger_error($message);
1084
 
                }
1085
 
 
1086
 
                return ($banned) ? true : false;
1087
 
        }
1088
 
 
1089
 
        /**
1090
 
        * Check if ip is blacklisted
1091
 
        * This should be called only where absolutly necessary
1092
 
        *
1093
 
        * Only IPv4 (rbldns does not support AAAA records/IPv6 lookups)
1094
 
        *
1095
 
        * @author satmd (from the php manual)
1096
 
        * @param string $mode register/post - spamcop for example is ommitted for posting
1097
 
        * @return false if ip is not blacklisted, else an array([checked server], [lookup])
1098
 
        */
1099
 
        function check_dnsbl($mode, $ip = false)
1100
 
        {
1101
 
                if ($ip === false)
1102
 
                {
1103
 
                        $ip = $this->ip;
1104
 
                }
1105
 
 
1106
 
                $dnsbl_check = array(
1107
 
                        'list.dsbl.org'                 => 'http://dsbl.org/listing?',
1108
 
                        'sbl-xbl.spamhaus.org'  => 'http://www.spamhaus.org/query/bl?ip=',
1109
 
                );
1110
 
 
1111
 
                if ($mode == 'register')
1112
 
                {
1113
 
                        $dnsbl_check['bl.spamcop.net'] = 'http://spamcop.net/bl.shtml?';
1114
 
                }
1115
 
 
1116
 
                if ($ip)
1117
 
                {
1118
 
                        $quads = explode('.', $ip);
1119
 
                        $reverse_ip = $quads[3] . '.' . $quads[2] . '.' . $quads[1] . '.' . $quads[0];
1120
 
 
1121
 
                        // Need to be listed on all servers...
1122
 
                        $listed = true;
1123
 
                        $info = array();
1124
 
 
1125
 
                        foreach ($dnsbl_check as $dnsbl => $lookup)
1126
 
                        {
1127
 
                                if (phpbb_checkdnsrr($reverse_ip . '.' . $dnsbl . '.', 'A') === true)
1128
 
                                {
1129
 
                                        $info = array($dnsbl, $lookup . $ip);
1130
 
                                }
1131
 
                                else
1132
 
                                {
1133
 
                                        $listed = false;
1134
 
                                }
1135
 
                        }
1136
 
 
1137
 
                        if ($listed)
1138
 
                        {
1139
 
                                return $info;
1140
 
                        }
1141
 
                }
1142
 
 
1143
 
                return false;
1144
 
        }
1145
 
 
1146
 
        /**
1147
 
        * Check if URI is blacklisted
1148
 
        * This should be called only where absolutly necessary, for example on the submitted website field
1149
 
        * This function is not in use at the moment and is only included for testing purposes, it may not work at all!
1150
 
        * This means it is untested at the moment and therefore commented out
1151
 
        *
1152
 
        * @param string $uri URI to check
1153
 
        * @return true if uri is on blacklist, else false. Only blacklist is checked (~zero FP), no grey lists
1154
 
        function check_uribl($uri)
1155
 
        {
1156
 
                // Normally parse_url() is not intended to parse uris
1157
 
                // We need to get the top-level domain name anyway... change.
1158
 
                $uri = parse_url($uri);
1159
 
 
1160
 
                if ($uri === false || empty($uri['host']))
1161
 
                {
1162
 
                        return false;
1163
 
                }
1164
 
 
1165
 
                $uri = trim($uri['host']);
1166
 
 
1167
 
                if ($uri)
1168
 
                {
1169
 
                        // One problem here... the return parameter for the "windows" method is different from what
1170
 
                        // we expect... this may render this check useless...
1171
 
                        if (phpbb_checkdnsrr($uri . '.multi.uribl.com.', 'A') === true)
1172
 
                        {
1173
 
                                return true;
1174
 
                        }
1175
 
                }
1176
 
 
1177
 
                return false;
1178
 
        }
1179
 
        */
1180
 
 
1181
 
        /**
1182
 
        * Set/Update a persistent login key
1183
 
        *
1184
 
        * This method creates or updates a persistent session key. When a user makes
1185
 
        * use of persistent (formerly auto-) logins a key is generated and stored in the
1186
 
        * DB. When they revisit with the same key it's automatically updated in both the
1187
 
        * DB and cookie. Multiple keys may exist for each user representing different
1188
 
        * browsers or locations. As with _any_ non-secure-socket no passphrase login this
1189
 
        * remains vulnerable to exploit.
1190
 
        */
1191
 
        function set_login_key($user_id = false, $key = false, $user_ip = false)
1192
 
        {
1193
 
                global $config, $db;
1194
 
 
1195
 
                $user_id = ($user_id === false) ? $this->data['user_id'] : $user_id;
1196
 
                $user_ip = ($user_ip === false) ? $this->ip : $user_ip;
1197
 
                $key = ($key === false) ? (($this->cookie_data['k']) ? $this->cookie_data['k'] : false) : $key;
1198
 
 
1199
 
                $key_id = unique_id(hexdec(substr($this->session_id, 0, 8)));
1200
 
 
1201
 
                $sql_ary = array(
1202
 
                        'key_id'                => (string) md5($key_id),
1203
 
                        'last_ip'               => (string) $this->ip,
1204
 
                        'last_login'    => (int) time()
1205
 
                );
1206
 
 
1207
 
                if (!$key)
1208
 
                {
1209
 
                        $sql_ary += array(
1210
 
                                'user_id'       => (int) $user_id
1211
 
                        );
1212
 
                }
1213
 
 
1214
 
                if ($key)
1215
 
                {
1216
 
                        $sql = 'UPDATE ' . SESSIONS_KEYS_TABLE . '
1217
 
                                SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
1218
 
                                WHERE user_id = ' . (int) $user_id . "
1219
 
                                        AND key_id = '" . $db->sql_escape(md5($key)) . "'";
1220
 
                }
1221
 
                else
1222
 
                {
1223
 
                        $sql = 'INSERT INTO ' . SESSIONS_KEYS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
1224
 
                }
1225
 
                $db->sql_query($sql);
1226
 
 
1227
 
                $this->cookie_data['k'] = $key_id;
1228
 
 
1229
 
                return false;
1230
 
        }
1231
 
 
1232
 
        /**
1233
 
        * Reset all login keys for the specified user
1234
 
        *
1235
 
        * This method removes all current login keys for a specified (or the current)
1236
 
        * user. It will be called on password change to render old keys unusable
1237
 
        */
1238
 
        function reset_login_keys($user_id = false)
1239
 
        {
1240
 
                global $config, $db;
1241
 
 
1242
 
                $user_id = ($user_id === false) ? $this->data['user_id'] : $user_id;
1243
 
 
1244
 
                $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
1245
 
                        WHERE user_id = ' . (int) $user_id;
1246
 
                $db->sql_query($sql);
1247
 
 
1248
 
                // Let's also clear any current sessions for the specified user_id
1249
 
                // If it's the current user then we'll leave this session intact
1250
 
                $sql_where = 'session_user_id = ' . (int) $user_id;
1251
 
                $sql_where .= ($user_id === $this->data['user_id']) ? " AND session_id <> '" . $db->sql_escape($this->session_id) . "'" : '';
1252
 
 
1253
 
                $sql = 'DELETE FROM ' . SESSIONS_TABLE . "
1254
 
                        WHERE $sql_where";
1255
 
                $db->sql_query($sql);
1256
 
 
1257
 
                // We're changing the password of the current user and they have a key
1258
 
                // Lets regenerate it to be safe
1259
 
                if ($user_id === $this->data['user_id'] && $this->cookie_data['k'])
1260
 
                {
1261
 
                        $this->set_login_key($user_id);
1262
 
                }
1263
 
        }
1264
 
}
1265
 
 
1266
 
 
1267
 
/**
1268
 
* Base user class
1269
 
*
1270
 
* This is the overarching class which contains (through session extend)
1271
 
* all methods utilised for user functionality during a session.
1272
 
*
1273
 
* @package phpBB3
1274
 
*/
1275
 
class user extends session
1276
 
{
1277
 
        var $lang = array();
1278
 
        var $help = array();
1279
 
        var $theme = array();
1280
 
        var $date_format;
1281
 
        var $timezone;
1282
 
        var $dst;
1283
 
 
1284
 
        var $lang_name;
1285
 
        var $lang_id = false;
1286
 
        var $lang_path;
1287
 
        var $img_lang;
1288
 
        var $img_array = array();
1289
 
 
1290
 
        // Able to add new option (id 7)
1291
 
        var $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'popuppm' => 10);
1292
 
        var $keyvalues = array();
1293
 
 
1294
 
        /**
1295
 
        * Setup basic user-specific items (style, language, ...)
1296
 
        */
1297
 
        function setup($lang_set = false, $style = false)
1298
 
        {
1299
 
                global $db, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache;
1300
 
 
1301
 
                if ($this->data['user_id'] != ANONYMOUS)
1302
 
                {
1303
 
                        $this->lang_name = (file_exists($phpbb_root_path . 'language/' . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']);
1304
 
                        $this->lang_path = $phpbb_root_path . 'language/' . $this->lang_name . '/';
1305
 
 
1306
 
                        $this->date_format = $this->data['user_dateformat'];
1307
 
                        $this->timezone = $this->data['user_timezone'] * 3600;
1308
 
                        $this->dst = $this->data['user_dst'] * 3600;
1309
 
                }
1310
 
                else
1311
 
                {
1312
 
                        $this->lang_name = basename($config['default_lang']);
1313
 
                        $this->lang_path = $phpbb_root_path . 'language/' . $this->lang_name . '/';
1314
 
                        $this->date_format = $config['default_dateformat'];
1315
 
                        $this->timezone = $config['board_timezone'] * 3600;
1316
 
                        $this->dst = $config['board_dst'] * 3600;
1317
 
 
1318
 
                        /**
1319
 
                        * If a guest user is surfing, we try to guess his/her language first by obtaining the browser language
1320
 
                        * If re-enabled we need to make sure only those languages installed are checked
1321
 
                        * Commented out so we do not loose the code.
1322
 
 
1323
 
                        if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
1324
 
                        {
1325
 
                                $accept_lang_ary = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
1326
 
 
1327
 
                                foreach ($accept_lang_ary as $accept_lang)
1328
 
                                {
1329
 
                                        // Set correct format ... guess full xx_YY form
1330
 
                                        $accept_lang = substr($accept_lang, 0, 2) . '_' . strtoupper(substr($accept_lang, 3, 2));
1331
 
                                        $accept_lang = basename($accept_lang);
1332
 
 
1333
 
                                        if (file_exists($phpbb_root_path . 'language/' . $accept_lang . "/common.$phpEx"))
1334
 
                                        {
1335
 
                                                $this->lang_name = $config['default_lang'] = $accept_lang;
1336
 
                                                $this->lang_path = $phpbb_root_path . 'language/' . $accept_lang . '/';
1337
 
                                                break;
1338
 
                                        }
1339
 
                                        else
1340
 
                                        {
1341
 
                                                // No match on xx_YY so try xx
1342
 
                                                $accept_lang = substr($accept_lang, 0, 2);
1343
 
                                                $accept_lang = basename($accept_lang);
1344
 
 
1345
 
                                                if (file_exists($phpbb_root_path . 'language/' . $accept_lang . "/common.$phpEx"))
1346
 
                                                {
1347
 
                                                        $this->lang_name = $config['default_lang'] = $accept_lang;
1348
 
                                                        $this->lang_path = $phpbb_root_path . 'language/' . $accept_lang . '/';
1349
 
                                                        break;
1350
 
                                                }
1351
 
                                        }
1352
 
                                }
1353
 
                        }
1354
 
                        */
1355
 
                }
1356
 
 
1357
 
                // We include common language file here to not load it every time a custom language file is included
1358
 
                $lang = &$this->lang;
1359
 
 
1360
 
                if ((@include $this->lang_path . "common.$phpEx") === false)
1361
 
                {
1362
 
                        die('Language file ' . $this->lang_name . "/common.$phpEx" . " couldn't be opened.");
1363
 
                }
1364
 
 
1365
 
                $this->add_lang($lang_set);
1366
 
                unset($lang_set);
1367
 
 
1368
 
                if (!empty($_GET['style']) && $auth->acl_get('a_styles'))
1369
 
                {
1370
 
                        global $SID, $_EXTRA_URL;
1371
 
 
1372
 
                        $style = request_var('style', 0);
1373
 
                        $SID .= '&amp;style=' . $style;
1374
 
                        $_EXTRA_URL = array('style=' . $style);
1375
 
                }
1376
 
                else
1377
 
                {
1378
 
                        // Set up style
1379
 
                        $style = ($style) ? $style : ((!$config['override_user_style']) ? $this->data['user_style'] : $config['default_style']);
1380
 
                }
1381
 
 
1382
 
                $sql = 'SELECT s.style_id, t.template_storedb, t.template_path, t.template_id, t.bbcode_bitfield, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name
1383
 
                        FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i
1384
 
                        WHERE s.style_id = $style
1385
 
                                AND t.template_id = s.template_id
1386
 
                                AND c.theme_id = s.theme_id
1387
 
                                AND i.imageset_id = s.imageset_id";
1388
 
                $result = $db->sql_query($sql, 3600);
1389
 
                $this->theme = $db->sql_fetchrow($result);
1390
 
                $db->sql_freeresult($result);
1391
 
 
1392
 
                // User has wrong style
1393
 
                if (!$this->theme && $style == $this->data['user_style'])
1394
 
                {
1395
 
                        $style = $this->data['user_style'] = $config['default_style'];
1396
 
 
1397
 
                        $sql = 'UPDATE ' . USERS_TABLE . "
1398
 
                                SET user_style = $style
1399
 
                                WHERE user_id = {$this->data['user_id']}";
1400
 
                        $db->sql_query($sql);
1401
 
 
1402
 
                        $sql = 'SELECT s.style_id, t.template_storedb, t.template_path, t.template_id, t.bbcode_bitfield, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name
1403
 
                                FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i
1404
 
                                WHERE s.style_id = $style
1405
 
                                        AND t.template_id = s.template_id
1406
 
                                        AND c.theme_id = s.theme_id
1407
 
                                        AND i.imageset_id = s.imageset_id";
1408
 
                        $result = $db->sql_query($sql, 3600);
1409
 
                        $this->theme = $db->sql_fetchrow($result);
1410
 
                        $db->sql_freeresult($result);
1411
 
                }
1412
 
 
1413
 
                if (!$this->theme)
1414
 
                {
1415
 
                        trigger_error('Could not get style data', E_USER_ERROR);
1416
 
                }
1417
 
 
1418
 
                // Now parse the cfg file and cache it
1419
 
                $parsed_items = $cache->obtain_cfg_items($this->theme);
1420
 
 
1421
 
                // We are only interested in the theme configuration for now
1422
 
                $parsed_items = $parsed_items['theme'];
1423
 
 
1424
 
                $check_for = array(
1425
 
                        'parse_css_file'        => (int) 0,
1426
 
                        'pagination_sep'        => (string) ', '
1427
 
                );
1428
 
 
1429
 
                foreach ($check_for as $key => $default_value)
1430
 
                {
1431
 
                        $this->theme[$key] = (isset($parsed_items[$key])) ? $parsed_items[$key] : $default_value;
1432
 
                        settype($this->theme[$key], gettype($default_value));
1433
 
 
1434
 
                        if (is_string($default_value))
1435
 
                        {
1436
 
                                $this->theme[$key] = htmlspecialchars($this->theme[$key]);
1437
 
                        }
1438
 
                }
1439
 
 
1440
 
                // If the style author specified the theme needs to be cached
1441
 
                // (because of the used paths and variables) than make sure it is the case.
1442
 
                // For example, if the theme uses language-specific images it needs to be stored in db.
1443
 
                if (!$this->theme['theme_storedb'] && $this->theme['parse_css_file'])
1444
 
                {
1445
 
                        $this->theme['theme_storedb'] = 1;
1446
 
 
1447
 
                        $stylesheet = file_get_contents("{$phpbb_root_path}styles/{$this->theme['theme_path']}/theme/stylesheet.css");
1448
 
                        // Match CSS imports
1449
 
                        $matches = array();
1450
 
                        preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches);
1451
 
 
1452
 
                        if (sizeof($matches))
1453
 
                        {
1454
 
                                $content = '';
1455
 
                                foreach ($matches[0] as $idx => $match)
1456
 
                                {
1457
 
                                        if ($content = @file_get_contents("{$phpbb_root_path}styles/{$this->theme['theme_path']}/theme/" . $matches[1][$idx]))
1458
 
                                        {
1459
 
                                                $content = trim($content);
1460
 
                                        }
1461
 
                                        else
1462
 
                                        {
1463
 
                                                $content = '';
1464
 
                                        }
1465
 
                                        $stylesheet = str_replace($match, $content, $stylesheet);
1466
 
                                }
1467
 
                                unset($content);
1468
 
                        }
1469
 
 
1470
 
                        $stylesheet = str_replace('./', 'styles/' . $this->theme['theme_path'] . '/theme/', $stylesheet);
1471
 
 
1472
 
                        $sql_ary = array(
1473
 
                                'theme_data'    => $stylesheet,
1474
 
                                'theme_mtime'   => time(),
1475
 
                                'theme_storedb' => 1
1476
 
                        );
1477
 
 
1478
 
                        $sql = 'UPDATE ' . STYLES_THEME_TABLE . '
1479
 
                                SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
1480
 
                                WHERE theme_id = ' . $this->theme['theme_id'];
1481
 
                        $db->sql_query($sql);
1482
 
 
1483
 
                        unset($sql_ary);
1484
 
                }
1485
 
 
1486
 
                $template->set_template();
1487
 
 
1488
 
                $this->img_lang = (file_exists($phpbb_root_path . 'styles/' . $this->theme['imageset_path'] . '/imageset/' . $this->lang_name)) ? $this->lang_name : $config['default_lang'];
1489
 
 
1490
 
                $sql = 'SELECT image_name, image_filename, image_lang, image_height, image_width
1491
 
                        FROM ' . STYLES_IMAGESET_DATA_TABLE . '
1492
 
                        WHERE imageset_id = ' . $this->theme['imageset_id'] . "
1493
 
                        AND image_lang IN ('" . $db->sql_escape($this->img_lang) . "', '')";
1494
 
                $result = $db->sql_query($sql, 3600);
1495
 
 
1496
 
                $localised_images = false;
1497
 
                while ($row = $db->sql_fetchrow($result))
1498
 
                {
1499
 
                        if ($row['image_lang'])
1500
 
                        {
1501
 
                                $localised_images = true;
1502
 
                        }
1503
 
 
1504
 
                        $this->img_array[$row['image_name']] = $row;
1505
 
                }
1506
 
                $db->sql_freeresult($result);
1507
 
 
1508
 
                // there were no localised images, try to refresh the localised imageset for the user's language
1509
 
                if (!$localised_images)
1510
 
                {
1511
 
                        // Attention: this code ignores the image definition list from acp_styles and just takes everything
1512
 
                        // that the config file contains
1513
 
                        $sql_ary = array();
1514
 
 
1515
 
                        $db->sql_transaction('begin');
1516
 
 
1517
 
                        $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . '
1518
 
                                WHERE imageset_id = ' . $this->theme['imageset_id'] . '
1519
 
                                        AND image_lang = \'' . $db->sql_escape($this->img_lang) . '\'';
1520
 
                        $result = $db->sql_query($sql);
1521
 
 
1522
 
                        if (@file_exists("{$phpbb_root_path}styles/{$this->theme['imageset_path']}/imageset/{$this->img_lang}/imageset.cfg"))
1523
 
                        {
1524
 
                                $cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$this->theme['imageset_path']}/imageset/{$this->img_lang}/imageset.cfg");
1525
 
                                foreach ($cfg_data_imageset_data as $image_name => $value)
1526
 
                                {
1527
 
                                        if (strpos($value, '*') !== false)
1528
 
                                        {
1529
 
                                                if (substr($value, -1, 1) === '*')
1530
 
                                                {
1531
 
                                                        list($image_filename, $image_height) = explode('*', $value);
1532
 
                                                        $image_width = 0;
1533
 
                                                }
1534
 
                                                else
1535
 
                                                {
1536
 
                                                        list($image_filename, $image_height, $image_width) = explode('*', $value);
1537
 
                                                }
1538
 
                                        }
1539
 
                                        else
1540
 
                                        {
1541
 
                                                $image_filename = $value;
1542
 
                                                $image_height = $image_width = 0;
1543
 
                                        }
1544
 
 
1545
 
                                        if (strpos($image_name, 'img_') === 0 && $image_filename)
1546
 
                                        {
1547
 
                                                $image_name = substr($image_name, 4);
1548
 
                                                $sql_ary[] = array(
1549
 
                                                        'image_name'            => (string) $image_name,
1550
 
                                                        'image_filename'        => (string) $image_filename,
1551
 
                                                        'image_height'          => (int) $image_height,
1552
 
                                                        'image_width'           => (int) $image_width,
1553
 
                                                        'imageset_id'           => (int) $this->theme['imageset_id'],
1554
 
                                                        'image_lang'            => (string) $this->img_lang,
1555
 
                                                );
1556
 
                                        }
1557
 
                                }
1558
 
                        }
1559
 
 
1560
 
                        if (sizeof($sql_ary))
1561
 
                        {
1562
 
                                $db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);
1563
 
                                $db->sql_transaction('commit');
1564
 
                                $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
1565
 
 
1566
 
                                add_log('admin', 'LOG_IMAGESET_LANG_REFRESHED', $this->theme['imageset_name'], $this->img_lang);
1567
 
                        }
1568
 
                        else
1569
 
                        {
1570
 
                                $db->sql_transaction('commit');
1571
 
                                add_log('admin', 'LOG_IMAGESET_LANG_MISSING', $this->theme['imageset_name'], $this->img_lang);
1572
 
                        }
1573
 
                }
1574
 
 
1575
 
                // Call phpbb_user_session_handler() in case external application want to "bend" some variables or replace classes...
1576
 
                // After calling it we continue script execution...
1577
 
                phpbb_user_session_handler();
1578
 
 
1579
 
                // If this function got called from the error handler we are finished here.
1580
 
                if (defined('IN_ERROR_HANDLER'))
1581
 
                {
1582
 
                        return;
1583
 
                }
1584
 
 
1585
 
                // Disable board if the install/ directory is still present
1586
 
                // For the brave development army we do not care about this, else we need to comment out this everytime we develop locally
1587
 
                if (!defined('DEBUG_EXTRA') && !defined('ADMIN_START') && !defined('IN_INSTALL') && !defined('IN_LOGIN') && file_exists($phpbb_root_path . 'install'))
1588
 
                {
1589
 
                        // Adjust the message slightly according to the permissions
1590
 
                        if ($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))
1591
 
                        {
1592
 
                                $message = 'REMOVE_INSTALL';
1593
 
                        }
1594
 
                        else
1595
 
                        {
1596
 
                                $message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE';
1597
 
                        }
1598
 
                        trigger_error($message);
1599
 
                }
1600
 
 
1601
 
                // Is board disabled and user not an admin or moderator?
1602
 
                if ($config['board_disable'] && !defined('IN_LOGIN') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
1603
 
                {
1604
 
                        header('HTTP/1.1 503 Service Unavailable');
1605
 
 
1606
 
                        $message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE';
1607
 
                        trigger_error($message);
1608
 
                }
1609
 
 
1610
 
                // Is load exceeded?
1611
 
                if ($config['limit_load'] && $this->load !== false)
1612
 
                {
1613
 
                        if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN'))
1614
 
                        {
1615
 
                                // Set board disabled to true to let the admins/mods get the proper notification
1616
 
                                $config['board_disable'] = '1';
1617
 
 
1618
 
                                if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
1619
 
                                {
1620
 
                                        header('HTTP/1.1 503 Service Unavailable');
1621
 
                                        trigger_error('BOARD_UNAVAILABLE');
1622
 
                                }
1623
 
                        }
1624
 
                }
1625
 
 
1626
 
                if (isset($this->data['session_viewonline']))
1627
 
                {
1628
 
                        // Make sure the user is able to hide his session
1629
 
                        if (!$this->data['session_viewonline'])
1630
 
                        {
1631
 
                                // Reset online status if not allowed to hide the session...
1632
 
                                if (!$auth->acl_get('u_hideonline'))
1633
 
                                {
1634
 
                                        $sql = 'UPDATE ' . SESSIONS_TABLE . '
1635
 
                                                SET session_viewonline = 1
1636
 
                                                WHERE session_user_id = ' . $this->data['user_id'];
1637
 
                                        $db->sql_query($sql);
1638
 
                                        $this->data['session_viewonline'] = 1;
1639
 
                                }
1640
 
                        }
1641
 
                        else if (!$this->data['user_allow_viewonline'])
1642
 
                        {
1643
 
                                // the user wants to hide and is allowed to  -> cloaking device on.
1644
 
                                if ($auth->acl_get('u_hideonline'))
1645
 
                                {
1646
 
                                        $sql = 'UPDATE ' . SESSIONS_TABLE . '
1647
 
                                                SET session_viewonline = 0
1648
 
                                                WHERE session_user_id = ' . $this->data['user_id'];
1649
 
                                        $db->sql_query($sql);
1650
 
                                        $this->data['session_viewonline'] = 0;
1651
 
                                }
1652
 
                        }
1653
 
                }
1654
 
 
1655
 
 
1656
 
                // Does the user need to change their password? If so, redirect to the
1657
 
                // ucp profile reg_details page ... of course do not redirect if we're already in the ucp
1658
 
                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))
1659
 
                {
1660
 
                        if (strpos($this->page['query_string'], 'mode=reg_details') === false && $this->page['page_name'] != "ucp.$phpEx")
1661
 
                        {
1662
 
                                redirect(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=profile&amp;mode=reg_details'));
1663
 
                        }
1664
 
                }
1665
 
 
1666
 
                return;
1667
 
        }
1668
 
 
1669
 
        /**
1670
 
        * Add Language Items - use_db and use_help are assigned where needed (only use them to force inclusion)
1671
 
        *
1672
 
        * @param mixed $lang_set specifies the language entries to include
1673
 
        * @param bool $use_db internal variable for recursion, do not use
1674
 
        * @param bool $use_help internal variable for recursion, do not use
1675
 
        *
1676
 
        * Examples:
1677
 
        * <code>
1678
 
        * $lang_set = array('posting', 'help' => 'faq');
1679
 
        * $lang_set = array('posting', 'viewtopic', 'help' => array('bbcode', 'faq'))
1680
 
        * $lang_set = array(array('posting', 'viewtopic'), 'help' => array('bbcode', 'faq'))
1681
 
        * $lang_set = 'posting'
1682
 
        * $lang_set = array('help' => 'faq', 'db' => array('help:faq', 'posting'))
1683
 
        * </code>
1684
 
        */
1685
 
        function add_lang($lang_set, $use_db = false, $use_help = false)
1686
 
        {
1687
 
                global $phpEx;
1688
 
 
1689
 
                if (is_array($lang_set))
1690
 
                {
1691
 
                        foreach ($lang_set as $key => $lang_file)
1692
 
                        {
1693
 
                                // Please do not delete this line.
1694
 
                                // We have to force the type here, else [array] language inclusion will not work
1695
 
                                $key = (string) $key;
1696
 
 
1697
 
                                if ($key == 'db')
1698
 
                                {
1699
 
                                        $this->add_lang($lang_file, true, $use_help);
1700
 
                                }
1701
 
                                else if ($key == 'help')
1702
 
                                {
1703
 
                                        $this->add_lang($lang_file, $use_db, true);
1704
 
                                }
1705
 
                                else if (!is_array($lang_file))
1706
 
                                {
1707
 
                                        $this->set_lang($this->lang, $this->help, $lang_file, $use_db, $use_help);
1708
 
                                }
1709
 
                                else
1710
 
                                {
1711
 
                                        $this->add_lang($lang_file, $use_db, $use_help);
1712
 
                                }
1713
 
                        }
1714
 
                        unset($lang_set);
1715
 
                }
1716
 
                else if ($lang_set)
1717
 
                {
1718
 
                        $this->set_lang($this->lang, $this->help, $lang_set, $use_db, $use_help);
1719
 
                }
1720
 
        }
1721
 
 
1722
 
        /**
1723
 
        * Set language entry (called by add_lang)
1724
 
        * @access private
1725
 
        */
1726
 
        function set_lang(&$lang, &$help, $lang_file, $use_db = false, $use_help = false)
1727
 
        {
1728
 
                global $phpEx;
1729
 
 
1730
 
                // Make sure the language path is set (if the user setup did not happen it is not set)
1731
 
                if (!$this->lang_path)
1732
 
                {
1733
 
                        global $phpbb_root_path, $config;
1734
 
 
1735
 
                        $this->lang_path = $phpbb_root_path . 'language/' . basename($config['default_lang']) . '/';
1736
 
                }
1737
 
 
1738
 
                // $lang == $this->lang
1739
 
                // $help == $this->help
1740
 
                // - add appropriate variables here, name them as they are used within the language file...
1741
 
                if (!$use_db)
1742
 
                {
1743
 
                        if ($use_help && strpos($lang_file, '/') !== false)
1744
 
                        {
1745
 
                                $language_filename = $this->lang_path . substr($lang_file, 0, stripos($lang_file, '/') + 1) . 'help_' . substr($lang_file, stripos($lang_file, '/') + 1) . '.' . $phpEx;
1746
 
                        }
1747
 
                        else
1748
 
                        {
1749
 
                                $language_filename = $this->lang_path . (($use_help) ? 'help_' : '') . $lang_file . '.' . $phpEx;
1750
 
                        }
1751
 
 
1752
 
                        if ((@include $language_filename) === false)
1753
 
                        {
1754
 
                                trigger_error('Language file ' . basename($language_filename) . ' couldn\'t be opened.', E_USER_ERROR);
1755
 
                        }
1756
 
                }
1757
 
                else if ($use_db)
1758
 
                {
1759
 
                        // Get Database Language Strings
1760
 
                        // Put them into $lang if nothing is prefixed, put them into $help if help: is prefixed
1761
 
                        // For example: help:faq, posting
1762
 
                }
1763
 
        }
1764
 
 
1765
 
        /**
1766
 
        * Format user date
1767
 
        */
1768
 
        function format_date($gmepoch, $format = false, $forcedate = false)
1769
 
        {
1770
 
                static $midnight;
1771
 
 
1772
 
                $lang_dates = $this->lang['datetime'];
1773
 
                $format = (!$format) ? $this->date_format : $format;
1774
 
 
1775
 
                // Short representation of month in format
1776
 
                if ((strpos($format, '\M') === false && strpos($format, 'M') !== false) || (strpos($format, '\r') === false && strpos($format, 'r') !== false))
1777
 
                {
1778
 
                        $lang_dates['May'] = $lang_dates['May_short'];
1779
 
                }
1780
 
 
1781
 
                unset($lang_dates['May_short']);
1782
 
 
1783
 
                if (!$midnight)
1784
 
                {
1785
 
                        list($d, $m, $y) = explode(' ', gmdate('j n Y', time() + $this->timezone + $this->dst));
1786
 
                        $midnight = gmmktime(0, 0, 0, $m, $d, $y) - $this->timezone - $this->dst;
1787
 
                }
1788
 
 
1789
 
                if (strpos($format, '|') === false || ($gmepoch < $midnight - 86400 && !$forcedate) || ($gmepoch > $midnight + 172800 && !$forcedate))
1790
 
                {
1791
 
                        return strtr(@gmdate(str_replace('|', '', $format), $gmepoch + $this->timezone + $this->dst), $lang_dates);
1792
 
                }
1793
 
 
1794
 
                if ($gmepoch > $midnight + 86400 && !$forcedate)
1795
 
                {
1796
 
                        $format = substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1);
1797
 
                        return str_replace('||', $this->lang['datetime']['TOMORROW'], strtr(@gmdate($format, $gmepoch + $this->timezone + $this->dst), $lang_dates));
1798
 
                }
1799
 
                else if ($gmepoch > $midnight && !$forcedate)
1800
 
                {
1801
 
                        $format = substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1);
1802
 
                        return str_replace('||', $this->lang['datetime']['TODAY'], strtr(@gmdate($format, $gmepoch + $this->timezone + $this->dst), $lang_dates));
1803
 
                }
1804
 
                else if ($gmepoch > $midnight - 86400 && !$forcedate)
1805
 
                {
1806
 
                        $format = substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1);
1807
 
                        return str_replace('||', $this->lang['datetime']['YESTERDAY'], strtr(@gmdate($format, $gmepoch + $this->timezone + $this->dst), $lang_dates));
1808
 
                }
1809
 
 
1810
 
                return strtr(@gmdate(str_replace('|', '', $format), $gmepoch + $this->timezone + $this->dst), $lang_dates);
1811
 
        }
1812
 
 
1813
 
        /**
1814
 
        * Get language id currently used by the user
1815
 
        */
1816
 
        function get_iso_lang_id()
1817
 
        {
1818
 
                global $config, $db;
1819
 
 
1820
 
                if (!empty($this->lang_id))
1821
 
                {
1822
 
                        return $this->lang_id;
1823
 
                }
1824
 
 
1825
 
                if (!$this->lang_name)
1826
 
                {
1827
 
                        $this->lang_name = $config['default_lang'];
1828
 
                }
1829
 
 
1830
 
                $sql = 'SELECT lang_id
1831
 
                        FROM ' . LANG_TABLE . "
1832
 
                        WHERE lang_iso = '" . $db->sql_escape($this->lang_name) . "'";
1833
 
                $result = $db->sql_query($sql);
1834
 
                $this->lang_id = (int) $db->sql_fetchfield('lang_id');
1835
 
                $db->sql_freeresult($result);
1836
 
 
1837
 
                return $this->lang_id;
1838
 
        }
1839
 
 
1840
 
        /**
1841
 
        * Get users profile fields
1842
 
        */
1843
 
        function get_profile_fields($user_id)
1844
 
        {
1845
 
                global $db;
1846
 
 
1847
 
                if (isset($this->profile_fields))
1848
 
                {
1849
 
                        return;
1850
 
                }
1851
 
 
1852
 
                $sql = 'SELECT *
1853
 
                        FROM ' . PROFILE_FIELDS_DATA_TABLE . "
1854
 
                        WHERE user_id = $user_id";
1855
 
                $result = $db->sql_query_limit($sql, 1);
1856
 
                $this->profile_fields = (!($row = $db->sql_fetchrow($result))) ? array() : $row;
1857
 
                $db->sql_freeresult($result);
1858
 
        }
1859
 
 
1860
 
        /**
1861
 
        * Specify/Get image
1862
 
        */
1863
 
        function img($img, $alt = '', $width = false, $suffix = '', $type = 'full_tag')
1864
 
        {
1865
 
                static $imgs;
1866
 
                global $phpbb_root_path;
1867
 
 
1868
 
                $img_data = &$imgs[$img];
1869
 
 
1870
 
                if (empty($img_data))
1871
 
                {
1872
 
                        if (!isset($this->img_array[$img]))
1873
 
                        {
1874
 
                                // Do not fill the image to let designers decide what to do if the image is empty
1875
 
                                $img_data = '';
1876
 
                                return $img_data;
1877
 
                        }
1878
 
 
1879
 
                        $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'];
1880
 
                        $img_data['width'] = $this->img_array[$img]['image_width'];
1881
 
                        $img_data['height'] = $this->img_array[$img]['image_height'];
1882
 
                }
1883
 
 
1884
 
                $alt = (!empty($this->lang[$alt])) ? $this->lang[$alt] : $alt;
1885
 
 
1886
 
                switch ($type)
1887
 
                {
1888
 
                        case 'src':
1889
 
                                return $img_data['src'];
1890
 
                        break;
1891
 
 
1892
 
                        case 'width':
1893
 
                                return ($width === false) ? $img_data['width'] : $width;
1894
 
                        break;
1895
 
 
1896
 
                        case 'height':
1897
 
                                return $img_data['height'];
1898
 
                        break;
1899
 
 
1900
 
                        default:
1901
 
                                $use_width = ($width === false) ? $img_data['width'] : $width;
1902
 
 
1903
 
                                return '<img src="' . $img_data['src'] . '"' . (($use_width) ? ' width="' . $use_width . '"' : '') . (($img_data['height']) ? ' height="' . $img_data['height'] . '"' : '') . ' alt="' . $alt . '" title="' . $alt . '" />';
1904
 
                        break;
1905
 
                }
1906
 
        }
1907
 
 
1908
 
        /**
1909
 
        * Get option bit field from user options
1910
 
        */
1911
 
        function optionget($key, $data = false)
1912
 
        {
1913
 
                if (!isset($this->keyvalues[$key]))
1914
 
                {
1915
 
                        $var = ($data) ? $data : $this->data['user_options'];
1916
 
                        $this->keyvalues[$key] = ($var & 1 << $this->keyoptions[$key]) ? true : false;
1917
 
                }
1918
 
 
1919
 
                return $this->keyvalues[$key];
1920
 
        }
1921
 
 
1922
 
        /**
1923
 
        * Set option bit field for user options
1924
 
        */
1925
 
        function optionset($key, $value, $data = false)
1926
 
        {
1927
 
                $var = ($data) ? $data : $this->data['user_options'];
1928
 
 
1929
 
                if ($value && !($var & 1 << $this->keyoptions[$key]))
1930
 
                {
1931
 
                        $var += 1 << $this->keyoptions[$key];
1932
 
                }
1933
 
                else if (!$value && ($var & 1 << $this->keyoptions[$key]))
1934
 
                {
1935
 
                        $var -= 1 << $this->keyoptions[$key];
1936
 
                }
1937
 
                else
1938
 
                {
1939
 
                        return ($data) ? $var : false;
1940
 
                }
1941
 
 
1942
 
                if (!$data)
1943
 
                {
1944
 
                        $this->data['user_options'] = $var;
1945
 
                        return true;
1946
 
                }
1947
 
                else
1948
 
                {
1949
 
                        return $var;
1950
 
                }
1951
 
  }
1952
 
 
1953
 
  /** IVLE AUTH
1954
 
   * This function attempts to authenticate from a signed cookie provided by 
1955
 
   * IVLE. If it does it will return either the forum user_id for the logged in 
1956
 
   * IVLE user or will create a new one on-the-fly.
1957
 
   * 
1958
 
   * If a bad authentication is given then the ANONAMOUS user will be returned
1959
 
   */
1960
 
  function ivle_auth()
1961
 
  {
1962
 
        global $db, $phpEx;
1963
 
 
1964
 
        // Get the shared secret between IVLE and the Forum
1965
 
        require($phpbb_root_path . 'config.' . $phpEx);
1966
 
 
1967
 
        // Shared Cookie
1968
 
        $ivle_cookie = explode(':',$_COOKIE['ivleforumcookie']);
1969
 
   
1970
 
        if ($ivle_cookie == "NONE") {
1971
 
                return ANONYMOUS;
1972
 
        }
1973
 
 
1974
 
        // Decode and unescape the Cookie contents
1975
 
        $ivle_uid = urldecode($ivle_cookie[0]);
1976
 
        $ivle_nick = urldecode($ivle_cookie[1]);
1977
 
        $ivle_email = urldecode($ivle_cookie[2]);
1978
 
        $ivle_role = urldecode($ivle_cookie[3]);
1979
 
        $ivle_hash = $ivle_cookie[4];
1980
 
 
1981
 
        // Check if uid + nick + email + secret is the same as the hash
1982
 
        //$ivle_auth = False; // Flag just incase anything else need to know
1983
 
        if(md5($ivle_cookie[0].$ivle_cookie[1].$ivle_cookie[2].$ivle_cookie[3].$forum_secret) 
1984
 
        == $ivle_hash) {
1985
 
          //$ivle_auth = True;
1986
 
        
1987
 
        // Check if the user exists in the database
1988
 
        $sql = 'SELECT user_id
1989
 
                FROM ' . USERS_TABLE . "
1990
 
                WHERE username = '" . $db->sql_escape($ivle_uid) . "';";
1991
 
                $result = $db->sql_query($sql);
1992
 
                $row = $db->sql_fetchrow($result);
1993
 
                $user_id = $row['user_id'];
1994
 
                $db->sql_freeresult($result);
1995
 
 
1996
 
        // If no user_id is found for the username, create a new user
1997
 
        if(!$user_id) {
1998
 
                // Needed for IVLE auth overide
1999
 
                include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
2000
 
           
2001
 
                // Add all users to the Registered Group
2002
 
                $sql = 'SELECT group_id
2003
 
                        FROM ' . GROUPS_TABLE . "
2004
 
                        WHERE group_name = '" . $db->sql_escape('REGISTERED') . "'
2005
 
                        AND group_type = " . GROUP_SPECIAL;
2006
 
                $result = $db->sql_query($sql);
2007
 
                $row = $db->sql_fetchrow($result);
2008
 
                $db->sql_freeresult($result);
2009
 
                if (!$row) {
2010
 
                        trigger_error('NO_GROUP');
2011
 
                }
2012
 
 
2013
 
                $group_id = $row['group_id'];
2014
 
 
2015
 
                // Get the Time and Timezone
2016
 
                $timezone = date('Z') / 3600;
2017
 
                $is_dst = date('I');
2018
 
                $timezone = ($is_dst) ? $timezone - 1 : $timezone;
2019
 
                        
2020
 
                // Fill into array
2021
 
                $user_row = array(
2022
 
                        'username'                              => $ivle_uid,
2023
 
                        'user_password'                 => '', # Not a valid hash
2024
 
                        'user_email'                    => $ivle_email,
2025
 
                        'group_id'                              => (int) $group_id,
2026
 
                        'user_timezone'                 => (float) $timezone,
2027
 
                        'user_dst'                              => $is_dst,
2028
 
                        'user_lang'                             => 'en',
2029
 
                        'user_type'                             => USER_NORMAL,
2030
 
                        'user_actkey'                   => '',
2031
 
                        'user_ip'                               => $this->ip,
2032
 
                        'user_regdate'                  => time(),
2033
 
                        'user_inactive_reason'  => 0,
2034
 
                        'user_inactive_time'    => 0,
2035
 
                );
2036
 
                 
2037
 
                // Add user
2038
 
                $user_id = user_add($user_row);
2039
 
 
2040
 
                // Add any aditional groups
2041
 
                // Select the equvialent group
2042
 
                $group = False;
2043
 
                switch($ivle_role) {
2044
 
                        case('admin'):
2045
 
                                $group = 'ADMINISTRATORS';
2046
 
                                break;
2047
 
                        case('lecturer'):
2048
 
                                $group = 'GLOBAL_MODERATORS';
2049
 
                                break;
2050
 
                }
2051
 
                if ($group) {
2052
 
                        // Find the group_id
2053
 
                        $sql = 'SELECT group_id
2054
 
                                FROM ' . GROUPS_TABLE . "
2055
 
                                WHERE group_name = '" . $db->sql_escape($group) . "'
2056
 
                                AND group_type = " . GROUP_SPECIAL;
2057
 
                        
2058
 
                        $result = $db->sql_query($sql);
2059
 
                        $row = $db->sql_fetchrow($result);
2060
 
                        $db->sql_freeresult($result);
2061
 
 
2062
 
                        if (!$row) {
2063
 
                                trigger_error('NO_GROUP');
2064
 
                        }
2065
 
 
2066
 
                        $group_id = $row['group_id'];
2067
 
 
2068
 
                        group_user_add($group_id,Array($user_id));
2069
 
                }
2070
 
          }
2071
 
          return $user_id;
2072
 
        } else {
2073
 
          return False;
2074
 
        }
2075
 
  }
2076
 
}
2077
 
?>