mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-10-28 12:13:24 +00:00
[Web][Dovecot] Do not count logins as failed while the identity provider is unavailable
This commit is contained in:
7 files changed
+101
-34
No files matched your search
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mailcow\Auth;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* The identity provider could not answer a login (unreachable, timeout, server error). No failed login:
|
||||
* callers report a temporary failure and must not count it as an attempt for netfilter.
|
||||
*/
|
||||
class IdpUnavailable extends RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -4,6 +4,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace Mailcow\Auth\Service;
|
||||
|
||||
use LdapRecord\Auth\BindException;
|
||||
use LdapRecord\Connection;
|
||||
use LdapRecord\LdapRecordException;
|
||||
use Mailcow\Auth\IdpUnavailable;
|
||||
use Mailcow\Identity\Model\Settings;
|
||||
use Mailcow\Identity\Service\LinkService;
|
||||
use Mailcow\MailboxGroup\Service\TemplateService;
|
||||
@@ -19,6 +23,37 @@ class IdpLoginService
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds as the user to check the password, then again as the configured user. False for wrong credentials,
|
||||
* IdpUnavailable when the server cannot answer (client side codes are negative: server down, timeout, ...).
|
||||
*/
|
||||
public function verifyLdapPassword(Connection $ldap, string $dn, string $password): bool
|
||||
{
|
||||
// an empty password would be an unauthenticated bind, which succeeds
|
||||
if ($dn === '' || $password === '') {
|
||||
return false;
|
||||
}
|
||||
$guard = $ldap->auth();
|
||||
try {
|
||||
$guard->bind($dn, $password);
|
||||
$bound = true;
|
||||
} catch (BindException $e) {
|
||||
$code = $e->getDetailedError()?->getErrorCode();
|
||||
if ($code !== null && ($code < 0 || in_array($code, [51, 52], true))) {
|
||||
throw new IdpUnavailable('LDAP bind failed: ' . $e->getMessage(), 0, $e);
|
||||
}
|
||||
$bound = false;
|
||||
} catch (LdapRecordException $e) {
|
||||
throw new IdpUnavailable('LDAP bind failed: ' . $e->getMessage(), 0, $e);
|
||||
}
|
||||
try {
|
||||
$guard->bindAsConfiguredUser();
|
||||
} catch (LdapRecordException $e) {
|
||||
// the login needs no further LDAP access
|
||||
}
|
||||
return $bound;
|
||||
}
|
||||
|
||||
/** Template of the first attribute mapping matching one of the IdP attribute values, null if none */
|
||||
public function mappedTemplate(mixed $values): ?string
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user