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

Add ability to get groups from memberof attribute. #3902

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions connector/ldap/ldap.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ import (
type UserMatcher struct {
UserAttr string `json:"userAttr"`
GroupAttr string `json:"groupAttr"`
// Work only if UserAttr is 'memberOf' and GroupAttr is dn
GroupPrefix string `json:"groupPrefix"`
}

// Config holds configuration options for LDAP logins.
Expand Down Expand Up @@ -593,6 +595,49 @@ func (c *ldapConnector) groups(ctx context.Context, user ldap.Entry) ([]string,

var groups []*ldap.Entry
for _, matcher := range c.GroupSearch.UserMatchers {
// When we get groups from memberof user.s entity attribute, we may
// don.t want (Or don.t need) to perform extra search query for each group.
// Also when groupattr is dn (which implies memberof freeipa), we cannot use
// ldapsearch to retrieve group by DN (LDAP restriction)
if strings.ToLower(matcher.UserAttr) == "memberof" &&
strings.ToLower(matcher.GroupAttr) == "dn" {
for _, attr := range c.getAttrs(user, matcher.UserAttr) {
// If group dn has no ends with group search base dn - ignore it.
// In FreeIPA case, it also can contain hbac, sudo rules, etc...
if !strings.HasSuffix(attr, c.GroupSearch.BaseDN) {
continue
}

// Trim {NameAttr}= prefix and baseDN suffix to get group name.
// For NameAttr=cn and BaseDN=cn=groups,dc=example,dc=com :
// cn=groupname,cn=groups,dc=example,dc=com -> groupname
groupName := strings.TrimSuffix(
strings.TrimPrefix(attr,
fmt.Sprintf("%s=", c.GroupSearch.NameAttr)),
fmt.Sprintf(",%s", c.GroupSearch.BaseDN))

// Is it needed compability with GroupSearch.Filter? (r9odt)
if !strings.HasPrefix(groupName, matcher.GroupPrefix) {
continue
}

// Append result to group list as ldap.Entry to process it next wihtout
// extra changes in code.
groups = append(groups, &ldap.Entry{
DN: attr,
Attributes: []*ldap.EntryAttribute{
{
Name: c.GroupSearch.NameAttr,
Values: []string{
groupName,
},
},
},
})
}
continue
}

for _, attr := range c.getAttrs(user, matcher.UserAttr) {
filter := fmt.Sprintf("(%s=%s)", matcher.GroupAttr, ldap.EscapeFilter(attr))
if c.GroupSearch.Filter != "" {
Expand Down