@@ -87,7 +87,7 @@ public function __construct(IUserManager $userManager, IUserSession $userSession
87
87
* compared with OC_USER_BACKEND_CREATE_USER etc.
88
88
*/
89
89
public function respondToActions () {
90
- $ setPassword = function_exists ( ' ldap_exop_passwd ' ) && !$ this ->ldapConnect ->hasPasswordPolicy ()
90
+ $ setPassword = $ this -> canSetPassword ( ) && !$ this ->ldapConnect ->hasPasswordPolicy ()
91
91
? Backend::SET_PASSWORD
92
92
: 0 ;
93
93
@@ -247,29 +247,8 @@ public function createUser($username, $password) {
247
247
throw new \Exception ('Cannot create user: ' . ldap_error ($ connection ), ldap_errno ($ connection ));
248
248
}
249
249
250
- // Set password through ldap password exop, if supported
251
250
if ($ this ->respondToActions () & Backend::SET_PASSWORD ) {
252
- try {
253
- $ ret = ldap_exop_passwd ($ connection , $ newUserDN , '' , $ password );
254
- if ($ ret === false ) {
255
- $ message = 'ldap_exop_passwd failed, falling back to ldap_mod_replace to to set password for new user ' ;
256
- $ this ->logger ->log (ILogger::DEBUG , $ message , [
257
- 'app ' => Application::APP_ID ,
258
- ]);
259
-
260
- // Fallback to `userPassword` in case the server does not support exop_passwd
261
- $ ret = ldap_mod_replace ($ connection , $ newUserDN , ['userPassword ' => $ password ]);
262
- if ($ ret === false ) {
263
- $ message = 'Failed to set password for new user {dn} ' ;
264
- $ this ->logger ->log (ILogger::ERROR , $ message , [
265
- 'app ' => Application::APP_ID ,
266
- 'dn ' => $ newUserDN ,
267
- ]);
268
- }
269
- }
270
- } catch (\Exception $ e ) {
271
- $ this ->logger ->logException ($ e , ['app ' => Application::APP_ID ]);
272
- }
251
+ $ this ->setPassword ($ username , $ password , $ connection );
273
252
}
274
253
return $ ret ? $ newUserDN : false ;
275
254
}
@@ -355,30 +334,62 @@ public function deleteUser($uid): bool {
355
334
return $ res ;
356
335
}
357
336
337
+ /**
338
+ * checks whether the user is allowed to change their password in Nextcloud
339
+ *
340
+ * @return boolean either the user can or cannot
341
+ */
342
+ public function canSetPassword () {
343
+ return $ this ->configuration ->hasPasswordPermission ();
344
+ }
345
+
358
346
/**
359
347
* Set password
360
348
*
361
349
* @param string $uid The username
362
350
* @param string $password The new password
351
+ * @param ?LDAP\Connection $connection LDAP connection or null to create one
363
352
* @return bool
364
353
*
365
354
* Change the password of a user
366
355
*/
367
- public function setPassword ($ uid , $ password ) {
368
- if (!function_exists ('ldap_exop_passwd ' )) {
369
- // since PHP 7.2 – respondToActions checked this already, this
370
- // method should not be called. Double check due to public scope.
371
- // This method can be removed when Nextcloud 16 compat is dropped.
372
- return false ;
356
+ public function setPassword ($ uid , $ password , $ connection = null ) {
357
+ if (is_null ($ connection )) {
358
+ $ connection = $ this ->ldapProvider ->getLDAPConnection ($ uid );
373
359
}
360
+
374
361
try {
375
- $ cr = $ this ->ldapProvider ->getLDAPConnection ($ uid );
376
362
$ userDN = $ this ->getUserDN ($ uid );
377
- return ldap_exop_passwd ($ cr , $ userDN , '' , $ password );
363
+ $ ret = false ;
364
+
365
+ // try ldap_exop_passwd first
366
+ if ($ ldapConnect ->hasPasswdExopSupport ($ connection )) {
367
+ $ ret = ldap_exop_passwd ($ connection , $ userDN , '' , $ password );
368
+ if ($ ret === false ) {
369
+ $ message = 'ldap_exop_passwd failed, falling back to ldap_mod_replace to to set password for new user ' ;
370
+ $ this ->logger ->log (ILogger::ERROR , $ message , [
371
+ 'app ' => Application::APP_ID ,
372
+ 'ldap_error ' => ldap_error ($ connection ),
373
+ ]);
374
+ }
375
+ }
376
+
377
+ // Fallback to `userPassword` in case the server does not support exop_passwd
378
+ if ($ ret === false ) {
379
+ $ ret = ldap_mod_replace ($ connection , $ userDN , ['userPassword ' => $ password ]);
380
+ if ($ ret === false ) {
381
+ $ message = 'Failed to set password for user {dn} ' ;
382
+ $ this ->logger ->log (ILogger::ERROR , $ message , [
383
+ 'app ' => Application::APP_ID ,
384
+ 'dn ' => $ userDN ,
385
+ ]);
386
+ }
387
+ }
388
+ return $ ret ;
378
389
} catch (\Exception $ e ) {
379
390
$ this ->logger ->logException ($ e , ['app ' => Application::APP_ID ]);
391
+ return false ;
380
392
}
381
- return false ;
382
393
}
383
394
384
395
/**
0 commit comments