LdapRecord icon indicating copy to clipboard operation
LdapRecord copied to clipboard

[Bug] Can't set userAccountControl with v2.17 and above

Open klepptor opened this issue 2 years ago • 6 comments

Environment:

  • LDAP Server Type: ActiveDirectory
  • PHP Version: 8.1.4 / 8.1.11

Describe the bug:

After updating LdapRecord from 2.16 to v2.18 I couldn't create new users anymore with the following code:

    $user = new User();

    $user->givenname = $vorname;
    $user->sn = $nachname;
    // CN, DN oder samaccountname sind zwingend notwendig
    $user->cn = $vorname . " " . $nachname;
    // Standard PW, muss der Kennwortrichtlinie entsprechen, muss der User dann zurücksetzen
    $user->unicodepwd = 'PassPass233444';
    $user->userprincipalname = $upn;
    $user->telephonenumber = $telNr;
    $user->mail = $upn;

    $user->inside($userOU);

    // Sync the created users attributes.
    $user->refresh();

    // Enable the user.
    $user->userAccountControl = 512;
    //$user->userAccountControl = (new AccountControl)->accountIsNormal();

    $user->save();

Active Directory Server returns

Error Code: 53 ErrorMessage: Server is unwilling to perform DiagnosticMessage: 0000052D: SvcErr: DSID-031A126A, problem 5003 (WILL_NOT_PERFORM), data 0

I tried with all 2.17.x releases as well, same behaviour! Only 2.16.0 works...

klepptor avatar Oct 12 '22 11:10 klepptor

Hi @klepptor,

Are you sure this is an account control issue? Also, this line shouldn't work, as the user has not been created yet?

// Sync the created users attributes.
$user->refresh();

The only change to account creation between those two versions was to do with passwords:

https://github.com/DirectoryTree/LdapRecord/releases/tag/v2.17.2

stevebauman avatar Oct 12 '22 12:10 stevebauman

Hi @stevebauman

Frankly, I don't know. It's kind of weird...


   $user = (new User)->inside($userOU);

    $user->givenname = $vorname;
    $user->sn = $nachname;
    // CN, DN oder samaccountname sind zwingend notwendig
    $user->cn = $vorname . " " . $nachname;
    // Standard PW, muss der Kennwortrichlinie entsprechen, muss der User dann zurücksetzen
    $user->unicodepwd = 'Super123!';
    $user->userprincipalname = $upn;
    $user->telephonenumber = $telNr;
    $user->mail = $upn;

    $user->save();

    // Sync the created users attributes.
    $user->refresh();
    
    // Enable the user.
    $user->userAccountControl = 512;

    try {
        // TRY 1
        echo "TRY 1<p>";
        //$user->save();

        // Sync the created users attributes.
        // TRY 2
        echo "TRY 2<p>";
        $user->refresh();

        // TRY 3
        echo "TRY 3<p>";
        $userDN = $user->getDn();
        // TRY 4
        echo "TRY 4<p>";
        user_group_add($userDN,$ad_gruppen['Chat']);

        //$user->save();

    } catch (\LdapRecord\LdapRecordException $e) {
        // Failed saving user.

The original code works with 2.16. I changed it to consider your hint with $user->refresh(); but both snippets fail after TRY1 when calling $user->save(); after setting userAccountControl = 512:

klepptor avatar Oct 12 '22 14:10 klepptor

The original code works with 2.16. I changed it to consider your hint with $user->refresh(); but both snippets fail after TRY1 when calling $user->save(); after setting userAccountControl = 512:

If you do not set the userAccountControl on the user, are you able to create the user successfully?

stevebauman avatar Oct 12 '22 16:10 stevebauman

Yes, the user is created successfully. The code fails when calling $user->save(); after setting userAccountControl.

klepptor avatar Oct 12 '22 19:10 klepptor

Thanks @klepptor. Can you confirm if the password that you have set on the user during creation is properly set on the new user?

stevebauman avatar Oct 12 '22 20:10 stevebauman

Hi @stevebauman

I just tried to login with the new user (created with 2.18) after manually enabling the user. I unchecked the box to force the user to renew the password on first login (don't know if that's neccessary because I don't use the users for Windows login but for some web applications).

It did NOT work! So the password doesn't seem to be encoded/set correctly...

klepptor avatar Oct 13 '22 07:10 klepptor

Hmm I’m getting a conflicting report from #504.

Im going to see if I can set up a local AD instance with SSL enabled to test this myself before I reverse the change (unless you can provide a reproducible test case of course).

stevebauman avatar Oct 21 '22 07:10 stevebauman

Just to keep this updated:

I just tested v2.19 (although you didn't mention any changes concerning this bug), but it still doesn't work:

image

image

image

klepptor avatar Nov 08 '22 07:11 klepptor

Howdy! This smells familiar to issues I have experienced in the past testing OpenLDAP vs AD vs Okta/OneLogin/etc.

In certain configurations with TLS/SS, \ will act as an escape character and the binding will fail because the passwords are not matching on bind.

This is possible to validate by creating a user who's password includes a \ dnd executing a ldapsearch:

LDAPTLS_CACERT=/<path_to_cert>/<ca_certificate> ldapsearch -H ldaps://<ldap_server>:636 \
-D "<bind_dn>" -w <bind_password> -b <base_dn> "samaccountname=<user>".

-w "<bind_password>" may fail if the password contains certain characters. I've had bash scripts for testing that I've had to change to -w '''password''' because and situations where the service provider continued to work .

I digress; but it could be that the context has changed to facilitate a TLS/SSL implementation, where "password_phrase" string vs the "raw" password that is sent across using -W

I hope that helps! Keep up the great work my friend!

(Here's a similar situation: https://github.com/spring-projects/spring-security/issues/7741)

HinchK avatar Nov 09 '22 11:11 HinchK