Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBHF4R9EAejDJUMdwr6C68
47 lines
1.7 KiB
Go
47 lines
1.7 KiB
Go
package auth
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// dataCodeRe findet den AD-spezifischen data-Code im Text eines
|
|
// LDAP-Result-Code-49-Fehlers, z. B. "... error, data 52e, v4563".
|
|
var dataCodeRe = regexp.MustCompile(`(?i)\bdata\s+([0-9a-f]{3,4})\b`)
|
|
|
|
// dataCodeReasons bildet AD-data-Codes auf Audit-Reasons ab.
|
|
// 525 (kein solcher User) wird bewusst wie ein falsches Passwort behandelt,
|
|
// damit die Fehlermeldung keine Benutzerexistenz verrät.
|
|
var dataCodeReasons = map[string]string{
|
|
"525": ReasonInvalidCredentials,
|
|
"52e": ReasonInvalidCredentials,
|
|
"530": ReasonInvalidCredentials, // Anmeldung außerhalb erlaubter Zeiten
|
|
"531": ReasonInvalidCredentials, // Anmeldung an dieser Station nicht erlaubt
|
|
"532": ReasonPasswordExpired,
|
|
"533": ReasonAccountDisabled,
|
|
"701": ReasonAccountDisabled, // Konto abgelaufen
|
|
"773": ReasonPasswordChangeRequired,
|
|
"775": ReasonAccountLocked,
|
|
}
|
|
|
|
// ReasonFromLDAPError leitet den Audit-Reason aus einem LDAP-Bind-Fehler ab.
|
|
// Fehler ohne erkennbaren data-Code gelten als Backend-Problem, nicht als
|
|
// falsches Passwort — sonst würde ein DC-Ausfall als Fehlanmeldung gezählt
|
|
// und den Benutzer über den Rate-Limiter aussperren.
|
|
func ReasonFromLDAPError(err error) string {
|
|
if err == nil {
|
|
return ""
|
|
}
|
|
msg := err.Error()
|
|
if m := dataCodeRe.FindStringSubmatch(msg); m != nil {
|
|
if reason, ok := dataCodeReasons[strings.ToLower(m[1])]; ok {
|
|
return reason
|
|
}
|
|
// data-Code vorhanden, aber unbekannt: es war eine echte Ablehnung.
|
|
return ReasonInvalidCredentials
|
|
}
|
|
if strings.Contains(msg, "Result Code 49") || strings.Contains(msg, "Invalid Credentials") {
|
|
return ReasonInvalidCredentials
|
|
}
|
|
return ReasonBackendUnavailable
|
|
}
|