diff --git a/internal/lkgateway/auth.go b/internal/lkgateway/auth.go index 78e5c50..8a266bc 100644 --- a/internal/lkgateway/auth.go +++ b/internal/lkgateway/auth.go @@ -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)} {{end}} {{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)" +}