Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetGroupsOfUser() for Active Directory database #13

Open
PlkMarudny opened this issue May 28, 2018 · 9 comments
Open

GetGroupsOfUser() for Active Directory database #13

PlkMarudny opened this issue May 28, 2018 · 9 comments

Comments

@PlkMarudny
Copy link

What would be the GroupFilter in that case? User filter is "(sAMAccountName=%s)", BTW

@arpachuilo
Copy link

arpachuilo commented Jul 3, 2018

Using this in a project I'm working on with AD and this took me a bit to find out.

"(&(member=%s)(objectClass=group))" where "%s" is the user distinguished name -- I just grabbed the user dn from the attributes once they were authenticated. Hope this helps.

@eklein
Copy link

eklein commented Jan 18, 2019

I'm trying to use AD for authorization only.. I bind as a read-only user to query the list of groups a user is in, and I'm having a heck of a time getting the GroupFilter written properly to get anything but an empty set of groups. If you have a code example of how you're making this work, I would be very grateful, @arpachuilo!

@arpachuilo
Copy link

@eklein I've changed jobs since then, so I don't have access to the codebase to share a snippet -- nor do I remember what I did.

I hazily remember using "(&(member=%s)(objectClass=group))" as the GroupFilter. Then I guess beyond that when calling GetGroupsOfUser I passed in the user distinguished name of the user. Do not remember how I was getting a hold of the user DN beyond recreating it because I don't think I was doing Authentication either. I just remember the DN being essential to getting groups properly.

Not much, but hope this helps.

@Joffcom
Copy link

Joffcom commented Jan 21, 2019

I thought I had cracked this with (&(member=%s)(objectCategory=group)) then passing the sAMAccount name but then I noticed I was using the DN.

Time to create a quick helper function to grab the DN I guess

@Joffcom
Copy link

Joffcom commented Jan 21, 2019

@eklein My GetGroupsOfUser is now working using the modified version below, Give it a go and see if it works for you. It could do with a bit of cleanup but should get you started.

// GetGroupsOfUser returns the group for a user.
func (lc *LDAPClient) GetGroupsOfUser(username string) ([]string, error) {
	err := lc.Connect()
	if err != nil {
		return nil, err
	}
	defer lc.Close()

	// First Bind with read only user
	if lc.BindDN != "" && lc.BindPassword != "" {
		err = lc.Conn.Bind(lc.BindDN, lc.BindPassword)
		if err != nil {
			return nil, err
		}
	}

	// Get the users DN
	// Search for the given username
	searchRequest := ldap.NewSearchRequest(
		lc.Base,
		ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
		fmt.Sprintf(lc.UserFilter, username),
		[]string{"dn"},
		nil,
	)

	sr, err := lc.Conn.Search(searchRequest)
	if err != nil {
		return nil, err
	}

	if len(sr.Entries) != 1 {
		return nil, errors.New("User does not exist")
	}

	userdn := sr.Entries[0].DN

	searchRequest = ldap.NewSearchRequest(
		lc.Base,
		ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
		fmt.Sprintf(lc.GroupFilter, userdn),
		[]string{"cn"}, // can it be something else than "cn"?
		nil,
	)
	sr, err = lc.Conn.Search(searchRequest)
	if err != nil {
		return nil, err
	}

	groups := []string{}
	for _, entry := range sr.Entries {
		groups = append(groups, entry.GetAttributeValue("cn"))
	}

	return groups, nil
}

@eklein
Copy link

eklein commented Jan 22, 2019

Wish I would have seen this about 10 minutes ago 😂. I just sat down and wrote a helper function to do the same. This indeed did work for me, though I wonder if this breaks things when using openldap. Need to look into that since I have a need to authenticate against both. Thank you both very much for your help! @arpachuilo @Joffcom

@eklein
Copy link

eklein commented Jan 24, 2019

To follow-up, it does indeed break when trying to authenticate against openldap. I'll need to rewrite things to support both based on whether it's openldap or AD.

kacpersaw added a commit to kacpersaw/go-ldap-client that referenced this issue Dec 26, 2019
@abolinhas
Copy link

Hi
@Joffcom your example don't return the primary groups, like "Users" or "Domain Users".
Any way to return all groups of a specific user including Primary Groups?
Best regards

@Joffcom
Copy link

Joffcom commented Sep 29, 2022

Good question @abolinhas, I have not really played with this for a couple of years now but I would have expected it to work with the primary group as well as the user would still be a member 🤔

I don't have an AD server to test against anymore either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants