From 6a8c4fc73b5b2f5100d24a7a8b8273ffc6baca9c Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Thu, 02 Jul 2015 03:09:24 -0400 Subject: [PATCH] Fix issue when first search() argument is not an array --- program/lib/Roundcube/rcube_ldap.php | 117 ++++++++++++++++++++++++++++++---------------------------- 1 files changed, 61 insertions(+), 56 deletions(-) diff --git a/program/lib/Roundcube/rcube_ldap.php b/program/lib/Roundcube/rcube_ldap.php index 981f2e8..9e724cd 100644 --- a/program/lib/Roundcube/rcube_ldap.php +++ b/program/lib/Roundcube/rcube_ldap.php @@ -1,6 +1,6 @@ <?php -/* +/** +-----------------------------------------------------------------------+ | This file is part of the Roundcube Webmail client | | Copyright (C) 2006-2013, The Roundcube Dev Team | @@ -117,13 +117,14 @@ // fieldmap property is given if (is_array($p['fieldmap'])) { + $p['fieldmap'] = array_filter($p['fieldmap']); foreach ($p['fieldmap'] as $rf => $lf) $this->fieldmap[$rf] = $this->_attr_name(strtolower($lf)); } else if (!empty($p)) { // read deprecated *_field properties to remain backwards compatible foreach ($p as $prop => $value) - if (preg_match('/^(.+)_field$/', $prop, $matches)) + if (!empty($value) && preg_match('/^(.+)_field$/', $prop, $matches)) $this->fieldmap[$matches[1]] = $this->_attr_name(strtolower($value)); } @@ -238,10 +239,9 @@ $this->_connect(); } - /** - * Establish a connection to the LDAP server - */ + * Establish a connection to the LDAP server + */ private function _connect() { $rcube = rcube::get_instance(); @@ -282,12 +282,21 @@ } // Get the pieces needed for variable replacement. - if ($fu = $rcube->get_user_email()) + if ($fu = $rcube->get_user_email()) { list($u, $d) = explode('@', $fu); - else + } + else { $d = $this->mail_domain; + } $dc = 'dc='.strtr($d, array('.' => ',dc=')); // hierarchal domain string + + // resolve $dc through LDAP + if (!empty($this->prop['domain_filter']) && !empty($this->prop['search_bind_dn']) && + method_exists($this->ldap, 'domain_root_dn')) { + $this->ldap->bind($this->prop['search_bind_dn'], $this->prop['search_bind_pw']); + $dc = $this->ldap->domain_root_dn($d); + } $replaces = array('%dn' => '', '%dc' => $dc, '%d' => $d, '%fu' => $fu, '%u' => $u); @@ -429,7 +438,6 @@ return $this->ready; } - /** * Close connection to LDAP server */ @@ -440,7 +448,6 @@ } } - /** * Returns address book name * @@ -450,7 +457,6 @@ { return $this->prop['name']; } - /** * Set internal list page @@ -474,7 +480,6 @@ $this->ldap->set_vlv_page($this->list_page, $this->page_size); } - /** * Set internal sort settings * @@ -487,7 +492,6 @@ $this->sort_col = $this->coltypes[$sort_col]['attributes'][0]; } - /** * Save a search string for future listings * @@ -497,7 +501,6 @@ { $this->filter = $filter; } - /** * Getter for saved search properties @@ -509,7 +512,6 @@ return $this->filter; } - /** * Reset all saved results and search parameters */ @@ -520,14 +522,13 @@ $this->filter = ''; } - /** * List the current set of contact records * - * @param array List of cols to show - * @param int Only return this number of records + * @param array List of cols to show + * @param int Only return this number of records * - * @return array Indexed list of contact records, each a hash array + * @return array Indexed list of contact records, each a hash array */ function list_records($cols=null, $subset=0) { @@ -697,8 +698,9 @@ for ($i=0; $i < $entry['memberurl']['count']; $i++) { // extract components from url - if (!preg_match('!ldap:///([^\?]+)\?\?(\w+)\?(.*)$!', $entry['memberurl'][$i], $m)) + if (!preg_match('!ldap://[^/]*/([^\?]+)\?\?(\w+)\?(.*)$!', $entry['memberurl'][$i], $m)) { continue; + } // add search filter if any $filter = $this->filter ? '(&(' . $m[3] . ')(' . $this->filter . '))' : $m[3]; @@ -724,7 +726,6 @@ { return strcmp($a[$this->sort_col][0], $b[$this->sort_col][0]); } - /** * Search contacts @@ -790,33 +791,24 @@ return $this->result; } - // use AND operator for advanced searches - $filter = is_array($value) ? '(&' : '(|'; - // set wildcards - $wp = $ws = ''; - if (!empty($this->prop['fuzzy_search']) && $mode != 1) { - $ws = '*'; - if (!$mode) { - $wp = '*'; - } - } + // advanced per-attribute search + if (is_array($value)) { + // use AND operator for advanced searches + $filter = '(&'; - if ($fields == '*') { - // search_fields are required for fulltext search - if (empty($this->prop['search_fields'])) { - $this->set_error(self::ERROR_SEARCH, 'nofulltextsearch'); - $this->result = new rcube_result_set(); - return $this->result; - } - if (is_array($this->prop['search_fields'])) { - foreach ($this->prop['search_fields'] as $field) { - $filter .= "($field=$wp" . rcube_ldap_generic::quote_string($value) . "$ws)"; + // set wildcards + $wp = $ws = ''; + if (!empty($this->prop['fuzzy_search']) && $mode != 1) { + $ws = '*'; + if (!$mode) { + $wp = '*'; } } - } - else { + foreach ((array)$fields as $idx => $field) { - $val = is_array($value) ? $value[$idx] : $value; + $val = $value[$idx]; + if (!strlen($val)) + continue; if ($attrs = $this->_map_field($field)) { if (count($attrs) > 1) $filter .= '(|'; @@ -826,8 +818,33 @@ $filter .= ')'; } } + + $filter .= ')'; } - $filter .= ')'; + else { + if ($fields == '*') { + // search_fields are required for fulltext search + if (empty($this->prop['search_fields'])) { + $this->set_error(self::ERROR_SEARCH, 'nofulltextsearch'); + $this->result = new rcube_result_set(); + return $this->result; + } + $attributes = (array)$this->prop['search_fields']; + } + else { + // map address book fields into ldap attributes + $me = $this; + $attributes = array(); + array_walk((array) $fields, function($field) use ($me, &$attributes) { + if ($me->coltypes[$field] && ($attrs = (array)$me->coltypes[$field]['attributes'])) { + $attributes = array_merge($attributes, $attrs); + } + }); + } + + // compose a full-text-like search filter + $filter = rcube_ldap_generic::fulltext_search_filter($value, $attributes, $mode); + } // add required (non empty) fields filter $req_filter = ''; @@ -865,7 +882,6 @@ return $this->result; } - /** * Count number of available contacts in database * @@ -893,7 +909,6 @@ return new rcube_result_set($count, ($this->list_page-1) * $this->page_size); } - /** * Return the last result set @@ -962,7 +977,6 @@ return $err; } - /** * Check the given data before saving. @@ -1035,7 +1049,6 @@ return true; } - /** * Create a new contact record * @@ -1104,7 +1117,6 @@ return $dn; } - /** * Update a specific contact record @@ -1287,7 +1299,6 @@ return $newdn ? $newdn : true; } - /** * Mark one or more contact records as deleted * @@ -1336,7 +1347,6 @@ return count($ids); } - /** * Remove all contact records @@ -1406,7 +1416,6 @@ } } - /** * Converts LDAP entry into an array */ @@ -1465,7 +1474,6 @@ return $out; } - /** * Return LDAP attribute(s) for the given field */ @@ -1473,7 +1481,6 @@ { return (array)$this->coltypes[$field]['attributes']; } - /** * Convert a record data set into LDAP field attributes @@ -2016,7 +2023,6 @@ return $default; } - /** * HTML-safe DN string encoding * @@ -2043,5 +2049,4 @@ $str = str_pad(strtr($str, '-_', '+/'), strlen($str) % 4, '=', STR_PAD_RIGHT); return base64_decode($str); } - } -- Gitblit v1.9.1