richardun / active_directory

Native Ruby Access to Microsoft Active Directory
http://rubyforge.org/projects/activedirectory
12 stars 8 forks source link

"memberof" attribute very slow #15

Open acaeti opened 10 years ago

acaeti commented 10 years ago

Hello

It seems the "memberof" attribute is slow. For example, if I do this:

aduser = ActiveDirectory::User.find(:first, :samaccountname => "something") aduser.memberof

Depending on the number of groups the user is a member of, this can be super slow. I had tried this with caching (and performed my User.find against a distinguished name) but it was still pretty slow.

Is there any way to speed this up?

richardun commented 10 years ago

Hi Nick,

This may not be helpful, but what might be happening is that it's not only fetching the group DN's, but all data related to those groups, so it may be fetching all of the users related to those groups.

If you're checking to see who is a member of a group, it should be faster to put that into a filter:

filter = Net::LDAP::Filter.eq('memberOf', group_dn_string) ActiveDirectory::Base.setup(settings) # settings I store in config people_from_ad = ActiveDirectory::User.find(:all, filter)

May not be the answer you were looking for, but hope that helps.

R

On Fri, Jun 6, 2014 at 4:26 PM, Nick M notifications@github.com wrote:

Hello

It seems the "memberof" attribute is slow. For example, if I do this:

aduser = ActiveDirectory::User.find(:first, :samaccountname => "something") aduser.memberof

Depending on the number of groups the user is a member of, this can be super slow. I had tried this with caching (and performed my User.find against a distinguished name) but it was still pretty slow.

Is there any way to speed this up?

— Reply to this email directly or view it on GitHub https://github.com/richardun/active_directory/issues/15.

acaeti commented 10 years ago

Hello Richard

Yeah, I agree with your analysis. I am seeing this slowness in the context of using the group.add(user) functionality - part of that method includes pulling user.memberof data. Running a group.add(user) gets slow when the user is already in many AD groups, and running it over many users can really add up.

But your filter advice is definitely good for other situations :).

Thanks for replying!

richardun commented 10 years ago

I loved using this before Rails 3 because it was so much more like the ActiveRecord interface. It just needs a serious refactoring. Not only to provide an interface more like that or Rails 3 or 4 (not using the (:all) or (:first) parameters for instance, but also to make the backend code which is really using Net/Ldap to be much more optimized. Any small needs for AD interaction in my Rails 4 apps, I've just used straight Net/Ldap. The uses have been small if at all, so it was easy to add a filter here or there.

The group add code is pretty simple:

    def add(new_member)
        return false unless new_member.is_a?(User) || new_member.is_a?(Group)
        if @@ldap.modify(:dn => distinguishedName, :operations => [
            [ :add, :member, new_member.distinguishedName ]
        ])
            return true
        else
            return has_member?(new_member)
        end
    end

_https://github.com/richardun/active_directory/blob/master/lib/active_directory/group.rb#L56 https://github.com/richardun/active_directory/blob/master/lib/active_directory/group.rb#L56_

I am not sure why this is slow if it's adding the user and actually sending the @@ldap.modify command. I can see it being slow if that fails and then it checks to see if it has_member? (ie. then looking through all those groups).

Anyway, that's not terribly more helpful. I guess I would try to run the modify command myself in the code instead of using this gem just to see if that is taking a long time. If so, there's not a lot the gem can do if that's taking a long time, I'm afraid.

Good luck! And please do let me know what happens! R

On Fri, Jun 6, 2014 at 4:40 PM, Nick M notifications@github.com wrote:

Hello Richard

Yeah, I agree with your analysis. I am seeing this slowness in the context of using the group.add(user) functionality - part of that method includes pulling user.memberof data. Running a group.add(user) gets slow when the user is already in many AD groups, and running it over many users can really add up.

But your filter advice is definitely good for other situations :).

Thanks for replying!

— Reply to this email directly or view it on GitHub https://github.com/richardun/active_directory/issues/15#issuecomment-45387208 .