Browse Source

Merge 20dfbcc389 into 13f012fb81

pull/3902/merge
Alexey R. 4 days ago committed by GitHub
parent
commit
be742cabea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 75
      connector/ldap/ldap.go

75
connector/ldap/ldap.go

@ -11,6 +11,7 @@ import (
"net"
"net/url"
"os"
"regexp"
"strings"
"github.com/go-ldap/ldap/v3"
@ -62,6 +63,9 @@ import (
type UserMatcher struct {
UserAttr string `json:"userAttr"`
GroupAttr string `json:"groupAttr"`
// Work only if UserAttr is 'memberOf' and GroupAttr is dn
GroupRegexp string `json:"groupRegexp"`
groupMatcher *regexp.Regexp
// Look for parent groups
RecursionGroupAttr string `json:"recursionGroupAttr"`
}
@ -298,6 +302,13 @@ func (c *Config) openConnector(logger *slog.Logger) (*ldapConnector, error) {
// TODO(nabokihms): remove it after deleting deprecated groupSearch options
c.GroupSearch.UserMatchers = userMatchers(c, logger)
for i, _ := range c.GroupSearch.UserMatchers {
c.GroupSearch.UserMatchers[i].groupMatcher, err = regexp.Compile(c.GroupSearch.UserMatchers[i].GroupRegexp)
if err != nil {
logger.Error("Regular expression compilation error", "user_attr", c.GroupSearch.UserMatchers[i].UserAttr, "group_attr", c.GroupSearch.UserMatchers[i].GroupAttr, "err", err.Error())
c.GroupSearch.UserMatchers[i].groupMatcher, _ = regexp.Compile("")
}
}
return &ldapConnector{*c, userSearchScope, groupSearchScope, tlsConfig, logger}, nil
}
@ -600,20 +611,62 @@ func (c *ldapConnector) groups(ctx context.Context, user ldap.Entry) ([]string,
var groupNames []string
// Initial Search
var groups []*ldap.Entry
for _, matcher := range c.GroupSearch.UserMatchers {
// Initial Search
var groups []*ldap.Entry
for _, attr := range c.getAttrs(user, matcher.UserAttr) {
obtained, filter, err := c.queryGroups(ctx, matcher.GroupAttr, attr)
if err != nil {
return nil, err
// 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 !matcher.groupMatcher.MatchString(groupName) {
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,
},
},
},
})
}
gotGroups := len(obtained) != 0
if !gotGroups {
// TODO(ericchiang): Is this going to spam the logs?
c.logger.Error("ldap: groups search returned no groups", "filter", filter)
} else {
for _, attr := range c.getAttrs(user, matcher.UserAttr) {
obtained, filter, err := c.queryGroups(ctx, matcher.GroupAttr, attr)
if err != nil {
return nil, err
}
gotGroups := len(obtained) != 0
if !gotGroups {
// TODO(ericchiang): Is this going to spam the logs?
c.logger.Error("ldap: groups search returned no groups", "filter", filter)
}
groups = append(groups, obtained...)
}
groups = append(groups, obtained...)
}
// If RecursionGroupAttr is not set, convert direct groups into names and return

Loading…
Cancel
Save