Mercurial > hg > rc2
comparison program/lib/Roundcube/rcube_ldap_generic.php @ 0:4681f974d28b
vanilla 1.3.3 distro, I hope
author | Charlie Root |
---|---|
date | Thu, 04 Jan 2018 15:52:31 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4681f974d28b |
---|---|
1 <?php | |
2 | |
3 /** | |
4 +-----------------------------------------------------------------------+ | |
5 | Roundcube/rcube_ldap_generic.php | | |
6 | | | |
7 | This file is part of the Roundcube Webmail client | | |
8 | Copyright (C) 2006-2014, The Roundcube Dev Team | | |
9 | Copyright (C) 2012-2015, Kolab Systems AG | | |
10 | | | |
11 | Licensed under the GNU General Public License version 3 or | | |
12 | any later version with exceptions for skins & plugins. | | |
13 | See the README file for a full license statement. | | |
14 | | | |
15 | PURPOSE: | | |
16 | Provide basic functionality for accessing LDAP directories | | |
17 | | | |
18 +-----------------------------------------------------------------------+ | |
19 | Author: Thomas Bruederli <roundcube@gmail.com> | | |
20 | Aleksander Machniak <machniak@kolabsys.com> | | |
21 +-----------------------------------------------------------------------+ | |
22 */ | |
23 | |
24 /** | |
25 * Model class to access an LDAP directories | |
26 * | |
27 * @package Framework | |
28 * @subpackage LDAP | |
29 */ | |
30 class rcube_ldap_generic extends Net_LDAP3 | |
31 { | |
32 /** private properties */ | |
33 protected $cache = null; | |
34 protected $attributes = array('dn'); | |
35 protected $error; | |
36 | |
37 function __construct($config = null) | |
38 { | |
39 parent::__construct($config); | |
40 | |
41 $this->config_set('log_hook', array($this, 'log')); | |
42 } | |
43 | |
44 /** | |
45 * Establish a connection to the LDAP server | |
46 */ | |
47 public function connect($host = null) | |
48 { | |
49 // Net_LDAP3 does not support IDNA yet | |
50 // also parse_host() here is very Roundcube specific | |
51 $host = rcube_utils::parse_host($host, $this->config['mail_domain']); | |
52 $host = rcube_utils::idn_to_ascii($host); | |
53 | |
54 return parent::connect($host); | |
55 } | |
56 | |
57 /** | |
58 * Get a specific LDAP entry, identified by its DN | |
59 * | |
60 * @param string $dn Record identifier | |
61 * @param array $attributes Attributes to return | |
62 * | |
63 * @return array Hash array | |
64 */ | |
65 function get_entry($dn, $attributes = array()) | |
66 { | |
67 return parent::get_entry($dn, !empty($attributes) ? $attributes : $this->attributes); | |
68 } | |
69 | |
70 /** | |
71 * Prints debug/error info to the log | |
72 */ | |
73 public function log($level, $msg) | |
74 { | |
75 $msg = implode("\n", $msg); | |
76 | |
77 switch ($level) { | |
78 case LOG_DEBUG: | |
79 case LOG_INFO: | |
80 case LOG_NOTICE: | |
81 if ($this->config['debug']) { | |
82 rcube::write_log('ldap', $msg); | |
83 } | |
84 break; | |
85 | |
86 case LOG_EMERGE: | |
87 case LOG_ALERT: | |
88 case LOG_CRIT: | |
89 rcube::raise_error($msg, true, true); | |
90 break; | |
91 | |
92 case LOG_ERR: | |
93 case LOG_WARNING: | |
94 $this->error = $msg; | |
95 rcube::raise_error($msg, true, false); | |
96 break; | |
97 } | |
98 } | |
99 | |
100 /** | |
101 * Returns the last LDAP error occurred | |
102 * | |
103 * @return mixed Error message string or null if no error occurred | |
104 */ | |
105 function get_error() | |
106 { | |
107 return $this->error; | |
108 } | |
109 | |
110 /** | |
111 * @deprecated | |
112 */ | |
113 public function set_debug($dbg = true) | |
114 { | |
115 $this->config['debug'] = (bool) $dbg; | |
116 } | |
117 | |
118 /** | |
119 * @deprecated | |
120 */ | |
121 public function set_cache($cache_engine) | |
122 { | |
123 $this->config['cache'] = $cache_engine; | |
124 } | |
125 | |
126 /** | |
127 * @deprecated | |
128 */ | |
129 public static function scope2func($scope, &$ns_function = null) | |
130 { | |
131 return self::scope_to_function($scope, $ns_function); | |
132 } | |
133 | |
134 /** | |
135 * @deprecated | |
136 */ | |
137 public function set_config($opt, $val = null) | |
138 { | |
139 $this->config_set($opt, $val); | |
140 } | |
141 | |
142 /** | |
143 * @deprecated | |
144 */ | |
145 public function add($dn, $entry) | |
146 { | |
147 return $this->add_entry($dn, $entry); | |
148 } | |
149 | |
150 /** | |
151 * @deprecated | |
152 */ | |
153 public function delete($dn) | |
154 { | |
155 return $this->delete_entry($dn); | |
156 } | |
157 | |
158 /** | |
159 * Wrapper for ldap_mod_replace() | |
160 * | |
161 * @see ldap_mod_replace() | |
162 */ | |
163 public function mod_replace($dn, $entry) | |
164 { | |
165 $this->_debug("C: Replace $dn: ".print_r($entry, true)); | |
166 | |
167 if (!ldap_mod_replace($this->conn, $dn, $entry)) { | |
168 $this->_error("ldap_mod_replace() failed with " . ldap_error($this->conn)); | |
169 return false; | |
170 } | |
171 | |
172 $this->_debug("S: OK"); | |
173 return true; | |
174 } | |
175 | |
176 /** | |
177 * Wrapper for ldap_mod_add() | |
178 * | |
179 * @see ldap_mod_add() | |
180 */ | |
181 public function mod_add($dn, $entry) | |
182 { | |
183 $this->_debug("C: Add $dn: ".print_r($entry, true)); | |
184 | |
185 if (!ldap_mod_add($this->conn, $dn, $entry)) { | |
186 $this->_error("ldap_mod_add() failed with " . ldap_error($this->conn)); | |
187 return false; | |
188 } | |
189 | |
190 $this->_debug("S: OK"); | |
191 return true; | |
192 } | |
193 | |
194 /** | |
195 * Wrapper for ldap_mod_del() | |
196 * | |
197 * @see ldap_mod_del() | |
198 */ | |
199 public function mod_del($dn, $entry) | |
200 { | |
201 $this->_debug("C: Delete $dn: ".print_r($entry, true)); | |
202 | |
203 if (!ldap_mod_del($this->conn, $dn, $entry)) { | |
204 $this->_error("ldap_mod_del() failed with " . ldap_error($this->conn)); | |
205 return false; | |
206 } | |
207 | |
208 $this->_debug("S: OK"); | |
209 return true; | |
210 } | |
211 | |
212 /** | |
213 * Wrapper for ldap_rename() | |
214 * | |
215 * @see ldap_rename() | |
216 */ | |
217 public function rename($dn, $newrdn, $newparent = null, $deleteoldrdn = true) | |
218 { | |
219 $this->_debug("C: Rename $dn to $newrdn"); | |
220 | |
221 if (!ldap_rename($this->conn, $dn, $newrdn, $newparent, $deleteoldrdn)) { | |
222 $this->_error("ldap_rename() failed with " . ldap_error($this->conn)); | |
223 return false; | |
224 } | |
225 | |
226 $this->_debug("S: OK"); | |
227 return true; | |
228 } | |
229 | |
230 /** | |
231 * Wrapper for ldap_list() + ldap_get_entries() | |
232 * | |
233 * @see ldap_list() | |
234 * @see ldap_get_entries() | |
235 */ | |
236 public function list_entries($dn, $filter, $attributes = array('dn')) | |
237 { | |
238 $list = array(); | |
239 $this->_debug("C: List $dn [{$filter}]"); | |
240 | |
241 if ($result = ldap_list($this->conn, $dn, $filter, $attributes)) { | |
242 $list = ldap_get_entries($this->conn, $result); | |
243 | |
244 if ($list === false) { | |
245 $this->_error("ldap_get_entries() failed with " . ldap_error($this->conn)); | |
246 return array(); | |
247 } | |
248 | |
249 $count = $list['count']; | |
250 unset($list['count']); | |
251 | |
252 $this->_debug("S: $count record(s)"); | |
253 } | |
254 else { | |
255 $this->_error("ldap_list() failed with " . ldap_error($this->conn)); | |
256 } | |
257 | |
258 return $list; | |
259 } | |
260 | |
261 /** | |
262 * Wrapper for ldap_read() + ldap_get_entries() | |
263 * | |
264 * @see ldap_read() | |
265 * @see ldap_get_entries() | |
266 */ | |
267 public function read_entries($dn, $filter, $attributes = null) | |
268 { | |
269 $this->_debug("C: Read $dn [{$filter}]"); | |
270 | |
271 if ($this->conn && $dn) { | |
272 $result = @ldap_read($this->conn, $dn, $filter, $attributes, 0, (int)$this->config['sizelimit'], (int)$this->config['timelimit']); | |
273 if ($result === false) { | |
274 $this->_error("ldap_read() failed with " . ldap_error($this->conn)); | |
275 return false; | |
276 } | |
277 | |
278 $this->_debug("S: OK"); | |
279 return ldap_get_entries($this->conn, $result); | |
280 } | |
281 | |
282 return false; | |
283 } | |
284 | |
285 /** | |
286 * Turn an LDAP entry into a regular PHP array with attributes as keys. | |
287 * | |
288 * @param array $entry Attributes array as retrieved from ldap_get_attributes() or ldap_get_entries() | |
289 * @param bool $flat Convert one-element-array values into strings (not implemented) | |
290 * | |
291 * @return array Hash array with attributes as keys | |
292 */ | |
293 public static function normalize_entry($entry, $flat = false) | |
294 { | |
295 if (!isset($entry['count'])) { | |
296 return $entry; | |
297 } | |
298 | |
299 $rec = array(); | |
300 | |
301 for ($i=0; $i < $entry['count']; $i++) { | |
302 $attr = $entry[$i]; | |
303 if ($entry[$attr]['count'] == 1) { | |
304 switch ($attr) { | |
305 case 'objectclass': | |
306 $rec[$attr] = array(strtolower($entry[$attr][0])); | |
307 break; | |
308 default: | |
309 $rec[$attr] = $entry[$attr][0]; | |
310 break; | |
311 } | |
312 } | |
313 else { | |
314 for ($j=0; $j < $entry[$attr]['count']; $j++) { | |
315 $rec[$attr][$j] = $entry[$attr][$j]; | |
316 } | |
317 } | |
318 } | |
319 | |
320 return $rec; | |
321 } | |
322 | |
323 /** | |
324 * Compose an LDAP filter string matching all words from the search string | |
325 * in the given list of attributes. | |
326 * | |
327 * @param string $value Search value | |
328 * @param mixed $attrs List of LDAP attributes to search | |
329 * @param int $mode Matching mode: | |
330 * 0 - partial (*abc*), | |
331 * 1 - strict (=), | |
332 * 2 - prefix (abc*) | |
333 * @return string LDAP filter | |
334 */ | |
335 public static function fulltext_search_filter($value, $attributes, $mode = 1) | |
336 { | |
337 if (empty($attributes)) { | |
338 $attributes = array('cn'); | |
339 } | |
340 | |
341 $groups = array(); | |
342 $value = str_replace('*', '', $value); | |
343 $words = $mode == 0 ? rcube_utils::tokenize_string($value, 1) : array($value); | |
344 | |
345 // set wildcards | |
346 $wp = $ws = ''; | |
347 if ($mode != 1) { | |
348 $ws = '*'; | |
349 $wp = !$mode ? '*' : ''; | |
350 } | |
351 | |
352 // search each word in all listed attributes | |
353 foreach ($words as $word) { | |
354 $parts = array(); | |
355 foreach ($attributes as $attr) { | |
356 $parts[] = "($attr=$wp" . self::quote_string($word) . "$ws)"; | |
357 } | |
358 $groups[] = '(|' . join('', $parts) . ')'; | |
359 } | |
360 | |
361 return count($groups) > 1 ? '(&' . join('', $groups) . ')' : join('', $groups); | |
362 } | |
363 } | |
364 | |
365 // for backward compat. | |
366 class rcube_ldap_result extends Net_LDAP3_Result {} |