From 2a3c64abd6eec08c6e643aeb02b5f3e1aff9647a Mon Sep 17 00:00:00 2001 From: Wilton Rodrigues Date: Thu, 3 Aug 2023 15:13:19 -0300 Subject: [PATCH] Add param for search nested LDAP group - Prevent LDAP servers without support to LDAP_MATCHING_RULE_IN_CHAIN -- break with 'LDAP Result Code 12 "Unavailable Critical Extension": Bad search filter' -- https://ldapwiki.com/wiki/Wiki.jsp?page=LDAP_MATCHING_RULE_IN_CHAIN - Fixes #45 --- ldapauth.go | 31 +++++++++++++++++++++++-------- readme.md | 6 ++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/ldapauth.go b/ldapauth.go index 4d14142..bf8035c 100644 --- a/ldapauth.go +++ b/ldapauth.go @@ -61,6 +61,7 @@ type Config struct { ForwardExtraLdapHeaders bool `json:"forwardExtraLdapHeaders,omitempty" yaml:"forwardExtraLdapHeaders,omitempty"` WWWAuthenticateHeader bool `json:"wwwAuthenticateHeader,omitempty" yaml:"wwwAuthenticateHeader,omitempty"` WWWAuthenticateHeaderRealm string `json:"wwwAuthenticateHeaderRealm,omitempty" yaml:"wwwAuthenticateHeaderRealm,omitempty"` + EnableNestedGroupFilter bool `json:"enableNestedGroupsFilter,omitempty" yaml:"enableNestedGroupsFilter,omitempty"` AllowedGroups []string `json:"allowedGroups,omitempty" yaml:"allowedGroups,omitempty"` AllowedUsers []string `json:"allowedUsers,omitempty" yaml:"allowedUsers,omitempty"` Username string @@ -93,6 +94,7 @@ func CreateConfig() *Config { ForwardExtraLdapHeaders: false, WWWAuthenticateHeader: true, WWWAuthenticateHeaderRealm: "", + EnableNestedGroupFilter: false, AllowedGroups: nil, AllowedUsers: nil, Username: "", @@ -320,16 +322,29 @@ func LdapCheckUserGroups(conn *ldap.Conn, config *Config, entry *ldap.Entry, use found := false err := error(nil) + var group_filter bytes.Buffer + + templ := "(|" + + "(member={{.UserDN}})" + + "(uniqueMember={{.UserDN}})" + + "(memberUid={{.Username}})" + + "{{if .EnableNestedGroupFilter}}" + + "(member:1.2.840.113556.1.4.1941:={{.UserDN}})" + + "{{end}}" + + ")" + + template.Must(template.New("group_filter_template"). + Parse(templ)). + Execute(&group_filter, struct { + UserDN string + Username string + EnableNestedGroupFilter bool + }{ldap.EscapeFilter(entry.DN), ldap.EscapeFilter(username), config.EnableNestedGroupFilter}) + + LoggerDEBUG.Printf("Group Filter: '%s'", group_filter.String()) for _, g := range config.AllowedGroups { - group_filter := fmt.Sprintf("(|"+ - "(member=%s)"+ - "(uniqueMember=%s)"+ - "(memberUid=%s)"+ - "(member:1.2.840.113556.1.4.1941:=%s)"+ - ")", ldap.EscapeFilter(entry.DN), ldap.EscapeFilter(entry.DN), ldap.EscapeFilter(username), ldap.EscapeFilter(entry.DN)) - LoggerDEBUG.Printf("Searching Group: '%s' with User: '%s'", g, entry.DN) search := ldap.NewSearchRequest( @@ -339,7 +354,7 @@ func LdapCheckUserGroups(conn *ldap.Conn, config *Config, entry *ldap.Entry, use 0, 0, false, - group_filter, + group_filter.String(), []string{"member", "uniqueMember", "memberUid"}, nil, ) diff --git a/readme.md b/readme.md index 0554ded..7bc4568 100644 --- a/readme.md +++ b/readme.md @@ -282,6 +282,12 @@ _Optional, Default: `""`_ The name of the realm to specify in the `WWW-Authenticate` header. This option is ineffective unless the `wwwAuthenticateHeader` option is set to true. +##### `enableNestedGroupFilter` + +_Optional, Default: `false`_ + +If you need to search the user's nested group and the `LDAP` server support to [search for LDAP_MATCHING_RULE_IN_CHAIN groups](https://ldapwiki.com/wiki/Wiki.jsp?page=LDAP_MATCHING_RULE_IN_CHAIN), you can enabled it by settings this parameter to `true`, it is disabled by default. + ##### `allowedGroups` Needs `traefik` >= [`v2.8.2`](https://github.com/traefik/traefik/releases/tag/v2.8.2)