DirectoryTree / LdapRecord-Laravel

Multi-domain LDAP Authentication & Management for Laravel.
https://ldaprecord.com/docs/laravel/v3
MIT License
509 stars 54 forks source link

Server is unwilling to perform when assigning UAC (ActiveDirectory) #450

Closed sazanof closed 2 years ago

sazanof commented 2 years ago

Environment:

Hello! =)

I configured ldap record to use a secure connection (ssl) to create users and manage passwords and ran into the following problem: a user is being created, but I can't install UAC. Maybe I'm doing something wrong, but nevertheless, I will be glad if you help or check.

$ldapConnection = ConnectionController::connection();
$userFromLdap = (new LdapUser)->inside(config('ldap.connections.default.base_dn'));
$userFromLdap->cn = $data['fullname'];
$userFromLdap->samaccountname = $data['username'];
$userFromLdap->unicodePwd = $data['password'];
$userFromLdap->displayname = $data['fullname'];
$userFromLdap->givenname = $data['givenname'];
$userFromLdap->sn = $data['sn'];
$userFromLdap->userprincipalname = $data['email'];
$userFromLdap->mail = $data['email'];
$userFromLdap->title = $data['position'];
$userFromLdap->department = $data['department'];
$userFromLdap->telephonenumber = $data['telephonenumber'];

$ldapConnection return the new connection (ssl to win srv 2008 r2) of admin, that can add users (with stay bound option)

So, this part upon and below works.

//.........
try {
    $userFromLdap->save();
    // ................ works, create disabled user on AD

BUT this - do not:

    // ........... after $userFromLdap->save();
    $userFromLdap->refresh();
    $uac = new AccountControl();
    $uac->accountIsNormal();
    $uac->passwordDoesNotExpire();
    $uac->passwordCannotBeChanged();
    $userFromLdap->userAccountControl = $uac;
    $userFromLdap->save();

also Im trying just $userFromLdap->userAccountControl = 512; - do not work too

Catch an error "Server is unwilling to perform" Thank You! =)

stevebauman commented 2 years ago

Hi @sazanof,

Can you post your connection configuration with any sensitive details omitted (password etc.)?

sazanof commented 2 years ago

@stevebauman .env

LDAP_CONNECTION=default
LDAP_CONNECTIONS=default,shared,groups
LDAP_DEFAULT_HOSTS=my.ad.host
LDAP_DEFAULT_USERNAME=CN=ldapreader,OU=SystemUsers,OU=MyOU,DC=dc,DC=org,DC=ru
LDAP_DEFAULT_PASSWORD=superPassOfReaderUser
LDAP_DEFAULT_PORT=636
LDAP_DEFAULT_BASE_DN=CN=Users,DC=dc,DC=org,DC=ru
LDAP_DEFAULT_TIMEOUT=5
LDAP_DEFAULT_SSL=true
LDAP_DEFAULT_TLS=false

programaticaly in initialize method

$connection = new Connection([
            'hosts' => config('ldap.connections.default.hosts'),
            'username' => $dn,
            'password' => $password,
            'use_ssl' => true
        ]);

try {
         $connection->connect();
            return $connection;
        } catch (\Exception $exception) {
            return null;
      }

in connection method

$connection = self::initialize($credentials[0], $credentials[1]);
try {
    if ($connection->auth()->attempt($credentials[0], $credentials[1], true)) {
        Container::addConnection($connection, $connectionName);
        return $connection;
    }
} catch (\Exception $exception) {
    return null;
}

I use this addition connection so that an authorized administrator in the admin panel can enter confirmation of the action (for example, when creating a user, enter the password from the current administrator to continue execution)

sazanof commented 2 years ago

@stevebauman

$modification = $userFromLdap->getModifications();
var_dump($modification);die;

image Strangely, after the first save() and refresh() methods, there are 2 modifications - password and uac. For some reason I thought there would be one, since I thought that the password modification was applied after save&refresh

sazanof commented 2 years ago

@stevebauman

Cool. This is the magic of your repository! While reading your documentation and checking my code at the same time, I remembered that I changed the password security policy on AD.

And my password didn't meet the security requirements. Solution: enter a password that meets the security requirements =)

Now we need to think through the rest of the exception handling logic in order to notify admins about this via the web interface.

stevebauman commented 2 years ago

Excellent, I'm glad you were able to resolve it @sazanof. Appreciate you posting the solution here 👍