Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change LDAP password #54

Open
fslozano opened this issue Apr 27, 2015 · 25 comments
Open

Change LDAP password #54

fslozano opened this issue Apr 27, 2015 · 25 comments

Comments

@fslozano
Copy link

Currently AuthLDAP simply hides the change password option from a LDAP user profile. Would it be too hard to make AuthLDAP change the user password on LDAP? A bonus would be to implement "forgot my password" for LDAP users also.

@fslozano fslozano changed the title Change password from LDAP Change LDAP password Apr 27, 2015
@heiglandreas
Copy link
Owner

Not really an easy one as there is no default way to change a users password in LDAP.

Well, of course you can use ldap_mod_replace to change an attribute and a password is nothing else than an attribute. But how is the password stored in the LDAP? Encrypted I suppose, but how? And is there possibly more than one field to update using different encryptions?

In all setups that I have seen so far there was a central piece of software (mostly a website) where the user could change it's password for the LDAP. We could add a config-option that holds a link to such a password-change site and display that link instead of the password-fields in the backend. But I think everything else wouldn't really work smoothly. But I'm open for suggestions there 😉

@fslozano
Copy link
Author

I was not aware this would be hard... but see from "man ldappasswd" which is part of openldap-clients:

"ldappasswd is a tool to set the password of an LDAP user. ldappasswd uses the LDAPv3 Password Modify (RFC 3062) extended operation."

So it seems there is a standard password change operation. Maybe it's not supported by some products like MSAD. Maybe not supported by PHP LDAP client library.

I guess it would be possible to support a few common cases like OpenLDAP and FreeIPA with inetOrgPerson / posixUserAccount, Samba3 PDC + OpenLDAP or MSAD. Those looks like are well documented.

Anyway a google search for "php ldap change password" shows promising results.

@chaplina
Copy link

I consider this outside the scope of the functionality provided by this plugin.

Changing the LDAP password should be handled via another plugin or an
external application.

On 04/27/2015 11:18 AM, fslozano wrote:

I was not aware this would be hard... but see from "man ldappasswd" which is
part of openldap-clients:

"ldappasswd is a tool to set the password of an LDAP user. ldappasswd uses
the LDAPv3 Password Modify (RFC 3062) extended operation."

So it seems there is a standard password change operation. Maybe it's not
supported by some products like MSAD. Maybe not supported by PHP LDAP client
library.

I guess it would be possible to support a few common cases like OpenLDAP and
FreeIPA with inetOrgPerson / posixUserAccount, Samba3 PDC + OpenLDAP or
MSAD. Those looks like are well documented.

Anyway a google search for "php ldap change password" shows promising results.


Reply to this email directly or view it on GitHub
#54 (comment).

@heiglandreas
Copy link
Owner

The scope of this plugin is to authenticate against an LDAP, not to change the LDAP. That's the scope of dedicated tools like phpmyldap or gosa.

Why?

ldappasswd is a tool that can be used to change the password on the commandline. But from a webserver running PHP there is only a slight possibility to use the exec-functions to use that commandline-tool to change the password. That might not be possible as exec is often either completely blocked or at least very restricted. And it only works together with OpenLDAP-backends whereas a great part of LDAP-Servers we authenticate against are ADs.

So the only other option would be to use a function provided by the PHP-library which is only the ldap_mod_replace to change ay attribute-value. There is no way of directly changing the password.

And last but not least, on changing the password one would have to check al the possible password-policies that can be set, different encryption/hashing-algoriithms, different attributes to store differently hashed stuff in. Thats so many variables that the possibility that the organization already thought of that and has an already implemented way to change a password is so high, that it doesn't make sense to add this to the plugin.

As already states, adding a link to such a password-changing website would be possible and I would add that. Everything else is in my eyes out of scope.

@fslozano
Copy link
Author

Are chaplina and heiglandreas the same person?

I understand a feature may not be a interesting for the developer, but asking won't hurt. ;-) And a little exchange of ideas can help the developer make its mind or help someone else who would be interested in implementing the feature.

Yes it could be done by an external program. But the user experience would not be good, if wordpress is intended to be the "face" of the organization. Not to mention installing, integrating, configuring the external program.

Some directories (ex: OpenLDAP) provide no web interface for an end-user, only CLI tools for administrators. Others (ex: FreeIPA) provide a web interface which is useful only for internal users like sysadmins, not for end-users, specially those outside the organization.

So IMHO it would be nice having AuthLDAP handing this. But I respect other's opinions and I apologize if this is not the proper forum for discussing such feature viability, even if it's for the sake of someone else picking up the idea.

@chaplina
Copy link

LOL! I (chaplina) am just a very satisfied user of this plugin.

Andreas is a plugin developer/programmer.

My statement regarding your request, while short (I'm responding at work!!),
should not be regarded as dismissive.

I simply believe that when one uses LDAP, there are likely multiple
applications which use it for authentication, and adding one more for LDAP
password/profile management is not taboo. :)

Adding this functionality to this plugin is no easy task and can introduce
other config options (like enforcing password complexity/rules) which can
make code maintenance burdensome.

On 04/27/2015 11:40 AM, fslozano wrote:

Are chaplina and heiglandreas the same person?

I understand a feature may not be a interesting for the developer, but
asking won't hurt. ;-) And a little exchange of ideas can help the developer
make its mind or help someone else who would be interested in implementing
the feature.

Yes it could be done by an external program. But the user experience would
not be good, if wordpress is intended to be the "face" of the organization.
Not to mention installing, integrating, configuring the external program.

Some directories (ex: OpenLDAP) provide no web interface for an end-user,
only CLI tools for administrators. Others (ex: FreeIPA) provide a web
interface which is useful only for internal users like sysadmins, not for
end-users, specially those outside the organization.

So IMHO it would be nice having AuthLDAP handing this. But I respect other's
opinions and I apologize if this is not the proper forum for discussing such
feature viability, even if it's for the sake of someone else picking up the
idea.


Reply to this email directly or view it on GitHub
#54 (comment).

@heiglandreas
Copy link
Owner

HI @fslozano . No, me and @chaplina are not the same person 😉

And I can understand your idea very well. Having "Once face to the customer" is a great idea! But for me the scope of a plugin should do one thing but that as good as possible. This plugin tries to do authentication a user against an LDAP as good as possible. Changing a users password in LDAP is a completely different story, another scope. Therefore I'd say it's a completely different plugin if you want to do that in wordpress. I know Sysadmins that would go berserk on the sheer idea of that. It's a matter of security they do not want to be given out of hands. And as it's a matter of company-wide security I can only advise anyone to consult a security expert on that one. I'm not that person. Therefore I don't want to (and won't) mess with that.

Admins can use and setup different GUIs to allow users to change passwords. One of the most well known ones is the change password-function on your computers user-preferences. In most enterprise environments changing the password on your machine changes the password in the LDAP and triggeres everything necessary. Alternate options would be WebInterfaces like GOsa or phpLdapAdmin. A third alternative would be to create a webapplication solely for changing passwords. But I do not know one out-of-the-box solution for that.

PS: There was surely no offence meant by any comments I made.

Cheers! And thank you for giving me the opportunity to overthink my opinions on that matter. Very much apprechiated.

@heiglandreas
Copy link
Owner

@chaplina Thanks for the kind words 😄

@fslozano
Copy link
Author

Hi chaplina, when you told it was outside the scope you told with such an authority it looked like an "official" statement by the developer. So far I'm also very satisfied with the plugin, it's the best I could find. :-)

I'll research what self-service end-user options I can find and maybe provide feedback on this github issue. Unfortunately phpLdapAdmin and GOsa look like sysadmin tools, not something I'd expose to end users.

My users are external to my organization, so the regular OS change password will no work. There'll be other web apps besides wordpress using the same LDAP directory for users, password and roles, but something has to provide those users the ability to change and reset their password... besides setting it on first access (registration). So far I found no wordpress plugin for that. :-(

I really wanted to avoid extensive custom development or having to make two different apps look the same... but do not want to start wordpress without ldap, it'll be harder to integrate later (when the second web app goes live) than now!

@wtfiwtz
Copy link

wtfiwtz commented Jul 29, 2015

This works with OpenLDAP (using MD5 hashes)...

function authLdap_passwordReset($user, $password) {

    $ldap_rdn = 'cn=admin,dc=company,dc=com';
    $ldap_pw = 'adminpw';
    $ldap_orgunit = 'ou=people,dc=company,dc=com';

    $ldap_conn = ldap_connect("ldap://id.company.com", 389);
    if ($ldap_conn) {
        ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, 3);
        $ldap_bind = ldap_bind($ldap_conn, $ldap_rdn, $ldap_pw);
        if ($ldap_bind) {

            // Check to see if the user exists
            $searched = ldap_search($ldap_conn, $ldap_orgunit, 'cn=' . $user->user_login, array('cn'));
            if (!$searched) {
                authLdap_debug("User does not exist: " . $user . " in LDAP server");
                ldap_close($ldap_conn);
                return null;
            }

            $entries = ldap_get_entries($ldap_conn, $searched);
            if ($entries['count'] != 1) {
                authLdap_debug("User does not exist, or more than 1 user with this login: " . $user . " in LDAP server");
                ldap_close($ldap_conn);
                return null;
            }


            // Overwrite the user's password
            $ldap_entry = array();
            $ldap_entry['userPassword'] = '{MD5}' . base64_encode(pack('H*',md5($password)));

            $added = ldap_modify($ldap_conn, "cn=" . $user->user_login . ',' . $ldap_orgunit, $ldap_entry);
            if (!$added) {
                authLdap_debug("Cannot reset password for user " . $user->user_login . " in LDAP server");
                ldap_close($ldap_conn);
                return null;
            }

        } else {
            authLdap_debug("Cannot bind to LDAP server with admin account");
            ldap_close($ldap_conn);
            return null;
        }

    } else {
        authLdap_debug("Cannot connect to LDAP server with admin account");
        ldap_close($ldap_conn);
        return null;
    }

    ldap_close($ldap_conn);
    return $data;
}

add_action('password_reset', 'authLdap_passwordReset', 10, 2);

See also #65

@heiglandreas
Copy link
Owner

Hi @wtfiwtz. Thanks for the contribution of a working password-reset script.

But as stated earlier changing passwords is Out-Of-Scope for the authLdap-plugin. Changing passwords in an LDAP is a complex task involving password-policies, possibly multiple password fields, different password-hashing algorithms etc. It's not complex from the programming POV but from the underlying workflow POV. And that's why I won't implement it in this plugin.

But I'll leave this as a reference for users that want to implement it on their own! Therefore Thanks for your time and effort for this contribution!

@wtfiwtz
Copy link

wtfiwtz commented Jul 29, 2015

@heiglandreas no probs... hope this helps someone else.

@heiglandreas
Copy link
Owner

I hope so too! That's why I want it to stay open 😉

I will later link it also from the README to make it accessible more easily!

@couling
Copy link

couling commented Aug 22, 2017

Its a pity this is out of scope since from a user perspective it's less obvious why this should be the case. I'm not arguing against the developer logic though, including it could increase the development size many times over.

@wtfiwtz Have you considered wrapping this code into its own plugin. That way the code can be made easily available to those of us it would help.

@heiglandreas
Copy link
Owner

@couling This depends on whether the wordpress-instance is the ONLY connection of the users to the LDAP. Because usually there are a lot of services that are affected by changing the password like email, computer-logins, login to different other company services…

What I could think of would be to have a hook that rewrites the link to the password-change so that it redirects the user to an interface where the LDAP-Password can be changed…

@couling
Copy link

couling commented Aug 22, 2017

In another world, other apps than wordpress (including nextcloud) have got round this by flagging individual users as being provided by LDAP so that non-ldap users aren't affected. If it depends the configuration of the wordpress instance then its a matter for configuration options and not scope. But that's as argumentative as I'm going to be on the subject. :-)

Yes other Wordpress plugins have just given a different link like you suggest.

@heiglandreas
Copy link
Owner

heiglandreas commented Aug 22, 2017

authLDAP actually flags users as LDAP-users and hides the password-change-button in the interface. Doesn't work though for the lost-password link as the user usually isn't logged in at that moment…

So you can only change the "lost-password"-link for all users…

I might add that as an option though…

@bilbo-the-hobbit
Copy link

Hello,

yes never change something in a application and hope it will work elsewhere :) The idea to have a hook to be able to send the user to the password changing interface could be a nice idea.

Cheers

@couling
Copy link

couling commented Aug 22, 2017

@bilbo-the-hobbit Yes I agree hope is bad currency in software.
Standards on the other hand... https://tools.ietf.org/html/rfc3112

@tareko
Copy link

tareko commented Mar 13, 2019

Hello all,

I was wondering if there's been any movement on this. I'm happy to contribute to a programmer who wants to make this feature, as authLDAP is almost perfect otherwise. Even if it's technically 'adjacent', this really is an important part of this type of plugin to create an ldap system that works and is as transparent to users as possible.

For our instance, we use multiple sites with openLDAP as the backend for auth, and our WP site as the main user-facing site / hub. I expect others have this configuration too.

Modifying other attributes would be fantastic too

tarek : )

@heiglandreas
Copy link
Owner

Changing the LDAP password or any other attribute inside LDAP is no in the scope of this plugin. This plugin merely handles authentication against an LDAP backend. Nothing more but also nothing less!

Whoever wants to create a plugin that handles password-changes or merging more attribute feel free to do so and I'm more than happy to help when questions pop up. But not within this plugin.

@couling
Copy link

couling commented Mar 15, 2019

I actually looked into doing just that and discovered Wordpres's own code makes it impossible because one of the pluggable functions is circumvented where it shouldn't be. I opened a ticket against the issue on wordpress. If I ever get the time I'll write a pull request that fixes it. But for now, its possible to write something which catches the lost password reset, but not the user resetting their own password in their profile config.

@fernwerker
Copy link

So you can only change the "lost-password"-link for all users…

That would be really great and a lot easier to maintain than the "change password feature".
You could use something like: https://github.com/ltb-project/self-service-password

@LSCOBAIT
Copy link

just joining the fray, authLDAP works with my OpenLDAP, however when I try wtfiwtz's addition, the password in OpenLDAP is not changed, with some debug it appears the WP password_reset action is not fired? may be that's what @couling discovered? may I know if there is any update on that?

@oznerol-wp
Copy link

This works with OpenLDAP (using MD5 hashes)...

function authLdap_passwordReset($user, $password) {

    $ldap_rdn = 'cn=admin,dc=company,dc=com';
    $ldap_pw = 'adminpw';
    $ldap_orgunit = 'ou=people,dc=company,dc=com';

    $ldap_conn = ldap_connect("ldap://id.company.com", 389);
    if ($ldap_conn) {
        ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, 3);
        $ldap_bind = ldap_bind($ldap_conn, $ldap_rdn, $ldap_pw);
        if ($ldap_bind) {

            // Check to see if the user exists
            $searched = ldap_search($ldap_conn, $ldap_orgunit, 'cn=' . $user->user_login, array('cn'));
            if (!$searched) {
                authLdap_debug("User does not exist: " . $user . " in LDAP server");
                ldap_close($ldap_conn);
                return null;
            }

            $entries = ldap_get_entries($ldap_conn, $searched);
            if ($entries['count'] != 1) {
                authLdap_debug("User does not exist, or more than 1 user with this login: " . $user . " in LDAP server");
                ldap_close($ldap_conn);
                return null;
            }


            // Overwrite the user's password
            $ldap_entry = array();
            $ldap_entry['userPassword'] = '{MD5}' . base64_encode(pack('H*',md5($password)));

            $added = ldap_modify($ldap_conn, "cn=" . $user->user_login . ',' . $ldap_orgunit, $ldap_entry);
            if (!$added) {
                authLdap_debug("Cannot reset password for user " . $user->user_login . " in LDAP server");
                ldap_close($ldap_conn);
                return null;
            }

        } else {
            authLdap_debug("Cannot bind to LDAP server with admin account");
            ldap_close($ldap_conn);
            return null;
        }

    } else {
        authLdap_debug("Cannot connect to LDAP server with admin account");
        ldap_close($ldap_conn);
        return null;
    }

    ldap_close($ldap_conn);
    return $data;
}

add_action('password_reset', 'authLdap_passwordReset', 10, 2);

See also #65

hi, this is still work? how can we integrate it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants