Back to index

d-push  2.0
searchldap.php
Go to the documentation of this file.
00001 <?php
00002 /***********************************************
00003 * File      :   searchLDAP.php
00004 * Project   :   Z-Push
00005 * Descr     :   A ISearchProvider implementation to
00006 *               query a ldap server for GAL
00007 *               information.
00008 *
00009 * Created   :   03.08.2010
00010 *
00011 * Copyright 2007 - 2011 Zarafa Deutschland GmbH
00012 *
00013 * This program is free software: you can redistribute it and/or modify
00014 * it under the terms of the GNU Affero General Public License, version 3,
00015 * as published by the Free Software Foundation with the following additional
00016 * term according to sec. 7:
00017 *
00018 * According to sec. 7 of the GNU Affero General Public License, version 3,
00019 * the terms of the AGPL are supplemented with the following terms:
00020 *
00021 * "Zarafa" is a registered trademark of Zarafa B.V.
00022 * "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
00023 * The licensing of the Program under the AGPL does not imply a trademark license.
00024 * Therefore any rights, title and interest in our trademarks remain entirely with us.
00025 *
00026 * However, if you propagate an unmodified version of the Program you are
00027 * allowed to use the term "Z-Push" to indicate that you distribute the Program.
00028 * Furthermore you may use our trademarks where it is necessary to indicate
00029 * the intended purpose of a product or service provided you use it in accordance
00030 * with honest practices in industrial or commercial matters.
00031 * If you want to propagate modified versions of the Program under the name "Z-Push",
00032 * you may only do so if you have a written permission by Zarafa Deutschland GmbH
00033 * (to acquire a permission please contact Zarafa at trademark@zarafa.com).
00034 *
00035 * This program is distributed in the hope that it will be useful,
00036 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00037 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00038 * GNU Affero General Public License for more details.
00039 *
00040 * You should have received a copy of the GNU Affero General Public License
00041 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00042 *
00043 * Consult LICENSE file for details
00044 ************************************************/
00045 
00046 require_once("backend/searchldap/config.php");
00047 
00048 class BackendSearchLDAP implements ISearchProvider {
00049     private $connection;
00050 
00060     public function BackendSearchLDAP() {
00061         if (!function_exists("ldap_connect"))
00062             throw new StatusException("BackendSearchLDAP(): php-ldap is not installed. Search aborted.", SYNC_SEARCHSTATUS_STORE_SERVERERROR, null, LOGLEVEL_FATAL);
00063 
00064         // connect to LDAP
00065         $this->connection = @ldap_connect(LDAP_HOST, LDAP_PORT);
00066         @ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, 3);
00067 
00068         // Authenticate
00069         if (constant('ANONYMOUS_BIND') === true) {
00070             if(! @ldap_bind($this->connection)) {
00071                 $this->connection = false;
00072                 throw new StatusException("BackendSearchLDAP(): Could not bind anonymously to server! Search aborted.", SYNC_SEARCHSTATUS_STORE_CONNECTIONFAILED, null, LOGLEVEL_ERROR);
00073             }
00074         }
00075         else if (constant('LDAP_BIND_USER') != "") {
00076             if(! @ldap_bind($this->connection, LDAP_BIND_USER, LDAP_BIND_PASSWORD)) {
00077                 $this->connection = false;
00078                 throw new StatusException(sprintf("BackendSearchLDAP(): Could not bind to server with user '%s' and specified password! Search aborted.", LDAP_BIND_USER), SYNC_SEARCHSTATUS_STORE_ACCESSDENIED, null, LOGLEVEL_ERROR);
00079             }
00080         }
00081         else {
00082             // it would be possible to use the users login and password to authenticate on the LDAP server
00083             // the main $backend has to keep these values so they could be used here
00084             $this->connection = false;
00085             throw new StatusException("BackendSearchLDAP(): neither anonymous nor default bind enabled. Other options not implemented.", SYNC_SEARCHSTATUS_STORE_CONNECTIONFAILED, null, LOGLEVEL_ERROR);
00086         }
00087     }
00088 
00098     public function SupportsType($searchtype) {
00099         return ($searchtype == ISearchProvider::SEARCH_GAL);
00100     }
00101 
00102 
00112     public function GetGALSearchResults($searchquery, $searchrange) {
00113         global $ldap_field_map;
00114         if (isset($this->connection) && $this->connection !== false) {
00115             $searchfilter = str_replace("SEARCHVALUE", $searchquery, LDAP_SEARCH_FILTER);
00116             $result = @ldap_search($this->connection, LDAP_SEARCH_BASE, $searchfilter);
00117             if (!$result) {
00118                 ZLog::Write(LOGLEVEL_ERROR, "BackendSearchLDAP: Error in search query. Search aborted");
00119                 return false;
00120             }
00121 
00122             // get entry data as array
00123             $searchresult = ldap_get_entries($this->connection, $result);
00124 
00125             // range for the search results, default symbian range end is 50, wm 99,
00126             // so we'll use that of nokia
00127             $rangestart = 0;
00128             $rangeend = 50;
00129 
00130             if ($searchrange != '0') {
00131                 $pos = strpos($searchrange, '-');
00132                 $rangestart = substr($searchrange, 0, $pos);
00133                 $rangeend = substr($searchrange, ($pos + 1));
00134             }
00135             $items = array();
00136 
00137             // TODO the limiting of the searchresults could be refactored into Utils as it's probably used more than once
00138             $querycnt = $searchresult['count'];
00139             //do not return more results as requested in range
00140             $querylimit = (($rangeend + 1) < $querycnt) ? ($rangeend + 1) : $querycnt;
00141             $items['range'] = $rangestart.'-'.($querycnt-1);
00142             $items['searchtotal'] = $querycnt;
00143 
00144             $rc = 0;
00145             for ($i = $rangestart; $i < $querylimit; $i++) {
00146                 foreach ($ldap_field_map as $key=>$value ) {
00147                     if (isset($searchresult[$i][$value])) {
00148                         if (is_array($searchresult[$i][$value]))
00149                             $items[$rc][$key] = $searchresult[$i][$value][0];
00150                         else
00151                             $items[$rc][$key] = $searchresult[$i][$value];
00152                     }
00153                 }
00154                 $rc++;
00155             }
00156 
00157             return $items;
00158         }
00159         else
00160             return false;
00161     }
00162 
00170     public function GetMailboxSearchResults($cpo) {
00171         return array();
00172     }
00173 
00181     public function TerminateSearch($pid) {
00182         return true;
00183     }
00184 
00191     public function Disconnect() {
00192         if ($this->connection)
00193             @ldap_close($this->connection);
00194 
00195         return true;
00196     }
00197 }
00198 ?>