diff --git a/cmd/sts-handlers.go b/cmd/sts-handlers.go index f52a18c86..80f1038eb 100644 --- a/cmd/sts-handlers.go +++ b/cmd/sts-handlers.go @@ -101,7 +101,10 @@ const ( ) var ( - errLDAPAuthenticationFailed = errors.New("LDAP authentication failed") + // One message for unknown users and wrong passwords. The console tries + // the built-in login (root, access keys) only when the LDAP error says + // "not found", so the message keeps those words. + errLDAPAuthenticationFailed = errors.New("LDAP authentication failed: user not found or invalid password") globalSTSLDAPLoginRateLimiter = newSTSLDAPLoginRateLimiter(time.Minute/time.Duration(stsLDAPLoginBurst), stsLDAPLoginBurst, stsLDAPLoginEntryTTL) ) diff --git a/cmd/sts-handlers_test.go b/cmd/sts-handlers_test.go index a0c93a29f..d4bb043f8 100644 --- a/cmd/sts-handlers_test.go +++ b/cmd/sts-handlers_test.go @@ -2048,6 +2048,17 @@ func TestLDAPBindErrorToSTS(t *testing.T) { } } +// The console falls back from LDAP to the built-in identity provider (root, +// access keys) only when the LDAP STS error says "not found" +// (pgsty/silo-console api/client.go, NewConsoleCredentials). The uniform +// failure for unknown users and wrong passwords must keep those words. +func TestLDAPAuthFailureKeepsConsoleFallback(t *testing.T) { + _, err := ldapBindErrorToSTS(matchingAuthError{}) + if err == nil || !strings.Contains(strings.ToLower(err.Error()), "not found") { + t.Fatalf("the console would not try the built-in login after %q", err) + } +} + func TestSTSLDAPLoginRateLimiterCleanup(t *testing.T) { set := newSTSLDAPLoginKeyLimiterSet(time.Hour, 1, time.Minute) start := time.Unix(0, 0)