This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Class LDAPGateway |
||
4 | * |
||
5 | * Works within the LDAP domain model to provide basic operations. |
||
6 | * These are exclusively used in LDAPService for constructing more complex operations. |
||
7 | */ |
||
8 | class LDAPGateway extends Object |
||
0 ignored issues
–
show
|
|||
9 | { |
||
10 | /** |
||
11 | * @var array |
||
12 | * @config |
||
13 | */ |
||
14 | private static $options = []; |
||
0 ignored issues
–
show
|
|||
15 | |||
16 | /** |
||
17 | * @var Zend\Ldap\Ldap |
||
18 | */ |
||
19 | private $ldap; |
||
20 | |||
21 | public function __construct() |
||
22 | { |
||
23 | parent::__construct(); |
||
24 | // due to dependency injection this class can be created without any LDAP options set |
||
25 | // and \Zend\Ldap\Ldap will throw a warning with an empty array |
||
26 | if (count($this->config()->options)) { |
||
27 | $this->ldap = new Zend\Ldap\Ldap($this->config()->options); |
||
28 | } |
||
29 | } |
||
30 | |||
31 | /** |
||
32 | * Query the LDAP directory with the given filter. |
||
33 | * |
||
34 | * @param string $filter The string to filter by, e.g. (objectClass=user) |
||
35 | * @param null|string $baseDn The DN to search from. Default is the baseDn option in the connection if not given |
||
36 | * @param int $scope The scope to perform the search. Zend_Ldap::SEARCH_SCOPE_ONE, Zend_LDAP::SEARCH_SCOPE_BASE. Default is Zend_Ldap::SEARCH_SCOPE_SUB |
||
37 | * @param array $attributes Restrict to specific AD attributes. An empty array will return all attributes |
||
38 | * @param string $sort Sort results by this attribute if given |
||
39 | * @return array |
||
40 | */ |
||
41 | protected function search($filter, $baseDn = null, $scope = Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes = [], $sort = '') |
||
42 | { |
||
43 | $records = $this->ldap->search($filter, $baseDn, $scope, $attributes, $sort); |
||
44 | |||
45 | $results = []; |
||
46 | foreach ($records as $record) { |
||
47 | foreach ($record as $attribute => $value) { |
||
0 ignored issues
–
show
The expression
$record of type array|null is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
48 | // if the value is an array with a single value, e.g. 'samaccountname' => array(0 => 'myusername') |
||
49 | // then make sure it's just set in the results as 'samaccountname' => 'myusername' so that it |
||
50 | // can be used directly by ArrayData |
||
51 | if (is_array($value) && count($value) == 1) { |
||
52 | $value = $value[0]; |
||
53 | } |
||
54 | |||
55 | // ObjectGUID and ObjectSID attributes are in binary, we need to convert those to strings |
||
56 | if ($attribute == 'objectguid') { |
||
57 | $value = LDAPUtil::bin_to_str_guid($value); |
||
58 | } |
||
59 | if ($attribute == 'objectsid') { |
||
60 | $value = LDAPUtil::bin_to_str_sid($value); |
||
61 | } |
||
62 | |||
63 | $record[$attribute] = $value; |
||
64 | } |
||
65 | |||
66 | $results[] = $record; |
||
67 | } |
||
68 | |||
69 | return $results; |
||
70 | } |
||
71 | |||
72 | /** |
||
73 | * Authenticate the given username and password with LDAP. |
||
74 | * |
||
75 | * @param string $username |
||
76 | * @param string $password |
||
77 | * @return \Zend\Authentication\Result |
||
78 | */ |
||
79 | public function authenticate($username, $password) |
||
80 | { |
||
81 | $auth = new Zend\Authentication\AuthenticationService(); |
||
82 | $adapter = new Zend\Authentication\Adapter\Ldap([$this->config()->options], $username, $password); |
||
83 | return $auth->authenticate($adapter); |
||
84 | } |
||
85 | |||
86 | /** |
||
87 | * Query for LDAP nodes (organizational units, containers, and domains). |
||
88 | * |
||
89 | * @param null|string $baseDn The DN to search from. Default is the baseDn option in the connection if not given |
||
90 | * @param int $scope The scope to perform the search. Zend_Ldap::SEARCH_SCOPE_ONE, Zend_LDAP::SEARCH_SCOPE_BASE. Default is Zend_Ldap::SEARCH_SCOPE_SUB |
||
91 | * @param array $attributes Restrict to specific AD attributes. An empty array will return all attributes |
||
92 | * @param string $sort Sort results by this attribute if given |
||
93 | * @return array |
||
94 | */ |
||
95 | public function getNodes($baseDn = null, $scope = Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes = [], $sort = '') |
||
96 | { |
||
97 | return $this->search('(|(objectClass=organizationalUnit)(objectClass=container)(objectClass=domain))', $baseDn, $scope, $attributes, $sort); |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * Query for LDAP groups. |
||
102 | * |
||
103 | * @param null|string $baseDn The DN to search from. Default is the baseDn option in the connection if not given |
||
104 | * @param int $scope The scope to perform the search. Zend_Ldap::SEARCH_SCOPE_ONE, Zend_LDAP::SEARCH_SCOPE_BASE. Default is Zend_Ldap::SEARCH_SCOPE_SUB |
||
105 | * @param array $attributes Restrict to specific AD attributes. An empty array will return all attributes |
||
106 | * @param string $sort Sort results by this attribute if given |
||
107 | * @return array |
||
108 | */ |
||
109 | public function getGroups($baseDn = null, $scope = Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes = [], $sort = '') |
||
110 | { |
||
111 | return $this->search('(objectClass=group)', $baseDn, $scope, $attributes, $sort); |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * Return all nested AD groups underneath a specific DN |
||
116 | * |
||
117 | * @param string $dn |
||
118 | * @param null|string $baseDn The DN to search from. Default is the baseDn option in the connection if not given |
||
119 | * @param int $scope The scope to perform the search. Zend_Ldap::SEARCH_SCOPE_ONE, Zend_LDAP::SEARCH_SCOPE_BASE. Default is Zend_Ldap::SEARCH_SCOPE_SUB |
||
120 | * @param array $attributes Restrict to specific AD attributes. An empty array will return all attributes |
||
121 | * @return array |
||
122 | */ |
||
123 | public function getNestedGroups($dn, $baseDn = null, $scope = Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes = []) |
||
124 | { |
||
125 | return $this->search( |
||
126 | sprintf('(&(objectClass=group)(memberOf:1.2.840.113556.1.4.1941:=%s))', $dn), |
||
127 | $baseDn, |
||
128 | $scope, |
||
129 | $attributes |
||
130 | ); |
||
131 | } |
||
132 | |||
133 | /** |
||
134 | * Return a particular LDAP group by objectGUID value. |
||
135 | * |
||
136 | * @param string $guid |
||
137 | * @param null|string $baseDn The DN to search from. Default is the baseDn option in the connection if not given |
||
138 | * @param int $scope The scope to perform the search. Zend_Ldap::SEARCH_SCOPE_ONE, Zend_LDAP::SEARCH_SCOPE_BASE. Default is Zend_Ldap::SEARCH_SCOPE_SUB |
||
139 | * @param array $attributes Restrict to specific AD attributes. An empty array will return all attributes |
||
140 | * @return array |
||
141 | */ |
||
142 | View Code Duplication | public function getGroupByGUID($guid, $baseDn = null, $scope = Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes = []) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
143 | { |
||
144 | return $this->search( |
||
145 | sprintf('(&(objectClass=group)(objectGUID=%s))', LDAPUtil::str_to_hex_guid($guid, true)), |
||
146 | $baseDn, |
||
147 | $scope, |
||
148 | $attributes |
||
149 | ); |
||
150 | } |
||
151 | |||
152 | /** |
||
153 | * Return a particular LDAP group by DN value. |
||
154 | * |
||
155 | * @param string $dn |
||
156 | * @param null|string $baseDn The DN to search from. Default is the baseDn option in the connection if not given |
||
157 | * @param int $scope The scope to perform the search. Zend_Ldap::SEARCH_SCOPE_ONE, Zend_LDAP::SEARCH_SCOPE_BASE. Default is Zend_Ldap::SEARCH_SCOPE_SUB |
||
158 | * @param array $attributes Restrict to specific AD attributes. An empty array will return all attributes |
||
159 | * @return array |
||
160 | */ |
||
161 | public function getGroupByDN($dn, $baseDn = null, $scope = Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes = []) |
||
162 | { |
||
163 | return $this->search( |
||
164 | sprintf('(&(objectClass=group)(distinguishedname=%s))', $dn), |
||
165 | $baseDn, |
||
166 | $scope, |
||
167 | $attributes |
||
168 | ); |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * Query for LDAP users, but don't include built-in user accounts. |
||
173 | * |
||
174 | * @param null|string $baseDn The DN to search from. Default is the baseDn option in the connection if not given |
||
175 | * @param int $scope The scope to perform the search. Zend_Ldap::SEARCH_SCOPE_ONE, Zend_LDAP::SEARCH_SCOPE_BASE. Default is Zend_Ldap::SEARCH_SCOPE_SUB |
||
176 | * @param array $attributes Restrict to specific AD attributes. An empty array will return all attributes |
||
177 | * @param string $sort Sort results by this attribute if given |
||
178 | * @return array |
||
179 | */ |
||
180 | public function getUsers($baseDn = null, $scope = Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes = [], $sort = '') |
||
181 | { |
||
182 | return $this->search( |
||
183 | '(&(objectClass=user)(!(objectClass=computer))(!(samaccountname=Guest))(!(samaccountname=Administrator))(!(samaccountname=krbtgt)))', |
||
184 | $baseDn, |
||
185 | $scope, |
||
186 | $attributes, |
||
187 | $sort |
||
188 | ); |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * Return a particular LDAP user by objectGUID value. |
||
193 | * |
||
194 | * @param string $guid |
||
195 | * @return array |
||
196 | */ |
||
197 | View Code Duplication | public function getUserByGUID($guid, $baseDn = null, $scope = Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes = []) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
198 | { |
||
199 | return $this->search( |
||
200 | sprintf('(&(objectClass=user)(objectGUID=%s))', LDAPUtil::str_to_hex_guid($guid, true)), |
||
201 | $baseDn, |
||
202 | $scope, |
||
203 | $attributes |
||
204 | ); |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * Return a particular LDAP user by DN value. |
||
209 | * |
||
210 | * @param string $dn |
||
211 | * @param null|string $baseDn The DN to search from. Default is the baseDn option in the connection if not given |
||
212 | * @param int $scope The scope to perform the search. Zend_Ldap::SEARCH_SCOPE_ONE, Zend_LDAP::SEARCH_SCOPE_BASE. Default is Zend_Ldap::SEARCH_SCOPE_SUB |
||
213 | * @param array $attributes Restrict to specific AD attributes. An empty array will return all attributes |
||
214 | * @return array |
||
215 | */ |
||
216 | public function getUserByDN($dn, $baseDn = null, $scope = Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes = []) |
||
217 | { |
||
218 | return $this->search( |
||
219 | sprintf('(&(objectClass=user)(distinguishedname=%s))', $dn), |
||
220 | $baseDn, |
||
221 | $scope, |
||
222 | $attributes |
||
223 | ); |
||
224 | } |
||
225 | |||
226 | /** |
||
227 | * Return a particular LDAP user by mail value. |
||
228 | * |
||
229 | * @param string $email |
||
230 | * @return array |
||
231 | */ |
||
232 | public function getUserByEmail($email, $baseDn = null, $scope = Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes = []) |
||
233 | { |
||
234 | return $this->search( |
||
235 | sprintf('(&(objectClass=user)(mail=%s))', Zend\Ldap\Filter\AbstractFilter::escapeValue($email)), |
||
236 | $baseDn, |
||
237 | $scope, |
||
238 | $attributes |
||
239 | ); |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Get a specific user's data from LDAP |
||
244 | * |
||
245 | * @param string $username |
||
246 | * @param null|string $baseDn The DN to search from. Default is the baseDn option in the connection if not given |
||
247 | * @param int $scope The scope to perform the search. Zend_Ldap::SEARCH_SCOPE_ONE, Zend_LDAP::SEARCH_SCOPE_BASE. Default is Zend_Ldap::SEARCH_SCOPE_SUB |
||
248 | * @param array $attributes Restrict to specific AD attributes. An empty array will return all attributes |
||
249 | * @return array |
||
250 | * @throws Exception |
||
251 | */ |
||
252 | public function getUserByUsername($username, $baseDn = null, $scope = Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes = []) |
||
253 | { |
||
254 | $options = $this->config()->options; |
||
255 | $option = isset($options['accountCanonicalForm']) ? $options['accountCanonicalForm'] : null; |
||
256 | |||
257 | // will translate the username to [email protected], username or foo\user depending on the |
||
258 | // $options['accountCanonicalForm'] |
||
259 | $username = $this->ldap->getCanonicalAccountName($username, $option); |
||
260 | switch ($option) { |
||
261 | case Zend\Ldap\Ldap::ACCTNAME_FORM_USERNAME: // traditional style usernames, e.g. alice |
||
262 | $filter = sprintf('(&(objectClass=user)(samaccountname=%s))', Zend\Ldap\Filter\AbstractFilter::escapeValue($username)); |
||
263 | break; |
||
264 | case Zend\Ldap\Ldap::ACCTNAME_FORM_BACKSLASH: // backslash style usernames, e.g. FOO\alice |
||
265 | // @todo Not supported yet! |
||
266 | throw new Exception('Backslash style not supported in LDAPGateway::getUserByUsername()!'); |
||
267 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
268 | case Zend\Ldap\Ldap::ACCTNAME_FORM_PRINCIPAL: // principal style usernames, e.g. [email protected] |
||
269 | $filter = sprintf('(&(objectClass=user)(userprincipalname=%s))', Zend\Ldap\Filter\AbstractFilter::escapeValue($username)); |
||
270 | break; |
||
271 | case Zend\Ldap\Ldap::ACCTNAME_FORM_DN: // distinguished name, e.g. CN=someone,DC=example,DC=co,DC=nz |
||
272 | // @todo Not supported yet! |
||
273 | throw new Exception('DN style not supported in LDAPGateway::getUserByUsername()!'); |
||
274 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
275 | default: // default to principal style |
||
276 | $filter = sprintf('(&(objectClass=user)(userprincipalname=%s))', Zend\Ldap\Filter\AbstractFilter::escapeValue($username)); |
||
277 | } |
||
278 | |||
279 | return $this->search($filter, $baseDn, $scope, $attributes); |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * Get a canonical username from the record based on the connection settings. |
||
284 | * |
||
285 | * @param array $data |
||
286 | * @return string |
||
287 | */ |
||
288 | public function getCanonicalUsername($data) |
||
289 | { |
||
290 | $options = $this->config()->options; |
||
291 | $option = isset($options['accountCanonicalForm']) ? $options['accountCanonicalForm'] : null; |
||
292 | |||
293 | switch ($option) { |
||
294 | case Zend\Ldap\Ldap::ACCTNAME_FORM_USERNAME: // traditional style usernames, e.g. alice |
||
295 | if (empty($data['samaccountname'])) { |
||
296 | throw new \Exception('Could not extract canonical username: samaccountname field missing'); |
||
297 | } |
||
298 | return $data['samaccountname']; |
||
299 | case Zend\Ldap\Ldap::ACCTNAME_FORM_BACKSLASH: // backslash style usernames, e.g. FOO\alice |
||
300 | // @todo Not supported yet! |
||
301 | throw new Exception('Backslash style not supported in LDAPGateway::getUsernameByEmail()!'); |
||
302 | case Zend\Ldap\Ldap::ACCTNAME_FORM_PRINCIPAL: // principal style usernames, e.g. [email protected] |
||
303 | if (empty($data['userprincipalname'])) { |
||
304 | throw new \Exception('Could not extract canonical username: userprincipalname field missing'); |
||
305 | } |
||
306 | return $data['userprincipalname']; |
||
307 | default: // default to principal style |
||
308 | if (empty($data['userprincipalname'])) { |
||
309 | throw new \Exception('Could not extract canonical username: userprincipalname field missing'); |
||
310 | } |
||
311 | return $data['userprincipalname']; |
||
312 | } |
||
313 | } |
||
314 | |||
315 | /** |
||
316 | * Changes user password via LDAP. |
||
317 | * |
||
318 | * Change password is different to administrative password reset in that it will respect the password |
||
319 | * history policy. This is achieved by sending a remove followed by an add in one batch (which is different |
||
320 | * to an ordinary attribute modification operation). |
||
321 | * |
||
322 | * @param string $dn Location to update the entry at. |
||
323 | * @param string $password New password to set. |
||
324 | * @param string $oldPassword Old password is needed to trigger a password change. |
||
325 | * @throws \Zend\Ldap\Exception\LdapException |
||
326 | */ |
||
327 | public function changePassword($dn, $password, $oldPassword) |
||
328 | { |
||
329 | if (!function_exists('ldap_modify_batch')) { |
||
330 | // Password change is unsupported - missing PHP API method. |
||
331 | $this->resetPassword($dn, $password); |
||
332 | return; |
||
333 | } |
||
334 | |||
335 | $modifications = [ |
||
336 | [ |
||
337 | "attrib" => "unicodePwd", |
||
338 | "modtype" => LDAP_MODIFY_BATCH_REMOVE, |
||
339 | "values" => [iconv('UTF-8', 'UTF-16LE', sprintf('"%s"', $oldPassword))], |
||
340 | ], |
||
341 | [ |
||
342 | "attrib" => "unicodePwd", |
||
343 | "modtype" => LDAP_MODIFY_BATCH_ADD, |
||
344 | "values" => [iconv('UTF-8', 'UTF-16LE', sprintf('"%s"', $password))], |
||
345 | ], |
||
346 | ]; |
||
347 | // Batch attribute operations are not supported by Zend_Ldap, use raw resource. |
||
348 | $ldapConn = $this->ldap->getResource(); |
||
349 | \Zend\Stdlib\ErrorHandler::start(E_WARNING); |
||
350 | $succeeded = ldap_modify_batch($ldapConn, $dn, $modifications); |
||
351 | \Zend\Stdlib\ErrorHandler::stop(); |
||
352 | if (!$succeeded) { |
||
353 | throw new Exception($this->getLastPasswordError()); |
||
354 | } |
||
355 | } |
||
356 | |||
357 | /** |
||
358 | * Administrative password reset. |
||
359 | * |
||
360 | * This is different to password change - it does not require old password, but also |
||
361 | * it does not respect password history policy setting. |
||
362 | * |
||
363 | * @param string $dn Location to update the entry at. |
||
364 | * @param string $password New password to set. |
||
365 | * @throws \Zend\Ldap\Exception\LdapException |
||
366 | */ |
||
367 | public function resetPassword($dn, $password) |
||
368 | { |
||
369 | try { |
||
370 | $this->update( |
||
371 | $dn, |
||
372 | ['unicodePwd' => iconv('UTF-8', 'UTF-16LE', sprintf('"%s"', $password))] |
||
373 | ); |
||
374 | } catch(\Zend\Ldap\Exception\LdapException $e) { |
||
375 | throw new Exception($this->getLastPasswordError()); |
||
376 | } |
||
377 | } |
||
378 | |||
379 | /** |
||
380 | * Updates an LDAP object. |
||
381 | * |
||
382 | * For this work you might need that LDAP connection is bind:ed with a user with |
||
383 | * enough permissions to change attributes and that the LDAP connection is using |
||
384 | * SSL/TLS. It depends on the server setup. |
||
385 | * |
||
386 | * If there are some errors, the underlying LDAP library should throw an Exception |
||
387 | * |
||
388 | * @param string $dn Location to update the entry at. |
||
389 | * @param array $attributes An associative array of attributes. |
||
390 | * @throws \Zend\Ldap\Exception\LdapException |
||
391 | */ |
||
392 | public function update($dn, array $attributes) |
||
393 | { |
||
394 | $this->ldap->update($dn, $attributes); |
||
395 | } |
||
396 | |||
397 | /** |
||
398 | * Deletes an LDAP object. |
||
399 | * |
||
400 | * @param string $dn Location of object to delete |
||
401 | * @param bool $recursively Recursively delete nested objects? |
||
402 | * @throws \Zend\Ldap\Exception\LdapException |
||
403 | */ |
||
404 | public function delete($dn, $recursively = false) |
||
405 | { |
||
406 | $this->ldap->delete($dn, $recursively); |
||
407 | } |
||
408 | |||
409 | /** |
||
410 | * Move an LDAP object from it's original DN location to another. |
||
411 | * This effectively copies the object then deletes the original one. |
||
412 | * |
||
413 | * @param string $fromDn |
||
414 | * @param string $toDn |
||
415 | * @param bool $recursively Recursively move nested objects? |
||
416 | */ |
||
417 | public function move($fromDn, $toDn, $recursively = false) |
||
418 | { |
||
419 | $this->ldap->move($fromDn, $toDn, $recursively); |
||
420 | } |
||
421 | |||
422 | /** |
||
423 | * Add an LDAP object. |
||
424 | * |
||
425 | * For this work you might need that LDAP connection is bind:ed with a user with |
||
426 | * enough permissions to change attributes and that the LDAP connection is using |
||
427 | * SSL/TLS. It depends on the server setup. |
||
428 | * |
||
429 | * @param string $dn Location to add the entry at. |
||
430 | * @param array $attributes An associative array of attributes. |
||
431 | * @throws \Zend\Ldap\Exception\LdapException |
||
432 | */ |
||
433 | public function add($dn, array $attributes) |
||
434 | { |
||
435 | $this->ldap->add($dn, $attributes); |
||
436 | } |
||
437 | |||
438 | /** |
||
439 | * @param \Zend\Ldap\Exception\LdapException |
||
440 | * @return string |
||
441 | */ |
||
442 | private function getLastPasswordError() { |
||
443 | $defaultError = _t('LDAPAuthenticator.CANTCHANGEPASSWORD', 'We couldn\'t change your password, please contact an administrator.'); |
||
444 | $error = ''; |
||
445 | ldap_get_option($this->ldap->getResource(), LDAP_OPT_ERROR_STRING, $error); |
||
446 | |||
447 | if (!$error) { |
||
448 | return $defaultError; |
||
449 | } |
||
450 | |||
451 | // Try to parse the exception to get the error message to display to user, eg: |
||
452 | // 0000052D: Constraint violation - check_password_restrictions: the password does not meet the complexity criteria!) |
||
453 | // 0000052D: Constraint violation - check_password_restrictions: the password was already used (in history)!) |
||
454 | |||
455 | // We are only interested in the explanatory message after the last colon. |
||
456 | $message = preg_replace('/.*:/', '', $error); |
||
457 | if ($error) { |
||
458 | return ucfirst(trim($message)); |
||
459 | } |
||
460 | |||
461 | return $defaultError; |
||
462 | } |
||
463 | } |
||
464 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.