Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

auth.php

Zuletzt modifiziert: 09.10.2024, 12:50 - Dateigröße: 23.67 KiB


001  <?php
002  /**
003  *
004  * @package phpBB3
005  * @version $Id$
006  * @copyright (c) 2005 phpBB Group
007  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
008  *
009  */
010   
011  /**
012  * @ignore
013  */
014  if (!defined('IN_PHPBB'))
015  {
016      exit;
017  }
018   
019  /**
020  * Permission/Auth class
021  * @package phpBB3
022  */
023  class auth
024  {
025      var $acl = array();
026      var $cache = array();
027      var $acl_options = array();
028      var $acl_forum_ids = false;
029   
030      /**
031      * Init permissions
032      */
033      function acl(&$userdata)
034      {
035          global $db, $cache;
036   
037          $this->acl = $this->cache = $this->acl_options = array();
038          $this->acl_forum_ids = false;
039   
040          if (($this->acl_options = $cache->get('_acl_options')) === false)
041          {
042              $sql = 'SELECT auth_option, is_global, is_local
043                  FROM ' . ACL_OPTIONS_TABLE . '
044                  ORDER BY auth_option_id';
045              $result = $db->sql_query($sql);
046   
047              $global = $local = 0;
048              $this->acl_options = array();
049              while ($row = $db->sql_fetchrow($result))
050              {
051                  if ($row['is_global'])
052                  {
053                      $this->acl_options['global'][$row['auth_option']] = $global++;
054                  }
055   
056                  if ($row['is_local'])
057                  {
058                      $this->acl_options['local'][$row['auth_option']] = $local++;
059                  }
060              }
061              $db->sql_freeresult($result);
062   
063              $cache->put('_acl_options', $this->acl_options);
064              $this->acl_cache($userdata);
065          }
066          else if (!trim($userdata['user_permissions']))
067          {
068              $this->acl_cache($userdata);
069          }
070   
071          $user_permissions = explode("\n", $userdata['user_permissions']);
072   
073          foreach ($user_permissions as $f => $seq)
074          {
075              if ($seq)
076              {
077                  $i = 0;
078   
079                  if (!isset($this->acl[$f]))
080                  {
081                      $this->acl[$f] = '';
082                  }
083   
084                  while ($subseq = substr($seq, $i, 6))
085                  {
086                      // We put the original bitstring into the acl array
087                      $this->acl[$f] .= str_pad(base_convert($subseq, 36, 2), 31, 0, STR_PAD_LEFT);
088                      $i += 6;
089                  }
090              }
091          }
092   
093          return;
094      }
095   
096      /**
097      * Look up an option
098      * if the option is prefixed with !, then the result becomes negated
099      *
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  ?>