optimising ldap lookup
continuous-integration/drone/push Build is passing

This commit is contained in:
Nathan Coad
2026-04-21 13:50:07 +10:00
parent a8e38784d9
commit 14d242c8d1
+51 -20
View File
@@ -321,32 +321,63 @@ func (a *LDAPAuthenticator) lookupUserEntry(conn *ldap.Conn, username string, us
} }
for _, principal := range principalCandidates(username) { for _, principal := range principalCandidates(username) {
searchRes, err := conn.Search(ldap.NewSearchRequest( if strings.Contains(principal, "@") {
a.baseDN, entry, err := a.searchUserByAttribute(conn, "userPrincipalName", principal)
ldap.ScopeWholeSubtree, if err != nil {
ldap.NeverDerefAliases, return nil, "", err
2, }
0, if entry != nil {
false, return entry, "principal_upn", nil
fmt.Sprintf("(|(uid=%s)(cn=%s)(sAMAccountName=%s)(userPrincipalName=%s))", }
ldap.EscapeFilter(principal),
ldap.EscapeFilter(principal),
ldap.EscapeFilter(principal),
ldap.EscapeFilter(principal),
),
[]string{"uid", "sAMAccountName", "userPrincipalName", "cn", "memberOf"},
nil,
))
if err != nil {
return nil, "", fmt.Errorf("%w: user lookup failed: %v", ErrLDAPOperationFailed, err)
} }
if len(searchRes.Entries) > 0 {
return searchRes.Entries[0], "principal", nil entry, err := a.searchUserByAttribute(conn, "sAMAccountName", principal)
if err != nil {
return nil, "", err
}
if entry != nil {
return entry, "principal_samaccountname", nil
}
// Keep uid lookup as a fallback for non-AD LDAP directories.
entry, err = a.searchUserByAttribute(conn, "uid", principal)
if err != nil {
return nil, "", err
}
if entry != nil {
return entry, "principal_uid", nil
} }
} }
return nil, "", nil return nil, "", nil
} }
func (a *LDAPAuthenticator) searchUserByAttribute(conn *ldap.Conn, attribute string, value string) (*ldap.Entry, error) {
attribute = strings.TrimSpace(attribute)
value = strings.TrimSpace(value)
if attribute == "" || value == "" {
return nil, nil
}
searchRes, err := conn.Search(ldap.NewSearchRequest(
a.baseDN,
ldap.ScopeWholeSubtree,
ldap.NeverDerefAliases,
2,
0,
false,
fmt.Sprintf("(%s=%s)", attribute, ldap.EscapeFilter(value)),
[]string{"uid", "sAMAccountName", "userPrincipalName", "cn", "memberOf"},
nil,
))
if err != nil {
return nil, fmt.Errorf("%w: user lookup failed (%s): %v", ErrLDAPOperationFailed, attribute, err)
}
if len(searchRes.Entries) == 0 {
return nil, nil
}
return searchRes.Entries[0], nil
}
func normalizeDN(value string) string { func normalizeDN(value string) string {
return strings.ToLower(strings.TrimSpace(value)) return strings.ToLower(strings.TrimSpace(value))
} }