Adldap2 / Adldap2-Laravel

LDAP Authentication & Management for Laravel
MIT License
911 stars 184 forks source link

AdldapException: User.php line 1003 while trying to change password on FreeIPA #427

Open NamoDev opened 6 years ago

NamoDev commented 6 years ago

Description:

Steps To Reproduce:

Set up a Laravel project with the extension, then a LDAP binding with an admin account over TLS.

Now, create a controller for password operations. I used this code to get the user object: $theUser = Adldap::search()->users()->where("uid", "=", Session::get("username"))->first();

(Not sure if this is relevant, but as a side-note, in FreeIPA, the full DN for a user will be something like "uid=foobar,cn=users,cn=accounts,dc=mydc,dc=example,dc=net")

var_dump() shows that the user data comes up as expected. Then, the changePassword() method is called on the object like this: $theUser->changePassword($request->old_password, $request->new_password);

However, this causes an exception with no message. The only thing that the logger says is that there's an AdldapException on User.php line 1003.

I'm pretty sure this is probably a syntax issue (or something similar) somewhere, but after fiddling for a big while I still can't figure out why this won't work. Help would be much appreciated :)

stevebauman commented 6 years ago

Hi @NamoDev, unfortunately I have no experience with FreeIPA and I can't seem to find any documentation on the users password field that needs to be modified for a password change.

Do you know how to modify FreeIPA user passwords using an LDAP batch modification?

NamoDev commented 6 years ago

Hello @stevebauman, I'll have to check - I'm pretty new to FreeIPA as well. From what I've tried there seems to be no editable "password" field to be modified through a LDAP batch modification, but there has to be one somewhere...

stevebauman commented 6 years ago

No problem @NamoDev, thanks for looking into this. I know ActiveDirectory and OpenLDAP have a unicodepwd field that isn't present in attributes returned by records, but changes passwords when passed into a batch modification, but I can't find if FreeIPA has this functionality / compatibility?

NamoDev commented 6 years ago

Based on what I could find here and what I've got from tinkering around is that there's a field called userpassword, which isn't present in attributes returned, but when set to a password string will allow users to log in with that new password. Here's the code I used for that:

$theUser = Adldap::search()->users()->where("uid", "=", Session::get("username"))->first();
$theUser->userpassword = $request->new_password;
$theUser->save();

However, it's a bit strange that after "changing" the password, the user will be able to log in with both the old password AND the new password. This is definitely something that needs more research.

Additional Data: Here's the complete LDAP data of the user, dumped from the FreeIPA server itself (some info omitted):

[namo@ipa-dev-1 ~]$ ldapsearch -D "cn=Directory Manager" -x -b "uid=lena,cn=users,cn=accounts,dc=test,dc=overwatch,dc=int" -W
Enter LDAP Password: 

dn: uid=lena,cn=users,cn=accounts,dc=test,dc=overwatch,dc=int
displayName: Lena Oxton
uid: lena
krbCanonicalName: lena@TEST.OVERWATCH.INT
objectClass: ipaobject
objectClass: person
objectClass: top
objectClass: ipasshuser
objectClass: inetorgperson
objectClass: organizationalperson
objectClass: krbticketpolicyaux
objectClass: krbprincipalaux
objectClass: inetuser
objectClass: posixaccount
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
loginShell: /bin/sh
initials: LO
gecos: Lena Oxton
sn: Oxton
homeDirectory: /home/lena
mail: lena@test.overwatch.int
krbPrincipalName: lena@TEST.OVERWATCH.INT
givenName: Lena
cn: Lena Oxton
userPassword:: -- some long hash --
userPassword:: -- some long hash --
krbPrincipalKey:: -- some long hash --
krbPasswordExpiration: 20171213195001Z
krbLastPwdChange: 20171213195001Z
krbExtraData:: -- some long hash --
mepManagedEntry: cn=lena,cn=groups,cn=accounts,dc=test,dc=overwatch,dc=int
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=test,dc=overwatch,dc=int
krbLastSuccessfulAuth: 20171213195029Z
krbLoginFailedCount: 0
krbLastFailedAuth: 20171213194905Z

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

It appears that the userpassword attribute is somehow not over-writable, as there seems to be two userpassword attributes (each with different hashes). The good thing I found out is that FreeIPA will automatically hash plaintext passwords passed into that attribute.

stevebauman commented 6 years ago

Thanks @NamoDev for looking into this. Since it's just an attribute you can set and update, can you try the following?

$user->userpassword = 'password';

$user->save();

This should update their password. Give it a go!

NamoDev commented 6 years ago

@stevebauman Sorry for the delay, but I tried re-running this code again:

$theUser = Adldap::search()->users()->where("uid", "=", Session::get("username"))->first();
$theUser->userpassword = $request->new_password;
$theUser->save();

And the result remains the same. The old "userpassword" attribute still persists, and the second one is created when the user is saved (effectively the user will now have two valid passwords), which is kinda weird...

stevebauman commented 6 years ago

@NamoDev I've heard this before with FreeIPA, but unfortunately I won't be able to assist you much in this matter (can't even find documentation online about changing passwords in FreeIPA).

I'll leave this issue open in case others are knowledgeable and know how to perform resets in this LDAP distro.