2

I would like to change the password of a user in AD since there are no attribute for password in AD.

Currently running laravel framework with Adldap2-laravel package in order to manage ADLDAP operations.

Here's my ldap_auth.php

<?php

return [
    'connection' => env('LDAP_CONNECTION', 'default'),
    'provider' => Adldap\Laravel\Auth\DatabaseUserProvider::class,
    'model' => App\User::class,
    'rules' => [
        Adldap\Laravel\Validation\Rules\DenyTrashed::class,
    ],
    'scopes' => [
        Adldap\Laravel\Scopes\UidScope::class
    ],
    'identifiers' => [
        'ldap' => [
            'locate_users_by' => 'uid',
            'bind_users_by' => 'dn',
        ],
        'database' => [
            'guid_column' => 'objectguid',
            'username_column' => 'username',
        ],
        'windows' => [
            'locate_users_by' => 'samaccountname',
            'server_key' => 'AUTH_USER',
        ],
    ],
    'passwords' => [
        'sync' => env('LDAP_PASSWORD_SYNC', false),
        'column' => 'password',
    ],
    'login_fallback' => env('LDAP_LOGIN_FALLBACK', false),
    'sync_attributes' => [
        'username' => 'uid',
        'password' => 'userPassword',
        'name' => 'cn',
        'role' => 'l',
        'category' => 'businessCategory',
        'telephone_number' => 'telephoneNumber',
        'email' => 'mail'

    ],
    'logging' => [

        'enabled' => env('LDAP_LOGGING', true),

        'events' => [

            \Adldap\Laravel\Events\Importing::class                 => \Adldap\Laravel\Listeners\LogImport::class,
            \Adldap\Laravel\Events\Synchronized::class              => \Adldap\Laravel\Listeners\LogSynchronized::class,
            \Adldap\Laravel\Events\Synchronizing::class             => \Adldap\Laravel\Listeners\LogSynchronizing::class,
            \Adldap\Laravel\Events\Authenticated::class             => \Adldap\Laravel\Listeners\LogAuthenticated::class,
            \Adldap\Laravel\Events\Authenticating::class            => \Adldap\Laravel\Listeners\LogAuthentication::class,
            \Adldap\Laravel\Events\AuthenticationFailed::class      => \Adldap\Laravel\Listeners\LogAuthenticationFailure::class,
            \Adldap\Laravel\Events\AuthenticationRejected::class    => \Adldap\Laravel\Listeners\LogAuthenticationRejection::class,
            \Adldap\Laravel\Events\AuthenticationSuccessful::class  => \Adldap\Laravel\Listeners\LogAuthenticationSuccess::class,
            \Adldap\Laravel\Events\DiscoveredWithCredentials::class => \Adldap\Laravel\Listeners\LogDiscovery::class,
            \Adldap\Laravel\Events\AuthenticatedWithWindows::class  => \Adldap\Laravel\Listeners\LogWindowsAuth::class,
            \Adldap\Laravel\Events\AuthenticatedModelTrashed::class => \Adldap\Laravel\Listeners\LogTrashedModel::class,

        ],
    ],

];

Here is my LdapController.php where I include function to reset password

public function resetPassword(Request $req)
    {
        $req->validate([
            'userid' => 'required',
            'password' => 'required|min:6|confirmed'
        ]);
        $userLdap = Adldap::search()->where('uid', $req->userid)->firstOrFail();
        $newPassword = "{SHA}" . base64_encode(pack("H*", sha1($req->password)));
        $res = $userLdap->update([
            'userpassword' => $newPassword
        ]);

        //Force change AD Password
        // $adPassword = str_replace("\n", "", shell_exec("echo -n '\"" . $req->password . "\"' | recode latin1..utf-16le/base64"));
        // $provider = Adldap\Models\User::connect('ad');
        // $dn = $provider->search()->where('cn', $req->userid)->get();
        // $res = $dn->setPassword($adPassword);

        if ($res) {
            return back()->withSuccess('<strong>Success!</strong> Your password has been changed');
        } else {
            return back()->withErrors('<strong>Failed!</strong> Your password was unable to changed');
        }
    }

Unfortunately $res = $dn->setPassword($adPassword); returns error 'Method Adldap\Query\Collection::setPassword does not exist.'

Haziq Asyraff
  • 37
  • 1
  • 5
  • You tagged both Active Directory and OpenLDAP. Which one are you actually using? – Gabriel Luci Oct 31 '19 at 16:01
  • I'm trying to use both, since both contains user information, if changing LDAP password, I must force reset also the AD password. – Haziq Asyraff Oct 31 '19 at 16:14
  • I think you will have to be aware of which one you're using. Active Directory, for example, doesn't use the `uid` attribute (it exists, just isn't used). The username used for logging in is the `sAMAccountName` attribute. That might be part of your problem if you're testing this against Active Directory. – Gabriel Luci Oct 31 '19 at 16:19

1 Answers1

1

I found an example here when I searched Google for "Adldap2-laravel change password".

$user = Adldap::users()->find('jdoe');

if ($user instanceof Adldap\Models\User) {
    $oldPassword = 'password123';

    $newPassword = 'correcthorsebatterystaple';

    $user->changePassword($oldPassword, $newPassword);
}

If you want to reset the password, then it seems like this should work:

$user->setPassword("correcthorsebatterystaple");
$user->save();

If you want to know what's going on underneath, or how it can be done without Adldap2-laravel:

The attribute is unicodePwd. You can either "change" the password, or "reset" it.

Changing the password requires knowing the old password. This is what a user would do themselves.

Resetting a password requires the "Reset password" permission on the account, which is usually given to administrative accounts.

The documentation for unicodePwd tells you how to do both. For a "change", you send a delete instruction with the old password and an add instruction with the new one, all in the same request.

For a reset, you send a single replace instruction.

In both cases, the passwords have to be sent in a specific format.

The PHP documentation for 'ldap_modify_batch` shows an example of how to change a password.

On the documentation page for ldap_mod_replace, there is a comment that shows you how to reset a password.

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84