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) {
searchRes, err := conn.Search(ldap.NewSearchRequest(
a.baseDN,
ldap.ScopeWholeSubtree,
ldap.NeverDerefAliases,
2,
0,
false,
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 strings.Contains(principal, "@") {
entry, err := a.searchUserByAttribute(conn, "userPrincipalName", principal)
if err != nil {
return nil, "", err
}
if entry != nil {
return entry, "principal_upn", nil
}
}
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
}
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 {
return strings.ToLower(strings.TrimSpace(value))
}