1
0
mirror of https://github.com/mailcow/mailcow-dockerized.git synced 2025-12-13 01:45:59 +00:00

[Web] Fix authentication when mailbox or domain is deactivated

This commit is contained in:
FreddleSpl0it
2025-03-13 14:39:03 +01:00
parent 2596b9d386
commit cb08132a74
2 changed files with 103 additions and 12 deletions

View File

@@ -178,25 +178,40 @@ function user_login($user, $pass, $extra = null){
return false;
}
$stmt = $pdo->prepare("SELECT * FROM `mailbox`
$stmt = $pdo->prepare("SELECT
mailbox.*,
domain.active AS d_active
FROM `mailbox`
INNER JOIN domain on mailbox.domain = domain.domain
WHERE `kind` NOT REGEXP 'location|thing|group'
AND `domain`.`active`='1'
AND `username` = :user");
$stmt->execute(array(':user' => $user));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
// user does not exist, try call idp login and create user if possible via rest flow
if (!$row){
$result = false;
if ($iam_settings['authsource'] == 'keycloak' && intval($iam_settings['mailpassword_flow']) == 1){
$result = keycloak_mbox_login_rest($user, $pass, array('is_internal' => $is_internal, 'create' => true));
if ($result !== false) return $result;
} else if ($iam_settings['authsource'] == 'ldap') {
$result = ldap_mbox_login($user, $pass, array('is_internal' => $is_internal, 'create' => true));
if ($result !== false) return $result;
}
}
if ($row['active'] != 1) {
if ($result !== false){
// double check if mailbox is active
$stmt = $pdo->prepare("SELECT * FROM `mailbox`
INNER JOIN domain on mailbox.domain = domain.domain
WHERE `kind` NOT REGEXP 'location|thing|group'
AND `mailbox`.`active`='1'
AND `domain`.`active`='1'
AND `username` = :user");
$stmt->execute(array(':user' => $user));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!empty($row)) {
return true;
}
}
clear_session();
return false;
}
@@ -206,6 +221,19 @@ function user_login($user, $pass, $extra = null){
if (intval($iam_settings['mailpassword_flow']) == 1){
$result = keycloak_mbox_login_rest($user, $pass, array('is_internal' => $is_internal));
if ($result !== false) {
// double check if mailbox and domain is active
$stmt = $pdo->prepare("SELECT * FROM `mailbox`
INNER JOIN domain on mailbox.domain = domain.domain
WHERE `kind` NOT REGEXP 'location|thing|group'
AND `mailbox`.`active`='1'
AND `domain`.`active`='1'
AND `username` = :user");
$stmt->execute(array(':user' => $user));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (empty($row)) {
return false;
}
// check for tfa authenticators
$authenticators = get_tfa($user);
if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0 && !$is_internal) {
@@ -245,6 +273,19 @@ function user_login($user, $pass, $extra = null){
// user authsource is ldap
$result = ldap_mbox_login($user, $pass, array('is_internal' => $is_internal));
if ($result !== false) {
// double check if mailbox and domain is active
$stmt = $pdo->prepare("SELECT * FROM `mailbox`
INNER JOIN domain on mailbox.domain = domain.domain
WHERE `kind` NOT REGEXP 'location|thing|group'
AND `mailbox`.`active`='1'
AND `domain`.`active`='1'
AND `username` = :user");
$stmt->execute(array(':user' => $user));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (empty($row)) {
return false;
}
// check for tfa authenticators
$authenticators = get_tfa($user);
if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0 && !$is_internal) {
@@ -278,6 +319,9 @@ function user_login($user, $pass, $extra = null){
return $result;
break;
case 'mailcow':
if ($row['active'] != 1 || $row['d_active'] != 1) {
return false;
}
// verify password
if (verify_hash($row['password'], $pass) !== false) {
// check for tfa authenticators

View File

@@ -2653,17 +2653,25 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
$mapper_key = array_search($user_template, $iam_settings['mappers']);
// token valid, get mailbox
$stmt = $pdo->prepare("SELECT * FROM `mailbox`
$stmt = $pdo->prepare("SELECT
mailbox.*,
domain.active AS d_active
FROM `mailbox`
INNER JOIN domain on mailbox.domain = domain.domain
WHERE `kind` NOT REGEXP 'location|thing|group'
AND `mailbox`.`active`='1'
AND `domain`.`active`='1'
AND `username` = :user
AND (`authsource`='keycloak' OR `authsource`='generic-oidc')");
AND `username` = :user");
$stmt->execute(array(':user' => $info['email']));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row){
// success
if (!in_array($row['authsource'], array("keycloak", "generic-oidc"))) {
clear_session();
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $info['email'], "The user's authentication source is not of type OIDC"),
'msg' => 'login_failed'
);
return false;
}
if ($mapper_key !== false) {
// update user
$_SESSION['access_all_exception'] = '1';
@@ -2673,6 +2681,26 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
'template' => $iam_settings['templates'][$mapper_key]
));
$_SESSION['access_all_exception'] = '0';
// get updated row
$stmt = $pdo->prepare("SELECT
mailbox.*,
domain.active AS d_active
FROM `mailbox`
INNER JOIN domain on mailbox.domain = domain.domain
WHERE `kind` NOT REGEXP 'location|thing|group'
AND `username` = :user");
$stmt->execute(array(':user' => $info['email']));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
}
if ($row['active'] != 1 || $row['d_active'] != 1) {
clear_session();
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $info['email'], 'Domain or mailbox is inactive'),
'msg' => 'login_failed'
);
return false;
}
set_user_loggedin_session($info['email']);
$_SESSION['iam_token'] = $plain_token;
@@ -2715,6 +2743,25 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
return false;
}
// double check if mailbox and domain is active
$stmt = $pdo->prepare("SELECT * FROM `mailbox`
INNER JOIN domain on mailbox.domain = domain.domain
WHERE `kind` NOT REGEXP 'location|thing|group'
AND `mailbox`.`active`='1'
AND `domain`.`active`='1'
AND `username` = :user");
$stmt->execute(array(':user' => $info['email']));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (empty($row)) {
clear_session();
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $info['email'], 'Domain or mailbox is inactive'),
'msg' => 'login_failed'
);
return false;
}
set_user_loggedin_session($info['email']);
$_SESSION['iam_token'] = $plain_token;
$_SESSION['iam_refresh_token'] = $plain_refreshtoken;