Adldap2 / Adldap2-Laravel

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

Can not get all the users from AD group #757

Open oztinaz opened 5 years ago

oztinaz commented 5 years ago

Description:

I have an AD group with so many members (I don't know the exact amount but it's around 70k). I can get all users from cli via using ldapSearch and it takes 3-4 seconds but I need to get them in Laravel. I can get 2000 of the with the code below.

foreach ($this->adldap->getProviders() as $key => $provider) {
            /** @var Provider $provider */
            $adldapUsers = $provider->connect()->search()->users()->get();
        }

But of course I want to get them all. I've already tried https://github.com/Adldap2/Adldap2-Laravel/issues/82, https://github.com/Adldap2/Adldap2-Laravel/issues/624, https://github.com/Adldap2/Adldap2-Laravel/issues/333 and https://github.com/Adldap2/Adldap2/issues/590 solution offers, yet still couldn't find my way.

I've also tried the code below to get all users by their uidnumber, but actually I don't want to do that. I want something more accurate, more generic.

Initial values of $from and $to are respectively 0, 1000

foreach ($this->adldap->getProviders() as $key => $provider) {
            $counter = 0;
            $adldapUsers = [];
            while ($counter < 5) {
                /** @var Provider $provider */
                $tmp = $provider->connect()->search()->users()->whereBetween('uidnumber', [$this->from, $this->to]);
                if (empty($tmp)) {
                    $counter++;
                } else {
                    $counter = 0;
                }
                array_push($adldapUsers, $tmp);
                $this->from = $this->to + 1;
                $this->to *= 2;
            }
        }

Can you help me?

stevebauman commented 5 years ago

Hi @oztinaz,

It seems like you're running a standard user query - not one that is retrieving only members of a certain group.

It seems like your limit for results from AD is 2000 - can you try the following?

$group = $provider->search()->groups()->find('Group Name');

$users = $provider->search()->users()->whereMemberOf($group->getDn())->raw()->paginate(2000)->getResults();
oztinaz commented 5 years ago

Well, it didn't work for me. I replaced the 'Group Name' with my group name, it gets null. And I get my users from a single group.

stevebauman commented 5 years ago

You could also try retrieving users with a range() and limiting the amount of attributes returned so you don't run out of memory:

$step = 2000;
$total = 70000;

$range = range($step, $total, $step);

foreach ($range as $number) {
    $users = $ad->search()->users()
        ->select(['uid', 'mail'])
        ->whereBetween('uidnumber', [$number - $step, $number]);
        ->paginate($step)
        ->getResults();

    foreach ($users as $user) {
        // Do something with each user.
    }
}
stevebauman commented 5 years ago

Well, it didn't work for me. I replaced the 'Group Name' with my group name, it gets null. And I get my users from a single group.

Ok, try entering in the groups distinguished name yourself instead of trying to locate the group. Though if the DN you enter is incorrect, you won't receive any results:

$dn = 'cn=Group,dc=corp,dc=acme,dc=org';

$users = $provider->search()->users()->whereMemberOf($dn)->raw()->paginate(2000)->getResults();
oztinaz commented 5 years ago

Well, it didn't work for me. I replaced the 'Group Name' with my group name, it gets null. And I get my users from a single group.

Ok, try entering in the groups distinguished name yourself instead of trying to locate the group. Though if the DN you enter is incorrect, you won't receive any results:

$dn = 'cn=Group,dc=corp,dc=acme,dc=org';

$users = $provider->search()->users()->whereMemberOf($dn)->raw()->paginate(2000)->getResults();

I get an error as:

Type error: Argument 1 passed to Adldap\Query\Processor::Adldap\Query{closure}() must be an instance of Adldap\Models\Model, integer given

oztinaz commented 5 years ago

I've tried an alternative as this: $users = $provider->connect()->search()->rawFilter($ldapBackend->filter)->paginate(2000)->count(); It returns as 4986. But still it fails when I try for a larger group.