array()); is used in config.php.
// Note 2: search is likely to not work properly with OpenLDAP as well because of Windows specific filtering code in there
// (we are looking for matches for Windows-specific samaccountname property). Search needs to be redone during the next
// refactoring effort.
/**
* Auth_ldap class to authenticate users against an LDAP server (Windows AD, OpenLDAP, and others).
* @package TimeTracker
*/
class Auth_ldap extends Auth {
  var $params;
  function __construct($params)
  {
    $this->params = $params;
    if (isset($GLOBALS['smarty'])) {
      $GLOBALS['smarty']->assign('Auth_ldap_params', $this->params);
    }
  }
  function ldap_escape($str){
    $illegal = array("(", ")", "#");
    $legal = array();
    foreach ($illegal as $id => $char) {
      $legal[$id] = "\\".$char;
    }
    $str = str_replace($illegal, $legal,$str); //replace them
    return $str;
  }
  /**
   * Authenticate user against LDAP server.
   *
   * @param string $login
   * @param string $password
   * @return mixed
   */
  function authenticate($login, $password)
  {
    // Special handling for admin@localhost - authenticate against db, not ldap.
    // It is a fallback mechanism when admin account in LDAP directory does not exist or is misconfigured.
    if ($login == 'admin@localhost') {
        import('auth.Auth_db');
        return Auth_db::authenticate($login, $password);
    }
    if (!function_exists('ldap_bind')) {
      die ('php_ldap extension not loaded!');
    }
    if (empty($this->params['server']) || empty($this->params['base_dn'])) {
      die('You must set server and base_dn in AUTH_MODULE_PARAMS in config.php');
    }
    $member_of = @$this->params['member_of'];
    $lc = ldap_connect($this->params['server']);
    if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
      echo '
';
      echo '$lc='; var_dump($lc); echo '
';
      echo 'ldap_error()='; echo ldap_error($lc); echo '
';
    }
    if (!$lc) return false;
    ldap_set_option($lc, LDAP_OPT_PROTOCOL_VERSION, 3);
    ldap_set_option($lc, LDAP_OPT_REFERRALS, 0);
    if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
      ldap_set_option($lc, LDAP_OPT_DEBUG_LEVEL, 7);
    }
    // We need to handle Windows AD and OpenLDAP differently.
    if ($this->params['type'] != 'openldap') {
      // check if the user specified full login
      if (strpos($login, '@') === false) {
        // append default domain
        $login .= '@' . $this->params['default_domain'];
      }
      if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
        echo '$login='; var_dump($login); echo '
';
      }
      $lb = @ldap_bind($lc, $login, $password);
      if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
        echo '$lb='; var_dump($lb); echo '
';
        echo 'ldap_error()='; echo ldap_error($lc); echo '
';
      }
      if (!$lb) {
        ldap_unbind($lc);
        return false;
      }
      if ($member_of) {
        // get groups
        $filter = 'samaccountname='.Auth_ldap::ldap_escape($login);
        $fields = array('samaccountname', 'mail', 'memberof', 'department', 'displayname', 'telephonenumber', 'primarygroupid');
        $sr = @ldap_search($lc, $this->params['base_dn'], $filter, $fields);
        if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
          echo '$sr='; var_dump($sr); echo '
';
          echo 'ldap_error()='; echo ldap_error($lc); echo '
';
        }
        // if search failed it's likely that account is disabled
        if (!$sr) {
          ldap_unbind($lc);
          return false;
        }
        $entries = @ldap_get_entries($lc, $sr);
        if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
          echo '$entries='; var_dump($entries); echo '
';
          echo 'ldap_error()='; echo ldap_error($lc); echo '
';
        }
        if ($entries === false) {
          ldap_unbind($lc);
          return false;
        }
        $groups = array();
        // extract group names from
        // assuming the groups are in format: CN=,...
        for ($i = 0; $i < @$entries[0]['memberof']['count']; $i++) {
          $grp = $entries[0]['memberof'][$i];
          $grp_fields = explode(',', $grp);
          $groups[] = substr($grp_fields[0], 3);
        }
        if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
          echo '$member_of'; var_dump($member_of); echo '
';
        };
        // check for group membership
            foreach ($member_of as $check_grp) {
          if (!in_array($check_grp, $groups)) {
            ldap_unbind($lc);
            return false;
          }
        }
      }
      ldap_unbind($lc);
      return array('login' => $login, 'data' => $entries, 'member_of' => $groups);
    } else {
      // Assuming OpenLDAP server.
      $login_oldap = 'uid='.$login.','.$this->params['base_dn'];
      if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
        echo '$login_oldap='; var_dump($login_oldap); echo '
';
      }
      // check if the user specified full login
      if (strpos($login, '@') === false) {
        // append default domain
        $login .= '@' . $this->params['default_domain'];
      }
      $lb = @ldap_bind($lc, $login_oldap, $password);
      if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
        echo '$lb='; var_dump($lb); echo '
';
        echo 'ldap_error()='; echo ldap_error($lc); echo '
';
      }
      if (!$lb) {
        ldap_unbind($lc);
        return false;
      }
      if ($member_of) {
        // get groups
        $filter = 'samaccountname='.Auth_ldap::ldap_escape($login_oldap);
        $fields = array('samaccountname', 'mail', 'memberof', 'department', 'displayname', 'telephonenumber', 'primarygroupid');
        $sr = @ldap_search($lc, $this->params['base_dn'], $filter, $fields);
        if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
          echo '$sr='; var_dump($sr); echo '
';
          echo 'ldap_error()='; echo ldap_error($lc); echo '
';
        }
        // if search failed it's likely that account is disabled
        if (!$sr) {
          ldap_unbind($lc);
          return false;
        }
        $entries = @ldap_get_entries($lc, $sr);
        if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
          echo '$entries='; var_dump($entries); echo '
';
          echo 'ldap_error()='; echo ldap_error($lc); echo '
';
        }
        if ($entries === false) {
          ldap_unbind($lc);
          return false;
        }
        $groups = array();
        // extract group names from
        // assuming the groups are in format: CN=,...
        for ($i = 0; $i < @$entries[0]['memberof']['count']; $i++) {
          $grp = $entries[0]['memberof'][$i];
          $grp_fields = explode(',', $grp);
          $groups[] = substr($grp_fields[0], 3);
        }
        if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) {
          echo '$member_of'; var_dump($member_of); echo '
';
        };
        // check for group membership
        foreach ($member_of as $check_grp) {
          if (!in_array($check_grp, $groups)) {
            ldap_unbind($lc);
            return false;
          }
        }
      }
      ldap_unbind($lc);
      return array('login' => $login, 'data' => $entries, 'member_of' => $groups);
    }
  }
  function isPasswordExternal() {
    return true;
  }
}