fix: correctly "or"-join ldap userfilters (#9855)

# Which Problems Are Solved

LDAP userfilters are joined, but as it not handled as a list of filters
but as a string they are not or-joined.

# How the Problems Are Solved

Separate userfilters as list of filters and join them correctly with
"or" condition.

# Additional Changes

None

# Additional Context

Closes #7003

---------

Co-authored-by: Marco A. <kwbmm1990@gmail.com>
This commit is contained in:
Stefan Benz
2025-05-13 10:32:48 +02:00
committed by GitHub
parent d79d5e7b96
commit 1383cb0702
2 changed files with 17 additions and 14 deletions

View File

@@ -133,7 +133,6 @@ func tryBind(
username, username,
password, password,
timeout, timeout,
rootCA,
) )
} }
@@ -189,12 +188,11 @@ func trySearchAndUserBind(
username string, username string,
password string, password string,
timeout time.Duration, timeout time.Duration,
rootCA []byte,
) (*ldap.Entry, error) { ) (*ldap.Entry, error) {
searchQuery := queriesAndToSearchQuery( searchQuery := queriesAndToSearchQuery(
objectClassesToSearchQuery(objectClasses), objectClassesToSearchQuery(objectClasses),
queriesOrToSearchQuery( queriesOrToSearchQuery(
userFiltersToSearchQuery(userFilters, username), userFiltersToSearchQuery(userFilters, username)...,
), ),
) )
@@ -218,7 +216,12 @@ func trySearchAndUserBind(
user := sr.Entries[0] user := sr.Entries[0]
// Bind as the user to verify their password // Bind as the user to verify their password
if err = conn.Bind(user.DN, password); err != nil { userDN, err := ldap.ParseDN(user.DN)
if err != nil {
logging.WithFields("userDN", user.DN).WithError(err).Info("ldap user parse DN failed")
return nil, err
}
if err = conn.Bind(userDN.String(), password); err != nil {
logging.WithFields("userDN", user.DN).WithError(err).Info("ldap user bind failed") logging.WithFields("userDN", user.DN).WithError(err).Info("ldap user bind failed")
return nil, ErrFailedLogin return nil, ErrFailedLogin
} }
@@ -261,12 +264,12 @@ func objectClassesToSearchQuery(classes []string) string {
return searchQuery return searchQuery
} }
func userFiltersToSearchQuery(filters []string, username string) string { func userFiltersToSearchQuery(filters []string, username string) []string {
searchQuery := "" searchQueries := make([]string, len(filters))
for _, filter := range filters { for i, filter := range filters {
searchQuery += "(" + filter + "=" + ldap.EscapeFilter(username) + ")" searchQueries[i] = "(" + filter + "=" + username + ")"
} }
return searchQuery return searchQueries
} }
func mapLDAPEntryToUser( func mapLDAPEntryToUser(

View File

@@ -49,31 +49,31 @@ func TestProvider_userFiltersToSearchQuery(t *testing.T) {
name string name string
fields []string fields []string
username string username string
want string want []string
}{ }{
{ {
name: "zero", name: "zero",
fields: []string{}, fields: []string{},
username: "user", username: "user",
want: "", want: []string{},
}, },
{ {
name: "one", name: "one",
fields: []string{"test"}, fields: []string{"test"},
username: "user", username: "user",
want: "(test=user)", want: []string{"(test=user)"},
}, },
{ {
name: "three", name: "three",
fields: []string{"test1", "test2", "test3"}, fields: []string{"test1", "test2", "test3"},
username: "user", username: "user",
want: "(test1=user)(test2=user)(test3=user)", want: []string{"(test1=user)", "(test2=user)", "(test3=user)"},
}, },
{ {
name: "five", name: "five",
fields: []string{"test1", "test2", "test3", "test4", "test5"}, fields: []string{"test1", "test2", "test3", "test4", "test5"},
username: "user", username: "user",
want: "(test1=user)(test2=user)(test3=user)(test4=user)(test5=user)", want: []string{"(test1=user)", "(test2=user)", "(test3=user)", "(test4=user)", "(test5=user)"},
}, },
} }
for _, tt := range tests { for _, tt := range tests {