From 651844ba7c4209c2db3f6d5793aeafd7e3ba3411 Mon Sep 17 00:00:00 2001 From: Stefan Benz <46600784+stebenz@users.noreply.github.com> Date: Tue, 13 May 2025 10:32:48 +0200 Subject: [PATCH] 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. (cherry picked from commit 1383cb070264cba0a5ccc5c14762a24ef24a9644) --- internal/idp/providers/ldap/session.go | 21 ++++++++++++--------- internal/idp/providers/ldap/session_test.go | 10 +++++----- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/internal/idp/providers/ldap/session.go b/internal/idp/providers/ldap/session.go index 1679e35b61..a78dd02d73 100644 --- a/internal/idp/providers/ldap/session.go +++ b/internal/idp/providers/ldap/session.go @@ -133,7 +133,6 @@ func tryBind( username, password, timeout, - rootCA, ) } @@ -189,12 +188,11 @@ func trySearchAndUserBind( username string, password string, timeout time.Duration, - rootCA []byte, ) (*ldap.Entry, error) { searchQuery := queriesAndToSearchQuery( objectClassesToSearchQuery(objectClasses), queriesOrToSearchQuery( - userFiltersToSearchQuery(userFilters, username), + userFiltersToSearchQuery(userFilters, username)..., ), ) @@ -218,7 +216,12 @@ func trySearchAndUserBind( user := sr.Entries[0] // 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") return nil, ErrFailedLogin } @@ -261,12 +264,12 @@ func objectClassesToSearchQuery(classes []string) string { return searchQuery } -func userFiltersToSearchQuery(filters []string, username string) string { - searchQuery := "" - for _, filter := range filters { - searchQuery += "(" + filter + "=" + ldap.EscapeFilter(username) + ")" +func userFiltersToSearchQuery(filters []string, username string) []string { + searchQueries := make([]string, len(filters)) + for i, filter := range filters { + searchQueries[i] = "(" + filter + "=" + username + ")" } - return searchQuery + return searchQueries } func mapLDAPEntryToUser( diff --git a/internal/idp/providers/ldap/session_test.go b/internal/idp/providers/ldap/session_test.go index 69ba3a3256..89fee68718 100644 --- a/internal/idp/providers/ldap/session_test.go +++ b/internal/idp/providers/ldap/session_test.go @@ -49,31 +49,31 @@ func TestProvider_userFiltersToSearchQuery(t *testing.T) { name string fields []string username string - want string + want []string }{ { name: "zero", fields: []string{}, username: "user", - want: "", + want: []string{}, }, { name: "one", fields: []string{"test"}, username: "user", - want: "(test=user)", + want: []string{"(test=user)"}, }, { name: "three", fields: []string{"test1", "test2", "test3"}, username: "user", - want: "(test1=user)(test2=user)(test3=user)", + want: []string{"(test1=user)", "(test2=user)", "(test3=user)"}, }, { name: "five", fields: []string{"test1", "test2", "test3", "test4", "test5"}, 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 {