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

443 by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0
1
<?php
2
/**
3
*
4
* @package phpBB3
5
* @version $Id: auth.php,v 1.88 2007/10/05 14:30:07 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
* Permission/Auth class
21
* @package phpBB3
22
*/
23
class auth
24
{
25
	var $acl = array();
26
	var $cache = array();
27
	var $acl_options = array();
28
	var $acl_forum_ids = false;
29
30
	/**
31
	* Init permissions
32
	*/
33
	function acl(&$userdata)
34
	{
35
		global $db, $cache;
36
37
		$this->acl = $this->cache = $this->acl_options = array();
38
		$this->acl_forum_ids = false;
39
40
		if (($this->acl_options = $cache->get('_acl_options')) === false)
41
		{
42
			$sql = 'SELECT auth_option, is_global, is_local
43
				FROM ' . ACL_OPTIONS_TABLE . '
44
				ORDER BY auth_option_id';
45
			$result = $db->sql_query($sql);
46
47
			$global = $local = 0;
48
			$this->acl_options = array();
49
			while ($row = $db->sql_fetchrow($result))
50
			{
51
				if ($row['is_global'])
52
				{
53
					$this->acl_options['global'][$row['auth_option']] = $global++;
54
				}
55
56
				if ($row['is_local'])
57
				{
58
					$this->acl_options['local'][$row['auth_option']] = $local++;
59
				}
60
			}
61
			$db->sql_freeresult($result);
62
63
			$cache->put('_acl_options', $this->acl_options);
64
			$this->acl_cache($userdata);
65
		}
66
		else if (!trim($userdata['user_permissions']))
67
		{
68
			$this->acl_cache($userdata);
69
		}
70
71
		$user_permissions = explode("\n", $userdata['user_permissions']);
72
73
		foreach ($user_permissions as $f => $seq)
74
		{
75
			if ($seq)
76
			{
77
				$i = 0;
78
79
				if (!isset($this->acl[$f]))
80
				{
81
					$this->acl[$f] = '';
82
				}
83
84
				while ($subseq = substr($seq, $i, 6))
85
				{
86
					// We put the original bitstring into the acl array
87
					$this->acl[$f] .= str_pad(base_convert($subseq, 36, 2), 31, 0, STR_PAD_LEFT);
88
					$i += 6;
89
				}
90
			}
91
		}
92
93
		return;
94
	}
95
96
	/**
97
	* Look up an option
98
	* if the option is prefixed with !, then the result becomes negated
99
	*
100
	* If a forum id is specified the local option will be combined with a global option if one exist.
101
	* If a forum id is not specified, only the global option will be checked.
102
	*/
103
	function acl_get($opt, $f = 0)
104
	{
105
		$negate = false;
106
107
		if (strpos($opt, '!') === 0)
108
		{
109
			$negate = true;
110
			$opt = substr($opt, 1);
111
		}
112
113
		if (!isset($this->cache[$f][$opt]))
114
		{
115
			// We combine the global/local option with an OR because some options are global and local.
116
			// If the user has the global permission the local one is true too and vice versa
117
			$this->cache[$f][$opt] = false;
118
119
			// Is this option a global permission setting?
120
			if (isset($this->acl_options['global'][$opt]))
121
			{
122
				if (isset($this->acl[0]))
123
				{
124
					$this->cache[$f][$opt] = $this->acl[0][$this->acl_options['global'][$opt]];
125
				}
126
			}
127
128
			// Is this option a local permission setting?
129
			// But if we check for a global option only, we won't combine the options...
130
			if ($f != 0 && isset($this->acl_options['local'][$opt]))
131
			{
132
				if (isset($this->acl[$f]) && isset($this->acl[$f][$this->acl_options['local'][$opt]]))
133
				{
134
					$this->cache[$f][$opt] |= $this->acl[$f][$this->acl_options['local'][$opt]];
135
				}
136
			}
137
		}
138
139
		// Founder always has all global options set to true...
140
		return ($negate) ? !$this->cache[$f][$opt] : $this->cache[$f][$opt];
141
	}
142
143
	/**
144
	* Get forums with the specified permission setting
145
	* if the option is prefixed with !, then the result becomes nagated
146
	*
147
	* @param bool $clean set to true if only values needs to be returned which are set/unset
148
	*/
149
	function acl_getf($opt, $clean = false)
150
	{
151
		$acl_f = array();
152
		$negate = false;
153
154
		if (strpos($opt, '!') === 0)
155
		{
156
			$negate = true;
157
			$opt = substr($opt, 1);
158
		}
159
160
		// If we retrieve a list of forums not having permissions in, we need to get every forum_id
161
		if ($negate)
162
		{
163
			if ($this->acl_forum_ids === false)
164
			{
165
				global $db;
166
167
				$sql = 'SELECT forum_id
168
					FROM ' . FORUMS_TABLE;
169
				
170
				if (sizeof($this->acl))
171
				{
172
					$sql .= ' WHERE ' . $db->sql_in_set('forum_id', array_keys($this->acl), true);
173
				}
174
				$result = $db->sql_query($sql);
175
176
				$this->acl_forum_ids = array();
177
				while ($row = $db->sql_fetchrow($result))
178
				{
179
					$this->acl_forum_ids[] = $row['forum_id'];
180
				}
181
				$db->sql_freeresult($result);
182
			}
183
		}
184
		
185
		if (isset($this->acl_options['local'][$opt]))
186
		{
187
			foreach ($this->acl as $f => $bitstring)
188
			{
189
				// Skip global settings
190
				if (!$f)
191
				{
192
					continue;
193
				}
194
195
				$allowed = (!isset($this->cache[$f][$opt])) ? $this->acl_get($opt, $f) : $this->cache[$f][$opt];
196
197
				if (!$clean)
198
				{
199
					$acl_f[$f][$opt] = ($negate) ? !$allowed : $allowed;
200
				}
201
				else
202
				{
203
					if (($negate && !$allowed) || (!$negate && $allowed))
204
					{
205
						$acl_f[$f][$opt] = 1;
206
					}
207
				}
208
			}
209
		}
210
211
		// If we get forum_ids not having this permission, we need to fill the remaining parts
212
		if ($negate && sizeof($this->acl_forum_ids))
213
		{
214
			foreach ($this->acl_forum_ids as $f)
215
			{
216
				$acl_f[$f][$opt] = 1;
217
			}
218
		}
219
220
		return $acl_f;
221
	}
222
223
	/**
224
	* Get local permission state for any forum.
225
	*
226
	* Returns true if user has the permission in one or more forums, false if in no forum.
227
	* If global option is checked it returns the global state (same as acl_get($opt))
228
	* Local option has precedence...
229
	*/
230
	function acl_getf_global($opt)
231
	{
232
		if (is_array($opt))
233
		{
234
			// evaluates to true as soon as acl_getf_global is true for one option
235
			foreach ($opt as $check_option)
236
			{
237
				if ($this->acl_getf_global($check_option))
238
				{
239
					return true;
240
				}
241
			}
242
243
			return false;
244
		}
245
246
		if (isset($this->acl_options['local'][$opt]))
247
		{
248
			foreach ($this->acl as $f => $bitstring)
249
			{
250
				// Skip global settings
251
				if (!$f)
252
				{
253
					continue;
254
				}
255
256
				// as soon as the user has any permission we're done so return true
257
				if ((!isset($this->cache[$f][$opt])) ? $this->acl_get($opt, $f) : $this->cache[$f][$opt])
258
				{
259
					return true;
260
				}
261
			}
262
		}
263
		else if (isset($this->acl_options['global'][$opt]))
264
		{
265
			return $this->acl_get($opt);
266
		}
267
268
		return false;
269
	}
270
271
	/**
272
	* Get permission settings (more than one)
273
	*/
274
	function acl_gets()
275
	{
276
		$args = func_get_args();
277
		$f = array_pop($args);
278
279
		if (!is_numeric($f))
280
		{
281
			$args[] = $f;
282
			$f = 0;
283
		}
284
285
		// alternate syntax: acl_gets(array('m_', 'a_'), $forum_id)
286
		if (is_array($args[0]))
287
		{
288
			$args = $args[0];
289
		}
290
291
		$acl = 0;
292
		foreach ($args as $opt)
293
		{
294
			$acl |= $this->acl_get($opt, $f);
295
		}
296
297
		return $acl;
298
	}
299
300
	/**
301
	* Get permission listing based on user_id/options/forum_ids
302
	*/
303
	function acl_get_list($user_id = false, $opts = false, $forum_id = false)
304
	{
305
		$hold_ary = $this->acl_raw_data($user_id, $opts, $forum_id);
306
307
		$auth_ary = array();
308
		foreach ($hold_ary as $user_id => $forum_ary)
309
		{
310
			foreach ($forum_ary as $forum_id => $auth_option_ary)
311
			{
312
				foreach ($auth_option_ary as $auth_option => $auth_setting)
313
				{
314
					if ($auth_setting)
315
					{
316
						$auth_ary[$forum_id][$auth_option][] = $user_id;
317
					}
318
				}
319
			}
320
		}
321
322
		return $auth_ary;
323
	}
324
325
	/**
326
	* Cache data to user_permissions row
327
	*/
328
	function acl_cache(&$userdata)
329
	{
330
		global $db;
331
332
		// Empty user_permissions
333
		$userdata['user_permissions'] = '';
334
335
		$hold_ary = $this->acl_raw_data($userdata['user_id'], false, false);
336
337
		if (isset($hold_ary[$userdata['user_id']]))
338
		{
339
			$hold_ary = $hold_ary[$userdata['user_id']];
340
		}
341
342
		// Key 0 in $hold_ary are global options, all others are forum_ids
343
344
		// If this user is founder we're going to force fill the admin options ...
345
		if ($userdata['user_type'] == USER_FOUNDER)
346
		{
347
			foreach ($this->acl_options['global'] as $opt => $id)
348
			{
349
				if (strpos($opt, 'a_') === 0)
350
				{
351
					$hold_ary[0][$opt] = ACL_YES;
352
				}
353
			}
354
		}
355
356
		// Sometimes, it can happen $hold_ary holding forums which do not exist.
357
		// Since this function is not called that often (we are caching the data) we check for this inconsistency.
358
		$sql = 'SELECT forum_id
359
			FROM ' . FORUMS_TABLE . '
360
			WHERE ' . $db->sql_in_set('forum_id', array_keys($hold_ary), false, true);
361
		$result = $db->sql_query($sql);
362
363
		$forum_ids = (isset($hold_ary[0])) ? array(0) : array();
364
		while ($row = $db->sql_fetchrow($result))
365
		{
366
			$forum_ids[] = $row['forum_id'];
367
		}
368
		$db->sql_freeresult($result);
369
370
		// Now determine forums which do not exist and remove the unneeded information (for modding purposes it is clearly the wrong place. ;))
371
		$missing_forums = array_diff(array_keys($hold_ary), $forum_ids);
372
373
		if (sizeof($missing_forums))
374
		{
375
			foreach ($missing_forums as $forum_id)
376
			{
377
				unset($hold_ary[$forum_id]);
378
			}
379
380
			$sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $missing_forums);
381
			$db->sql_query($sql);
382
383
			$sql = 'DELETE FROM ' . ACL_USERS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $missing_forums);
384
			$db->sql_query($sql);
385
		}
386
387
		$hold_str = $this->build_bitstring($hold_ary);
388
389
		if ($hold_str)
390
		{
391
			$userdata['user_permissions'] = $hold_str;
392
393
			$sql = 'UPDATE ' . USERS_TABLE . "
394
				SET user_permissions = '" . $db->sql_escape($userdata['user_permissions']) . "',
395
					user_perm_from = 0
396
				WHERE user_id = " . $userdata['user_id'];
397
			$db->sql_query($sql);
398
		}
399
400
		return;
401
	}
402
403
	/**
404
	* Build bitstring from permission set
405
	*/
406
	function build_bitstring(&$hold_ary)
407
	{
408
		$hold_str = '';
409
410
		if (sizeof($hold_ary))
411
		{
412
			ksort($hold_ary);
413
414
			$last_f = 0;
415
416
			foreach ($hold_ary as $f => $auth_ary)
417
			{
418
				$ary_key = (!$f) ? 'global' : 'local';
419
420
				$bitstring = array();
421
				foreach ($this->acl_options[$ary_key] as $opt => $id)
422
				{
423
					if (isset($auth_ary[$opt]))
424
					{
425
						$bitstring[$id] = $auth_ary[$opt];
426
427
						$option_key = substr($opt, 0, strpos($opt, '_') + 1);
428
429
						// If one option is allowed, the global permission for this option has to be allowed too
430
						// example: if the user has the a_ permission this means he has one or more a_* permissions
431
						if ($auth_ary[$opt] == ACL_YES && (!isset($bitstring[$this->acl_options[$ary_key][$option_key]]) || $bitstring[$this->acl_options[$ary_key][$option_key]] == ACL_NEVER))
432
						{
433
							$bitstring[$this->acl_options[$ary_key][$option_key]] = ACL_YES;
434
						}
435
					}
436
					else
437
					{
438
						$bitstring[$id] = ACL_NEVER;
439
					}
440
				}
441
442
				// Now this bitstring defines the permission setting for the current forum $f (or global setting)
443
				$bitstring = implode('', $bitstring);
444
445
				// The line number indicates the id, therefore we have to add empty lines for those ids not present
446
				$hold_str .= str_repeat("\n", $f - $last_f);
447
			
448
				// Convert bitstring for storage - we do not use binary/bytes because PHP's string functions are not fully binary safe
449
				for ($i = 0, $bit_length = strlen($bitstring); $i < $bit_length; $i += 31)
450
				{
451
					$hold_str .= str_pad(base_convert(str_pad(substr($bitstring, $i, 31), 31, 0, STR_PAD_RIGHT), 2, 36), 6, 0, STR_PAD_LEFT);
452
				}
453
454
				$last_f = $f;
455
			}
456
			unset($bitstring);
457
458
			$hold_str = rtrim($hold_str);
459
		}
460
461
		return $hold_str;
462
	}
463
464
	/**
465
	* Clear one or all users cached permission settings
466
	*/
467
	function acl_clear_prefetch($user_id = false)
468
	{
469
		global $db;
470
471
		$where_sql = '';
472
473
		if ($user_id !== false)
474
		{
475
			$user_id = (!is_array($user_id)) ? $user_id = array((int) $user_id) : array_map('intval', $user_id);
476
			$where_sql = ' WHERE ' . $db->sql_in_set('user_id', $user_id);
477
		}
478
479
		$sql = 'UPDATE ' . USERS_TABLE . "
480
			SET user_permissions = '',
481
				user_perm_from = 0
482
			$where_sql";
483
		$db->sql_query($sql);
484
485
		return;
486
	}
487
488
	/**
489
	* Get assigned roles
490
	*/
491
	function acl_role_data($user_type, $role_type, $ug_id = false, $forum_id = false)
492
	{
493
		global $db;
494
495
		$roles = array();
496
497
		$sql_id = ($user_type == 'user') ? 'user_id' : 'group_id';
498
499
		$sql_ug = ($ug_id !== false) ? ((!is_array($ug_id)) ? "AND a.$sql_id = $ug_id" : 'AND ' . $db->sql_in_set("a.$sql_id", $ug_id)) : '';
500
		$sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? "AND a.forum_id = $forum_id" : 'AND ' . $db->sql_in_set('a.forum_id', $forum_id)) : '';
501
502
		// Grab assigned roles...
503
		$sql = 'SELECT a.auth_role_id, a.' . $sql_id . ', a.forum_id
504
			FROM ' . (($user_type == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE) . ' a, ' . ACL_ROLES_TABLE . " r
505
			WHERE a.auth_role_id = r.role_id
506
				AND r.role_type = '" . $db->sql_escape($role_type) . "'
507
				$sql_ug
508
				$sql_forum
509
			ORDER BY r.role_order ASC";
510
		$result = $db->sql_query($sql);
511
512
		while ($row = $db->sql_fetchrow($result))
513
		{
514
			$roles[$row[$sql_id]][$row['forum_id']] = $row['auth_role_id'];
515
		}
516
		$db->sql_freeresult($result);
517
518
		return $roles;
519
	}
520
521
	/**
522
	* Get raw acl data based on user/option/forum
523
	*/
524
	function acl_raw_data($user_id = false, $opts = false, $forum_id = false)
525
	{
526
		global $db;
527
528
		$sql_user = ($user_id !== false) ? ((!is_array($user_id)) ? 'user_id = ' . (int) $user_id : $db->sql_in_set('user_id', array_map('intval', $user_id))) : '';
529
		$sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? 'AND a.forum_id = ' . (int) $forum_id : 'AND ' . $db->sql_in_set('a.forum_id', array_map('intval', $forum_id))) : '';
530
531
		$sql_opts = '';
532
533
		if ($opts !== false)
534
		{
535
			$this->build_auth_option_statement('ao.auth_option', $opts, $sql_opts);
536
		}
537
538
		$hold_ary = array();
539
540
		// First grab user settings ... each user has only one setting for each
541
		// option ... so we shouldn't need any ACL_NEVER checks ... he says ...
542
		// Grab assigned roles...
543
		$sql = $db->sql_build_query('SELECT', array(
544
			'SELECT'	=> 'ao.auth_option, a.auth_role_id, r.auth_setting as role_auth_setting, a.user_id, a.forum_id, a.auth_setting',
545
546
			'FROM'		=> array(
547
				ACL_OPTIONS_TABLE	=> 'ao',
548
				ACL_USERS_TABLE		=> 'a'
549
			),
550
551
			'LEFT_JOIN'	=> array(
552
				array(
553
					'FROM'	=> array(ACL_ROLES_DATA_TABLE => 'r'),
554
					'ON'	=> 'a.auth_role_id = r.role_id'
555
				)
556
			),
557
558
			'WHERE'		=> '(ao.auth_option_id = a.auth_option_id OR ao.auth_option_id = r.auth_option_id)
559
				' . (($sql_user) ? 'AND a.' . $sql_user : '') . "
560
				$sql_forum
561
				$sql_opts",
562
		));
563
		$result = $db->sql_query($sql);
564
565
		while ($row = $db->sql_fetchrow($result))
566
		{
567
			$setting = ($row['auth_role_id']) ? $row['role_auth_setting'] : $row['auth_setting'];
568
			$hold_ary[$row['user_id']][$row['forum_id']][$row['auth_option']] = $setting;
569
		}
570
		$db->sql_freeresult($result);
571
572
		// Now grab group settings ... ACL_NEVER overrides ACL_YES so act appropriatley
573
		$sql_ary[] = $db->sql_build_query('SELECT', array(
574
			'SELECT'	=> 'ug.user_id, ao.auth_option, a.forum_id, a.auth_setting, a.auth_role_id, r.auth_setting as role_auth_setting',
575
576
			'FROM'		=> array(
577
				USER_GROUP_TABLE	=> 'ug',
578
				ACL_OPTIONS_TABLE	=> 'ao',
579
				ACL_GROUPS_TABLE	=> 'a'
580
			),
581
582
			'LEFT_JOIN'	=> array(
583
				array(
584
					'FROM'	=> array(ACL_ROLES_DATA_TABLE => 'r'),
585
					'ON'	=> 'a.auth_role_id = r.role_id'
586
				)
587
			),
588
589
			'WHERE'		=> 'ao.auth_option_id = a.auth_option_id
590
				AND a.group_id = ug.group_id
591
				AND ug.user_pending = 0
592
				' . (($sql_user) ? 'AND ug.' . $sql_user : '') . "
593
				$sql_forum
594
				$sql_opts"
595
		));
596
597
		$sql_ary[] = $db->sql_build_query('SELECT', array(
598
			'SELECT'	=> 'ug.user_id,  a.forum_id, a.auth_setting, a.auth_role_id, r.auth_setting as role_auth_setting, ao.auth_option' ,
599
600
			'FROM'		=> array(
601
				ACL_OPTIONS_TABLE	=> 'ao'
602
				
603
			),
604
605
			'LEFT_JOIN'	=> array(
606
				
607
				array(
608
					'FROM'	=> array(ACL_ROLES_DATA_TABLE => 'r'),
609
					'ON'	=> 'r.auth_option_id = ao.auth_option_id'
610
				),
611
				array(
612
					'FROM'	=> array(ACL_GROUPS_TABLE	=> 'a'),
613
					'ON'	=> 'a.auth_role_id = r.role_id'
614
				),
615
				array(
616
					'FROM'	=> array(USER_GROUP_TABLE	=> 'ug'),
617
					'ON'	=> 'ug.group_id = a.group_id'
618
				)
619
				
620
			),
621
622
			'WHERE'		=> 'ug.user_pending = 0
623
				' . (($sql_user) ? 'AND ug.' . $sql_user : '') . "
624
				$sql_forum
625
				$sql_opts"
626
		));
627
		
628
629
		foreach ($sql_ary as $sql)
630
		{
631
			$result = $db->sql_query($sql);
632
633
			while ($row = $db->sql_fetchrow($result))
634
			{
635
				if (!isset($hold_ary[$row['user_id']][$row['forum_id']][$row['auth_option']]) || (isset($hold_ary[$row['user_id']][$row['forum_id']][$row['auth_option']]) && $hold_ary[$row['user_id']][$row['forum_id']][$row['auth_option']] != ACL_NEVER))
636
				{
637
					$setting = ($row['auth_role_id']) ? $row['role_auth_setting'] : $row['auth_setting'];
638
					$hold_ary[$row['user_id']][$row['forum_id']][$row['auth_option']] = $setting;
639
	
640
					// Check for existence of ACL_YES if an option got set to ACL_NEVER
641
					if ($setting == ACL_NEVER)
642
					{
643
						$flag = substr($row['auth_option'], 0, strpos($row['auth_option'], '_') + 1);
644
	
645
						if (isset($hold_ary[$row['user_id']][$row['forum_id']][$flag]) && $hold_ary[$row['user_id']][$row['forum_id']][$flag] == ACL_YES)
646
						{
647
							unset($hold_ary[$row['user_id']][$row['forum_id']][$flag]);
648
	
649
							if (in_array(ACL_YES, $hold_ary[$row['user_id']][$row['forum_id']]))
650
							{
651
								$hold_ary[$row['user_id']][$row['forum_id']][$flag] = ACL_YES;
652
							}
653
						}
654
					}
655
				}
656
			}
657
			$db->sql_freeresult($result);
658
		}
659
660
		return $hold_ary;
661
	}
662
663
	/**
664
	* Get raw user based permission settings
665
	*/
666
	function acl_user_raw_data($user_id = false, $opts = false, $forum_id = false)
667
	{
668
		global $db;
669
670
		$sql_user = ($user_id !== false) ? ((!is_array($user_id)) ? 'user_id = ' . (int) $user_id : $db->sql_in_set('user_id', array_map('intval', $user_id))) : '';
671
		$sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? 'AND a.forum_id = ' . (int) $forum_id : 'AND ' . $db->sql_in_set('a.forum_id', array_map('intval', $forum_id))) : '';
672
673
		$sql_opts = '';
674
675
		if ($opts !== false)
676
		{
677
			$this->build_auth_option_statement('ao.auth_option', $opts, $sql_opts);
678
		}
679
680
		$hold_ary = array();
681
682
		// Grab user settings...
683
		$sql = $db->sql_build_query('SELECT', array(
684
			'SELECT'	=> 'ao.auth_option, a.auth_role_id, r.auth_setting as role_auth_setting, a.user_id, a.forum_id, a.auth_setting',
685
			
686
			'FROM'		=> array(
687
				ACL_OPTIONS_TABLE	=> 'ao',
688
				ACL_USERS_TABLE		=> 'a'
689
			),
690
			
691
			'LEFT_JOIN'	=> array(
692
				array(
693
					'FROM'	=> array(ACL_ROLES_DATA_TABLE => 'r'),
694
					'ON'	=> 'a.auth_role_id = r.role_id'
695
				),
696
			),
697
698
			'WHERE'		=> '(ao.auth_option_id = a.auth_option_id OR ao.auth_option_id = r.auth_option_id)
699
				' . (($sql_user) ? 'AND a.' . $sql_user : '') . "
700
				$sql_forum
701
				$sql_opts",
702
703
			'ORDER_BY'	=> 'a.forum_id, ao.auth_option'
704
		));
705
		$result = $db->sql_query($sql);
706
707
		while ($row = $db->sql_fetchrow($result))
708
		{
709
			$setting = ($row['auth_role_id']) ? $row['role_auth_setting'] : $row['auth_setting'];
710
			$hold_ary[$row['user_id']][$row['forum_id']][$row['auth_option']] = $setting;
711
		}
712
		$db->sql_freeresult($result);
713
714
		return $hold_ary;
715
	}
716
717
	/**
718
	* Get raw group based permission settings
719
	*/
720
	function acl_group_raw_data($group_id = false, $opts = false, $forum_id = false)
721
	{
722
		global $db;
723
724
		$sql_group = ($group_id !== false) ? ((!is_array($group_id)) ? 'group_id = ' . (int) $group_id : $db->sql_in_set('group_id', array_map('intval', $group_id))) : '';
725
		$sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? 'AND a.forum_id = ' . (int) $forum_id : 'AND ' . $db->sql_in_set('a.forum_id', array_map('intval', $forum_id))) : '';
726
727
		$sql_opts = '';
728
729
		if ($opts !== false)
730
		{
731
			$this->build_auth_option_statement('ao.auth_option', $opts, $sql_opts);
732
		}
733
734
		$hold_ary = array();
735
736
		// Grab group settings...
737
		$sql = $db->sql_build_query('SELECT', array(
738
			'SELECT'	=> 'a.group_id, ao.auth_option, a.forum_id, a.auth_setting, a.auth_role_id, r.auth_setting as role_auth_setting',
739
740
			'FROM'		=> array(
741
				ACL_OPTIONS_TABLE	=> 'ao',
742
				ACL_GROUPS_TABLE	=> 'a'
743
			),
744
745
			'LEFT_JOIN'	=> array(
746
				array(
747
					'FROM'	=> array(ACL_ROLES_DATA_TABLE => 'r'),
748
					'ON'	=> 'a.auth_role_id = r.role_id'
749
				),
750
			),
751
752
			'WHERE'		=> '(ao.auth_option_id = a.auth_option_id OR ao.auth_option_id = r.auth_option_id)
753
				' . (($sql_group) ? 'AND a.' . $sql_group : '') . "
754
				$sql_forum
755
				$sql_opts",
756
757
			'ORDER_BY'	=> 'a.forum_id, ao.auth_option'
758
		));
759
		$result = $db->sql_query($sql);
760
761
		while ($row = $db->sql_fetchrow($result))
762
		{
763
			$setting = ($row['auth_role_id']) ? $row['role_auth_setting'] : $row['auth_setting'];
764
			$hold_ary[$row['group_id']][$row['forum_id']][$row['auth_option']] = $setting;
765
		}
766
		$db->sql_freeresult($result);
767
768
		return $hold_ary;
769
	}
770
771
	/**
772
	* Authentication plug-ins is largely down to Sergey Kanareykin, our thanks to him.
773
	*/
774
	function login($username, $password, $autologin = false, $viewonline = 1, $admin = 0)
775
	{
776
		global $config, $db, $user, $phpbb_root_path, $phpEx;
777
778
		$method = trim(basename($config['auth_method']));
779
		include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
780
781
		$method = 'login_' . $method;
782
		if (function_exists($method))
783
		{
784
			$login = $method($username, $password);
785
786
			// If the auth module wants us to create an empty profile do so and then treat the status as LOGIN_SUCCESS
787
			if ($login['status'] == LOGIN_SUCCESS_CREATE_PROFILE)
788
			{
789
				// we are going to use the user_add function so include functions_user.php if it wasn't defined yet
790
				if (!function_exists('user_add'))
791
				{
792
					include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
793
				}
794
795
				user_add($login['user_row'], (isset($login['cp_data'])) ? $login['cp_data'] : false);
796
797
				$sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type
798
					FROM ' . USERS_TABLE . "
799
					WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
800
				$result = $db->sql_query($sql);
801
				$row = $db->sql_fetchrow($result);
802
				$db->sql_freeresult($result);
803
804
				if (!$row)
805
				{
806
					return array(
807
						'status'		=> LOGIN_ERROR_EXTERNAL_AUTH,
808
						'error_msg'		=> 'AUTH_NO_PROFILE_CREATED',
809
						'user_row'		=> array('user_id' => ANONYMOUS),
810
					);
811
				}
812
813
				$login = array(
814
					'status'	=> LOGIN_SUCCESS,
815
					'error_msg'	=> false,
816
					'user_row'	=> $row,
817
				);
818
			}
819
820
			// If login succeeded, we will log the user in... else we pass the login array through...
821
			if ($login['status'] == LOGIN_SUCCESS)
822
			{
823
				$old_session_id = $user->session_id;
824
825
				if ($admin)
826
				{
827
					global $SID, $_SID;
828
829
					$cookie_expire = time() - 31536000;
830
					$user->set_cookie('u', '', $cookie_expire);
831
					$user->set_cookie('sid', '', $cookie_expire);
832
					unset($cookie_expire);
833
834
					$SID = '?sid=';
835
					$user->session_id = $_SID = '';
836
				}
837
838
				$result = $user->session_create($login['user_row']['user_id'], $admin, $autologin, $viewonline);
839
840
				// Successful session creation
841
				if ($result === true)
842
				{
843
					// If admin re-authentication we remove the old session entry because a new one has been created...
844
					if ($admin)
845
					{
846
						// the login array is used because the user ids do not differ for re-authentication
847
						$sql = 'DELETE FROM ' . SESSIONS_TABLE . "
848
							WHERE session_id = '" . $db->sql_escape($old_session_id) . "'
849
							AND session_user_id = {$login['user_row']['user_id']}";
850
						$db->sql_query($sql);
851
					}
852
853
					return array(
854
						'status'		=> LOGIN_SUCCESS,
855
						'error_msg'		=> false,
856
						'user_row'		=> $login['user_row'],
857
					);
858
				}
859
860
				return array(
861
					'status'		=> LOGIN_BREAK,
862
					'error_msg'		=> $result,
863
					'user_row'		=> $login['user_row'],
864
				);
865
			}
866
867
			return $login;
868
		}
869
870
		trigger_error('Authentication method not found', E_USER_ERROR);
871
	}
872
873
	/**
874
	* Fill auth_option statement for later querying based on the supplied options
875
	*/
876
	function build_auth_option_statement($key, $auth_options, &$sql_opts)
877
	{
878
		global $db;
879
880
		if (!is_array($auth_options))
881
		{
882
			if (strpos($auth_options, '%') !== false)
883
			{
884
				$sql_opts = "AND $key " . $db->sql_like_expression(str_replace('%', $db->any_char, $auth_options));
885
			}
886
			else
887
			{
888
				$sql_opts = "AND $key = '" . $db->sql_escape($auth_options) . "'";
889
			}
890
		}
891
		else
892
		{
893
			$is_like_expression = false;
894
895
			foreach ($auth_options as $option)
896
			{
897
				if (strpos($option, '%') !== false)
898
				{
899
					$is_like_expression = true;
900
				}
901
			}
902
903
			if (!$is_like_expression)
904
			{
905
				$sql_opts = 'AND ' . $db->sql_in_set($key, $auth_options);
906
			}
907
			else
908
			{
909
				$sql = array();
910
911
				foreach ($auth_options as $option)
912
				{
913
					if (strpos($option, '%') !== false)
914
					{
915
						$sql[] = $key . ' ' . $db->sql_like_expression(str_replace('%', $db->any_char, $option));
916
					}
917
					else
918
					{
919
						$sql[] = $key . " = '" . $db->sql_escape($option) . "'";
920
					}
921
				}
922
923
				$sql_opts = 'AND (' . implode(' OR ', $sql) . ')';
924
			}
925
		}
926
	}
927
}
928
929
?>