class_ldap.inc 46.63 KiB
<?php
/*
  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
  Copyright (C) 2003-2010  Cajus Pollmeier
  Copyright (C) 2003 Alejandro Escanero Blanco <aescanero@chaosdimension.org>
  Copyright (C) 1998  Eric Kilfoil <eric@ipass.net>
  Copyright (C) 2011-2016  FusionDirectory
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
/*!
 * \file class_ldap.inc
 * Source code for Class LDAP
/*!
 * \brief This class contains all ldap function needed to make
 * ldap operations easy
class LDAP
  var $hascon         = FALSE;
  var $reconnect      = FALSE;
  var $tls            = FALSE;
  /**
   * Connection identifier
   * @var resource|object|false
  var $cid            = FALSE;
  var $hasres         = [];
  var $sr             = [];
  var $re             = [];
  var $basedn         = "";
  /* 0 if we are fetching the first entry, otherwise 1 */
  var $start          = [];
  /* Any error messages to be returned can be put here */
  var $error          = "";
  var $srp            = 0;
  /* Information read from slapd.oc.conf */
  var $objectClasses    = [];
  /* the dn for the bind */
  var $binddn           = "";
  /* the dn's password for the bind */
  var $bindpw           = "";
  var $hostname         = "";
  var $follow_referral  = FALSE;
  var $referrals        = [];
  /* 0, empty or negative values will disable this check */
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
var $max_ldap_query_time = 0; /*! * \brief Create a LDAP connection * * \param string $binddn Bind of the DN * * \param string $bindpw Bind * * \param string $hostname The hostname * * \param boolean $follow_referral FALSE * * \param boolean $tls FALSE */ function __construct ($binddn, $bindpw, $hostname, $follow_referral = FALSE, $tls = FALSE) { global $config; $this->follow_referral = $follow_referral; $this->tls = $tls; $this->binddn = $binddn; $this->bindpw = $bindpw; $this->hostname = $hostname; /* Check if MAX_LDAP_QUERY_TIME is defined */ if (is_object($config) && ($config->get_cfg_value("ldapMaxQueryTime") != "")) { $str = $config->get_cfg_value("ldapMaxQueryTime"); $this->max_ldap_query_time = (float)($str); } $this->connect(); } /*! \brief Remove bogus resources after unserialize */ public function __wakeup () { $this->cid = FALSE; $this->hascon = FALSE; } /*! * \brief Initialize a LDAP connection * * Initializes a LDAP connection. * * \param string $server The server we are connecting to * * \param string $base The base of our ldap tree * * \param string $binddn Default: empty * * \param string $pass Default: empty * * \return LDAP object */ public static function init (string $server, string $base, string $binddn = '', string $pass = ''): LDAP { global $config; $ldap = new LDAP($binddn, $pass, $server, isset($config->current['LDAPFOLLOWREFERRALS']) && $config->current['LDAPFOLLOWREFERRALS'] == 'TRUE', isset($config->current['LDAPTLS']) && $config->current['LDAPTLS'] == 'TRUE'); /* Sadly we've no proper return values here. Use the error message instead. */ if (!$ldap->success()) { throw new FatalError(htmlescape(sprintf(_('FATAL: Error when connecting to LDAP. Server said "%s".'), $ldap->get_error()))); } /* Preset connection base to $base and return to caller */
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
$ldap->cd($base); return $ldap; } /*! * \brief Get the search ressource * * \return increase srp */ function getSearchResource () { $this->sr[$this->srp] = NULL; $this->start[$this->srp] = 0; $this->hasres[$this->srp] = FALSE; return $this->srp++; } /*! * \brief Function to fix problematic characters in DN's that are used for search requests. I.e. member=.... * * \param string $dn The DN */ static function prepare4filter ($dn) { trigger_error('deprecated, use ldap_escape_f instead'); return ldap_escape_f($dn); } /*! * \brief Error text that must be returned for invalid user or password * * This is useful to make sure the same error text is shown whether a user exists or not, when the password is not correct. */ static function invalidCredentialsError (): string { return _(ldap_err2str(49)); } /*! * \brief Create a connection to LDAP server * * The string $error containts result of the connection */ function connect () { $this->hascon = FALSE; $this->reconnect = FALSE; if ($this->cid = @ldap_connect($this->hostname)) { @ldap_set_option($this->cid, LDAP_OPT_PROTOCOL_VERSION, 3); if ($this->follow_referral) { @ldap_set_option($this->cid, LDAP_OPT_REFERRALS, 1); @ldap_set_rebind_proc($this->cid, [&$this, 'rebind']); } if ($this->tls) { @ldap_start_tls($this->cid); } $this->error = 'No Error'; $serverctrls = []; if (class_available('ppolicyAccount')) { $serverctrls = [['oid' => LDAP_CONTROL_PASSWORDPOLICYREQUEST]]; } $result = @ldap_bind_ext($this->cid, $this->binddn, $this->bindpw, $serverctrls); if (@ldap_parse_result($this->cid, $result, $errcode, $matcheddn, $errmsg, $referrals, $ctrls)) { if (isset($ctrls[LDAP_CONTROL_PASSWORDPOLICYRESPONSE]['value']['error'])) { $this->hascon = FALSE; $this->error = match ($ctrls[LDAP_CONTROL_PASSWORDPOLICYRESPONSE]['value']['error']) { /* passwordExpired - password has expired and must be reset */ 0 => _('It seems your user password has expired. Please use <a href="recovery.php">password recovery</a> to change it.'), /* accountLocked */