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  ?>