From 947c4dc30b415b683dcd107227a0544b8c9ab6aa Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Thu, 02 Jul 2015 04:09:32 -0400 Subject: [PATCH] Fix issue when first search() argument is not an array --- program/lib/Roundcube/rcube_ldap.php | 112 +++++++++++++++++++++++++++++++++----------------------- 1 files changed, 66 insertions(+), 46 deletions(-) diff --git a/program/lib/Roundcube/rcube_ldap.php b/program/lib/Roundcube/rcube_ldap.php index 274616a..60f58ec 100644 --- a/program/lib/Roundcube/rcube_ldap.php +++ b/program/lib/Roundcube/rcube_ldap.php @@ -64,7 +64,6 @@ private $base_dn = ''; private $groups_base_dn = ''; - private $group_url; private $group_data; private $group_search_cache; private $cache; @@ -118,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)); } @@ -698,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]; @@ -766,16 +767,16 @@ if ($this->prop['vlv_search'] && $this->ready && join(',', (array)$fields) == join(',', $list_fields)) { $this->result = new rcube_result_set(0); - $search_suffix = $this->prop['fuzzy_search'] && $mode != 1 ? '*' : ''; + $this->ldap->config_set('fuzzy_search', intval($this->prop['fuzzy_search'] && $mode != 1)); $ldap_data = $this->ldap->search($this->base_dn, $this->prop['filter'], $this->prop['scope'], $this->prop['attributes'], - array('search' => $value . $search_suffix /*, 'sort' => $this->prop['sort'] */)); + array('search' => $value /*, 'sort' => $this->prop['sort'] */)); if ($ldap_data === false) { return $this->result; } // get all entries of this page and post-filter those that really match the query $search = mb_strtolower($value); - foreach ($ldap_data as $i => $entry) { + foreach ($ldap_data as $entry) { $rec = $this->_ldap2result($entry); foreach ($fields as $f) { foreach ((array)$rec[$f] as $val) { @@ -791,33 +792,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 .= '(|'; @@ -827,8 +819,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 = ''; @@ -906,7 +923,6 @@ return $this->result; } - /** * Get a specific contact record * @@ -946,6 +962,23 @@ } return $assoc ? $res : $this->result; + } + + /** + * Returns the last error occurred (e.g. when updating/inserting failed) + * + * @return array Hash array with the following fields: type, message + */ + function get_error() + { + $err = $this->error; + + // check ldap connection for errors + if (!$err && $this->ldap->get_error()) { + $err = array(self::ERROR_SEARCH, $this->ldap->get_error()); + } + + return $err; } @@ -1515,7 +1548,6 @@ return $ldap_data; } - /** * Returns unified attribute name (resolving aliases) */ @@ -1547,17 +1579,6 @@ } /** - * Prints debug info to the log - */ - private function _debug($str) - { - if ($this->debug) { - rcube::write_log('ldap', $str); - } - } - - - /** * Activate/deactivate debug mode * * @param boolean $dbg True if LDAP commands should be logged @@ -1570,7 +1591,6 @@ $this->ldap->config_set('debug', $dbg); } } - /** * Setter for the current group @@ -1609,7 +1629,7 @@ if ($search) { foreach ($group_cache as $group) { - if ($this->compare_search_value('name', $group['name'], $search, $mode)) { + if ($this->compare_search_value('name', $group['name'], mb_strtolower($search), $mode)) { $groups[] = $group; } } @@ -1974,7 +1994,7 @@ $filter = strtr("(|(member=$contact_dn)(uniqueMember=$contact_dn)$add_filter)", array('\\' => '\\\\')); $ldap_data = $this->ldap->search($base_dn, $filter, 'sub', array('dn', $name_attr)); - if ($res === false) { + if ($ldap_data === false) { return array(); } -- Gitblit v1.9.1