From d2a7145a4c6adc241d3cad4685c0fdfb5540d833 Mon Sep 17 00:00:00 2001 From: Nathan Coad Date: Tue, 21 Apr 2026 13:03:08 +1000 Subject: [PATCH] bugfix ldap --- internal/auth/ldap.go | 27 ++++++++++++++++++++++++--- internal/auth/ldap_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/internal/auth/ldap.go b/internal/auth/ldap.go index 4a16a7a..6b8452f 100644 --- a/internal/auth/ldap.go +++ b/internal/auth/ldap.go @@ -109,11 +109,13 @@ func (a *LDAPAuthenticator) AuthenticateAndFetchGroups(ctx context.Context, user } if whoami, err := conn.WhoAmI(nil); err != nil { identity.Diagnostics = append(identity.Diagnostics, fmt.Sprintf("whoami_failed:%v", err)) - } else if boundDN := strings.TrimSpace(strings.TrimPrefix(strings.TrimSpace(whoami.AuthzID), "dn:")); boundDN != "" { + } else if boundDN := parseWhoAmIDN(whoami.AuthzID); boundDN != "" { identity.UserDN = boundDN identity.Diagnostics = append(identity.Diagnostics, "whoami_dn_resolved") - } else { + } else if strings.TrimSpace(whoami.AuthzID) == "" { identity.Diagnostics = append(identity.Diagnostics, "whoami_dn_empty") + } else { + identity.Diagnostics = append(identity.Diagnostics, "whoami_non_dn_authzid") } entry, lookupStrategy, err := a.lookupUserEntry(conn, username, identity.UserDN) @@ -281,7 +283,10 @@ func (a *LDAPAuthenticator) buildTLSConfig() (*tls.Config, error) { } func (a *LDAPAuthenticator) lookupUserEntry(conn *ldap.Conn, username string, userDNHint string) (*ldap.Entry, string, error) { - dnCandidates := compactTrimmedStrings([]string{userDNHint}) + dnCandidates := make([]string, 0, 2) + if looksLikeDN(userDNHint) { + dnCandidates = append(dnCandidates, strings.TrimSpace(userDNHint)) + } if looksLikeDN(username) { dnCandidates = append(dnCandidates, strings.TrimSpace(username)) } @@ -378,6 +383,22 @@ func looksLikeDN(value string) bool { return strings.Contains(value, "=") && strings.Contains(value, ",") } +func parseWhoAmIDN(authzID string) string { + authzID = strings.TrimSpace(authzID) + if authzID == "" { + return "" + } + + lower := strings.ToLower(authzID) + if strings.HasPrefix(lower, "dn:") { + authzID = strings.TrimSpace(authzID[3:]) + } + if !looksLikeDN(authzID) { + return "" + } + return authzID +} + func principalCandidates(username string) []string { username = strings.TrimSpace(username) if username == "" { diff --git a/internal/auth/ldap_test.go b/internal/auth/ldap_test.go index 039840d..5ec1b6b 100644 --- a/internal/auth/ldap_test.go +++ b/internal/auth/ldap_test.go @@ -86,3 +86,41 @@ func TestBuildGroupMembershipFilter(t *testing.T) { t.Fatalf("unexpected group filter:\n got: %s\nwant: %s", filter, expected) } } + +func TestParseWhoAmIDN(t *testing.T) { + tests := []struct { + name string + authzID string + wantDN string + }{ + { + name: "dn prefix", + authzID: "dn:CN=User,OU=Users,DC=corpau,DC=wbcau,DC=westpac,DC=com,DC=au", + wantDN: "CN=User,OU=Users,DC=corpau,DC=wbcau,DC=westpac,DC=com,DC=au", + }, + { + name: "dn prefix upper", + authzID: "DN:CN=User,OU=Users,DC=corpau,DC=wbcau,DC=westpac,DC=com,DC=au", + wantDN: "CN=User,OU=Users,DC=corpau,DC=wbcau,DC=westpac,DC=com,DC=au", + }, + { + name: "non dn authzid", + authzID: "u:L075239@corpau.wbcau.westpac.com.au", + wantDN: "", + }, + { + name: "plain non dn", + authzID: "L075239@corpau.wbcau.westpac.com.au", + wantDN: "", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got := parseWhoAmIDN(tc.authzID) + if got != tc.wantDN { + t.Fatalf("unexpected whoami dn parse: got=%q want=%q", got, tc.wantDN) + } + }) + } +}