Вход AD: причина отказа по подкоду контроллера домена (блокировка, истёкший пароль, смена пароля, отключена…)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
zuevav
2026-09-24 14:06:46 +03:00
parent 405061ef8d
commit 1616b11eb5
+24 -1
View File
@@ -626,7 +626,7 @@ func adAuthenticate(a AuthSettings, login, password string) (*adResult, error) {
sam, upn := adSplitLogin(a, login)
if err := conn.Bind(upn, password); err != nil {
if ldap.IsErrorWithCode(err, ldap.LDAPResultInvalidCredentials) {
return nil, fmt.Errorf("неверный логин или пароль (AD)")
return nil, fmt.Errorf("%s", adBindReason(err))
}
return nil, fmt.Errorf("AD bind: %v", err)
}
@@ -1464,3 +1464,26 @@ a{color:var(--accent)}
</form>
{{end}}
</div></body></html>{{end}}`
// adBindReason — причина отказа AD по подкоду «data NNN» ответа контроллера домена
// (иначе все случаи выглядят как «неверный пароль»).
func adBindReason(err error) string {
s := strings.ToLower(err.Error())
switch {
case strings.Contains(s, "data 775"):
return "учётная запись заблокирована в AD (слишком много неверных попыток) — разблокирует администратор домена"
case strings.Contains(s, "data 532"):
return "срок действия пароля AD истёк — смените пароль (Ctrl+Alt+Del на компьютере в домене)"
case strings.Contains(s, "data 773"):
return "AD требует сменить пароль при следующем входе — смените пароль на компьютере в домене"
case strings.Contains(s, "data 533"):
return "учётная запись отключена в AD"
case strings.Contains(s, "data 701"):
return "срок действия учётной записи AD истёк"
case strings.Contains(s, "data 530"), strings.Contains(s, "data 531"):
return "вход этой учётной записи сейчас запрещён политикой AD (время/компьютер)"
case strings.Contains(s, "data 525"):
return "пользователь не найден в AD"
}
return "неверный логин или пароль (AD)"
}