@@ -84,7 +84,7 @@ public function __construct(IUserManager $userManager, IUserSession $userSession
84
84
* @return int bitwise-or'ed actions
85
85
*/
86
86
public function respondToActions () {
87
- $ setPassword = function_exists ( ' ldap_exop_passwd ' ) && !$ this ->ldapConnect ->hasPasswordPolicy ()
87
+ $ setPassword = $ this -> canSetPassword ( ) && !$ this ->ldapConnect ->hasPasswordPolicy ()
88
88
? Backend::SET_PASSWORD
89
89
: 0 ;
90
90
@@ -140,7 +140,7 @@ public function setDisplayName($uid, $displayName) {
140
140
* checks whether the user is allowed to change his avatar in Nextcloud
141
141
*
142
142
* @param string $uid the Nextcloud user name
143
- * @return boolean either the user can or cannot
143
+ * @return bool either the user can or cannot
144
144
*/
145
145
public function canChangeAvatar ($ uid ) {
146
146
return $ this ->configuration ->hasAvatarPermission ();
@@ -222,7 +222,12 @@ public function createUser($uid, $password) {
222
222
$ displayNameAttribute = $ this ->ldapConnect ->getDisplayNameAttribute ();
223
223
}
224
224
225
+ if ($ connection === false ) {
226
+ throw new \Exception ('Could not bind to LDAP server ' );
227
+ }
228
+
225
229
[$ newUserDN , $ newUserEntry ] = $ this ->buildNewEntry ($ uid , $ password , $ base );
230
+
226
231
$ newUserDN = $ this ->ldapProvider ->sanitizeDN ([$ newUserDN ])[0 ];
227
232
$ this ->ensureAttribute ($ newUserEntry , $ displayNameAttribute , $ uid );
228
233
@@ -244,27 +249,8 @@ public function createUser($uid, $password) {
244
249
throw new \Exception ('Cannot create user: ' . ldap_error ($ connection ), ldap_errno ($ connection ));
245
250
}
246
251
247
- // Set password through ldap password exop, if supported
248
252
if ($ this ->respondToActions () & Backend::SET_PASSWORD ) {
249
- try {
250
- $ ret = ldap_exop_passwd ($ connection , $ newUserDN , '' , $ password );
251
- if ($ ret === false ) {
252
- $ message = 'ldap_exop_passwd failed, falling back to ldap_mod_replace to to set password for new user ' ;
253
- $ this ->logger ->debug ($ message , ['app ' => Application::APP_ID ]);
254
-
255
- // Fallback to `userPassword` in case the server does not support exop_passwd
256
- $ ret = ldap_mod_replace ($ connection , $ newUserDN , ['userPassword ' => $ password ]);
257
- if ($ ret === false ) {
258
- $ message = 'Failed to set password for new user {dn} ' ;
259
- $ this ->logger ->error ($ message , [
260
- 'app ' => Application::APP_ID ,
261
- 'dn ' => $ newUserDN ,
262
- ]);
263
- }
264
- }
265
- } catch (\Exception $ e ) {
266
- $ this ->logger ->error ($ e ->getMessage (), ['exception ' => $ e , 'app ' => Application::APP_ID ]);
267
- }
253
+ $ this ->setPassword ($ username , $ password , $ connection );
268
254
}
269
255
return $ ret ? $ newUserDN : false ;
270
256
}
@@ -350,37 +336,82 @@ public function deleteUser($uid): bool {
350
336
return $ res ;
351
337
}
352
338
339
+ /**
340
+ * checks whether the user is allowed to change their password in Nextcloud
341
+ *
342
+ * @return bool either the user can or cannot
343
+ */
344
+ public function canSetPassword (): bool {
345
+ return $ this ->configuration ->hasPasswordPermission ();
346
+ }
347
+
353
348
/**
354
349
* Set password
355
350
*
356
351
* @param string $uid The username
357
352
* @param string $password The new password
353
+ * @param ?\LDAP\Connection $connection LDAP connection or null to create one
358
354
* @return bool
359
355
*
360
356
* Change the password of a user
361
357
*/
362
- public function setPassword ($ uid , $ password ) {
363
- if (!function_exists ('ldap_exop_passwd ' )) {
364
- // since PHP 7.2 – respondToActions checked this already, this
365
- // method should not be called. Double check due to public scope.
366
- // This method can be removed when Nextcloud 16 compat is dropped.
367
- return false ;
358
+ public function setPassword ($ uid , $ password , $ connection = null ) {
359
+ if (is_null ($ connection )) {
360
+ $ connection = $ this ->ldapProvider ->getLDAPConnection ($ uid );
368
361
}
362
+
369
363
try {
370
- $ cr = $ this ->ldapProvider ->getLDAPConnection ($ uid );
371
364
$ userDN = $ this ->getUserDN ($ uid );
372
- return ldap_exop_passwd ($ cr , $ userDN , '' , $ password ) !== false ;
365
+ $ ret = false ;
366
+
367
+ // try ldap_exop_passwd first
368
+ if ($ this ->ldapConnect ->hasPasswdExopSupport ($ connection )) {
369
+ $ ret = ldap_exop_passwd ($ connection , $ userDN , '' , $ password );
370
+ if ($ ret === false ) {
371
+ $ message = 'Failed to set password for user {dn} using ldap_exop_passwd ' ;
372
+ $ this ->logger ->error ($ message , [
373
+ 'ldap_error ' => ldap_error ($ connection ),
374
+ 'app ' => Application::APP_ID ,
375
+ 'dn ' => $ userDN ,
376
+ ]);
377
+ } else {
378
+ // `ldap_exop_passwd` is either FALSE or the password, in the later case return TRUE
379
+ $ ret = true ;
380
+ }
381
+ } else {
382
+ // Use ldap_mod_replace in case the server does not support exop_passwd
383
+ $ entry = [];
384
+ if ($ this ->configuration ->useUnicodePassword ()) {
385
+ $ entry ['unicodePwd ' ] = iconv ('UTF-8 ' , 'UTF-16LE ' , '" ' . $ password . '" ' );
386
+ } else {
387
+ $ entry ['userPassword ' ] = $ password ;
388
+ }
389
+ $ ret = ldap_mod_replace ($ connection , $ userDN , $ entry );
390
+ if ($ ret === false ) {
391
+ $ message = 'Failed to set password for user {dn} using ldap_mod_replace ' ;
392
+ $ this ->logger ->error ($ message , [
393
+ 'ldap_error ' => ldap_error ($ connection ),
394
+ 'app ' => Application::APP_ID ,
395
+ 'dn ' => $ userDN ,
396
+ ]);
397
+ }
398
+ }
399
+ return $ ret ;
373
400
} catch (\Exception $ e ) {
374
- $ this ->logger ->error ($ e ->getMessage (), ['exception ' => $ e , 'app ' => Application::APP_ID ]);
401
+ $ this ->logger ->error ('Exception occured while setting the password of user {uid} ' , [
402
+ 'app ' => Application::APP_ID ,
403
+ 'exception ' => $ e ,
404
+ 'uid ' => $ uid
405
+ ]);
406
+ return false ;
375
407
}
376
- return false ;
377
408
}
378
409
379
410
/**
380
411
* get the user's home directory
381
412
*
382
413
* @param string $uid the username
383
- * @return boolean
414
+ * @return bool
384
415
*/
385
416
public function getHome ($ uid ) {
386
417
// Not implemented
0 commit comments