class_ldap.inc 36.73 KiB
<?php
/*
  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
  Copyright (C) 1998  Eric Kilfoil
  Copyright (C) 2003 Alejandro Escanero Blanco
  Copyright (C) 2003-2010  Cajus Pollmeier
  Copyright (C) 2011-2018  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 $cid;
  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 */
  var $max_ldap_query_time  = 0;
  /*!
   * \brief Create a LDAP connection
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
* * \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 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 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 (function_exists("ldap_set_rebind_proc") && $this->follow_referral) { @ldap_set_option($this->cid, LDAP_OPT_REFERRALS, 1); @ldap_set_rebind_proc($this->cid, [&$this, "rebind"]); } if (function_exists("ldap_start_tls") && $this->tls) { @ldap_start_tls($this->cid);
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
} $this->error = "No Error"; if (@ldap_bind($this->cid, $this->binddn, $this->bindpw)) { $this->error = "Success"; $this->hascon = TRUE; } else { if ($this->reconnect) { if ($this->error != "Success") { $this->error = "Could not rebind to " . $this->binddn; } } else { $this->error = "Could not bind to " . $this->binddn; } } } else { $this->error = "Could not connect to LDAP server"; } } /*! * \brief Rebind */ function rebind ($ldap, $referral) { $credentials = $this->get_credentials($referral); if (@ldap_bind($ldap, $credentials['ADMINDN'], $credentials['ADMINPASSWORD'])) { $this->error = "Success"; $this->hascon = TRUE; $this->reconnect = TRUE; return 0; } else { $this->error = "Could not bind to " . $credentials['ADMINDN']; return NULL; } } /*! * \brief Reconnect to LDAP server */ function reconnect () { if ($this->reconnect) { $this->unbind(); } } /*! * \brief Unbind to LDAP server */ function unbind () { @ldap_unbind($this->cid); $this->cid = NULL; } /*! * \brief Disconnect to LDAP server */ function disconnect () { if ($this->hascon) { @ldap_close($this->cid); $this->hascon = FALSE; } } /*! * \brief Change directory *
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
* \param string $dir The new directory */ function cd ($dir) { if ($dir == '..') { $this->basedn = $this->getParentDir(); } else { $this->basedn = $dir; } } /*! * \brief Accessor of the parent directory of the basedn * * \param string $basedn The basedn which we want the parent directory * * \return String, the parent directory */ function getParentDir ($basedn = '') { if ($basedn == '') { $basedn = $this->basedn; } return preg_replace("/[^,]*[,]*[ ]*(.*)/", "$1", $basedn); } /*! * \brief Search about filter * * \param integer $srp srp * * \param string $filter The filter * * \param array $attrs * * \param string $scope Scope of the search: subtree/base/one */ function search ($srp, $filter, $attrs = [], $scope = 'subtree') { if ($this->hascon) { if ($this->reconnect) { $this->connect(); } $start = microtime(TRUE); $this->clearResult($srp); switch (strtolower($scope)) { case 'base': $this->sr[$srp] = @ldap_read($this->cid, $this->basedn, $filter, $attrs); break; case 'one': $this->sr[$srp] = @ldap_list($this->cid, $this->basedn, $filter, $attrs); break; default: case 'subtree': $this->sr[$srp] = @ldap_search($this->cid, $this->basedn, $filter, $attrs); break; } $this->error = @ldap_error($this->cid); $this->resetResult($srp); $this->hasres[$srp] = TRUE; /* Check if query took longer as specified in max_ldap_query_time */ if ($this->max_ldap_query_time) { $diff = microtime(TRUE) - $start; if ($diff > $this->max_ldap_query_time) { msg_dialog::display(_("Performance warning"), sprintf(_("LDAP performance is poor: last query took about %.2fs!"), $diff), WARNING_DIALOG); } }
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
$this->log("LDAP operation: time=".(microtime(TRUE) - $start)." operation=search('".$this->basedn."', '$filter')"); return $this->sr[$srp]; } else { $this->error = "Could not connect to LDAP server"; return ""; } } /* * \brief List * * \param integer $srp * * \param string $filter Initialized at "(objectclass=*)" * * \param string $basedn Empty string * * \param array $attrs */ function ls ($srp, $filter = "(objectclass=*)", $basedn = "", $attrs = ["*"]) { trigger_error('deprecated'); $this->cd($basedn); return $this->search($srp, $filter, $attrs, 'one'); } /* * \brief Concatenate * * \param integer $srp * * \param string $dn The DN * * \param array $attrs * * \param string $filter Initialized at "(objectclass=*)" */ function cat ($srp, $dn, $attrs = ["*"], $filter = "(objectclass=*)") { if ($this->hascon) { if ($this->reconnect) { $this->connect(); } $this->clearResult($srp); $this->sr[$srp] = @ldap_read($this->cid, $dn, $filter, $attrs); $this->error = @ldap_error($this->cid); $this->resetResult($srp); $this->hasres[$srp] = TRUE; return $this->sr[$srp]; } else { $this->error = "Could not connect to LDAP server"; return ""; } } /*! * \brief Search object from a filter * * \param string $dn The DN * * \param string $filter The filter of the research */ function object_match_filter ($dn, $filter) { if ($this->hascon) { if ($this->reconnect) { $this->connect(); } $res = @ldap_read($this->cid, $dn, $filter, ["objectClass"]);
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
$rv = @ldap_count_entries($this->cid, $res); return $rv; } else { $this->error = "Could not connect to LDAP server"; return FALSE; } } /*! * \brief Set a size limit * * \param $size The limit */ function set_size_limit ($size) { /* Ignore zero settings */ if ($size == 0) { @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, 10000000); } if ($this->hascon) { @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, $size); } else { $this->error = "Could not connect to LDAP server"; } } /*! * \brief Fetch * * \param integer $srp */ function fetch ($srp) { $att = []; if ($this->hascon) { if ($this->hasres[$srp]) { if ($this->start[$srp] == 0) { if ($this->sr[$srp]) { $this->start[$srp] = 1; $this->re[$srp] = @ldap_first_entry($this->cid, $this->sr[$srp]); } else { return []; } } else { $this->re[$srp] = @ldap_next_entry($this->cid, $this->re[$srp]); } if ($this->re[$srp]) { $att = @ldap_get_attributes($this->cid, $this->re[$srp]); $att['dn'] = trim(@ldap_get_dn($this->cid, $this->re[$srp])); } $this->error = @ldap_error($this->cid); if (!isset($att)) { $att = []; } return $att; } else { $this->error = "Perform a fetch with no search"; return ""; } } else { $this->error = "Could not connect to LDAP server"; return ""; } } /*! * \brief Reset the result * * \param integer $srp Value to be reset */
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
function resetResult ($srp) { $this->start[$srp] = 0; } /*! * \brief Clear a result * * \param integer $srp The result to clear */ function clearResult ($srp) { if ($this->hasres[$srp]) { $this->hasres[$srp] = FALSE; @ldap_free_result($this->sr[$srp]); } } /*! * \brief Accessor of the DN * * \param $srp srp */ function getDN ($srp) { if ($this->hascon) { if ($this->hasres[$srp]) { if (!$this->re[$srp]) { $this->error = "Perform a Fetch with no valid Result"; } else { $rv = @ldap_get_dn($this->cid, $this->re[$srp]); $this->error = @ldap_error($this->cid); return trim($rv); } } else { $this->error = "Perform a Fetch with no Search"; return ""; } } else { $this->error = "Could not connect to LDAP server"; return ""; } } /*! * \brief Return the numbers of entries * * \param $srp srp */ function count ($srp) { if ($this->hascon) { if ($this->hasres[$srp]) { $rv = @ldap_count_entries($this->cid, $this->sr[$srp]); $this->error = @ldap_error($this->cid); return $rv; } else { $this->error = "Perform a Fetch with no Search"; return ""; } } else { $this->error = "Could not connect to LDAP server"; return ""; } } /*! * \brief Remove
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
* * \param string $attrs Empty string * * \param string $dn Empty string */ function rm ($attrs = "", $dn = "") { if ($this->hascon) { if ($this->reconnect) { $this->connect(); } if ($dn == '') { $dn = $this->basedn; } $r = ldap_mod_del($this->cid, $dn, $attrs); $this->error = @ldap_error($this->cid); return $r; } else { $this->error = 'Could not connect to LDAP server'; return ''; } } function mod_add ($attrs = "", $dn = "") { if ($this->hascon) { if ($this->reconnect) { $this->connect(); } if ($dn == "") { $dn = $this->basedn; } $r = @ldap_mod_add($this->cid, $dn, $attrs); $this->error = @ldap_error($this->cid); return $r; } else { $this->error = "Could not connect to LDAP server"; return ""; } } /*! * \brief Remove directory * * \param string $deletedn The DN to be deleted */ function rmdir ($deletedn) { if ($this->hascon) { if ($this->reconnect) { $this->connect(); } $r = @ldap_delete($this->cid, $deletedn); $this->error = @ldap_error($this->cid); return ($r ? $r : 0); } else { $this->error = "Could not connect to LDAP server"; return ""; } } /*! * \brief Move the given Ldap entry from $source to $dest * * \param String $source The source dn. * * \param String $dest The destination dn.