git subrepo commit (merge) mailcow/src/mailcow-dockerized
subrepo: subdir: "mailcow/src/mailcow-dockerized"
merged: "02ae5285"
upstream: origin: "https://github.com/mailcow/mailcow-dockerized.git"
branch: "master"
commit: "649a5c01"
git-subrepo: version: "0.4.3"
origin: "???"
commit: "???"
Change-Id: I870ad468fba026cc5abf3c5699ed1e12ff28b32b
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php b/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php
index fff4190..24e5dab 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php
@@ -35,7 +35,7 @@
else {
$username = $_SESSION['mailcow_cc_username'];
}
- if (!is_numeric($_data["validity"]) || $_data["validity"] > 672) {
+ if (isset($_data["validity"]) && !filter_var($_data["validity"], FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 87600)))) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
@@ -43,8 +43,17 @@
);
return false;
}
- $domain = mailbox('get', 'mailbox_details', $username)['domain'];
- if (!is_valid_domain_name($domain)) {
+ else {
+ // Default to 1 yr
+ $_data["validity"] = 8760;
+ }
+ $domain = $_data['domain'];
+ $valid_domains[] = mailbox('get', 'mailbox_details', $username)['domain'];
+ $valid_alias_domains = user_get_alias_details($username)['alias_domains'];
+ if (!empty($valid_alias_domains)) {
+ $valid_domains = array_merge($valid_domains, $valid_alias_domains);
+ }
+ if (!in_array($domain, $valid_domains)) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
@@ -52,13 +61,11 @@
);
return false;
}
- $validity = strtotime("+".$_data["validity"]." hour");
- $letters = 'abcefghijklmnopqrstuvwxyz1234567890';
- $random_name = substr(str_shuffle($letters), 0, 24);
+ $validity = strtotime("+" . $_data["validity"] . " hour");
$stmt = $pdo->prepare("INSERT INTO `spamalias` (`address`, `goto`, `validity`) VALUES
(:address, :goto, :validity)");
$stmt->execute(array(
- ':address' => $random_name . '@' . $domain,
+ ':address' => readable_random_string(rand(rand(3, 9), rand(3, 9))) . '.' . readable_random_string(rand(rand(3, 9), rand(3, 9))) . '@' . $domain,
':goto' => $username,
':validity' => $validity
));
@@ -441,17 +448,17 @@
);
return false;
}
- $domain = idn_to_ascii(strtolower(trim($_data['domain'])), 0, INTL_IDNA_VARIANT_UTS46);
+ $domain = idn_to_ascii(strtolower(trim($_data['domain'])), 0, INTL_IDNA_VARIANT_UTS46);
$description = $_data['description'];
if (empty($description)) {
$description = $domain;
}
- $aliases = $_data['aliases'];
- $mailboxes = $_data['mailboxes'];
- $defquota = $_data['defquota'];
- $maxquota = $_data['maxquota'];
- $restart_sogo = $_data['restart_sogo'];
- $quota = $_data['quota'];
+ $aliases = (int)$_data['aliases'];
+ $mailboxes = (int)$_data['mailboxes'];
+ $defquota = (int)$_data['defquota'];
+ $maxquota = (int)$_data['maxquota'];
+ $restart_sogo = (int)$_data['restart_sogo'];
+ $quota = (int)$_data['quota'];
if ($defquota > $maxquota) {
$_SESSION['return'][] = array(
'type' => 'danger',
@@ -673,9 +680,10 @@
continue;
}
}
+ $gotos = array_unique($gotos);
$gotos = array_filter($gotos);
if (empty($gotos)) { return false; }
- $goto = implode(",", $gotos);
+ $goto = implode(",", (array)$gotos);
}
foreach ($addresses as $address) {
if (empty($address)) {
@@ -928,7 +936,7 @@
$password = $_data['password'];
$password2 = $_data['password2'];
$name = ltrim(rtrim($_data['name'], '>'), '<');
- $quota_m = intval($_data['quota']);
+ $quota_m = intval($_data['quota']);
if ((!isset($_SESSION['acl']['unlimited_quota']) || $_SESSION['acl']['unlimited_quota'] != "1") && $quota_m === 0) {
$_SESSION['return'][] = array(
'type' => 'danger',
@@ -948,9 +956,10 @@
$imap_access = (isset($_data['imap_access'])) ? intval($_data['imap_access']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['imap_access']);
$pop3_access = (isset($_data['pop3_access'])) ? intval($_data['pop3_access']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['pop3_access']);
$smtp_access = (isset($_data['smtp_access'])) ? intval($_data['smtp_access']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['smtp_access']);
+ $relayhost = (isset($_data['relayhost'])) ? intval($_data['relayhost']) : 0;
$quarantine_notification = (isset($_data['quarantine_notification'])) ? strval($_data['quarantine_notification']) : strval($MAILBOX_DEFAULT_ATTRIBUTES['quarantine_notification']);
$quarantine_category = (isset($_data['quarantine_category'])) ? strval($_data['quarantine_category']) : strval($MAILBOX_DEFAULT_ATTRIBUTES['quarantine_category']);
- $quota_b = ($quota_m * 1048576);
+ $quota_b = ($quota_m * 1048576);
$mailbox_attrs = json_encode(
array(
'force_pw_update' => strval($force_pw_update),
@@ -960,6 +969,8 @@
'imap_access' => strval($imap_access),
'pop3_access' => strval($pop3_access),
'smtp_access' => strval($smtp_access),
+ 'relayhost' => strval($relayhost),
+ 'passwd_update' => time(),
'mailbox_format' => strval($MAILBOX_DEFAULT_ATTRIBUTES['mailbox_format']),
'quarantine_notification' => strval($quarantine_notification),
'quarantine_category' => strval($quarantine_category)
@@ -989,7 +1000,7 @@
COUNT(*) as count,
COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota`
FROM `mailbox`
- WHERE `kind` NOT REGEXP 'location|thing|group'
+ WHERE (`kind` = '' OR `kind` = NULL)
AND `domain` = :domain");
$stmt->execute(array(':domain' => $domain));
$MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
@@ -1037,39 +1048,10 @@
);
return false;
}
- if (!empty($password) && !empty($password2)) {
- if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
- $_SESSION['return'][] = array(
- 'type' => 'danger',
- 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => 'password_complexity'
- );
- return false;
- }
- if ($password != $password2) {
- $_SESSION['return'][] = array(
- 'type' => 'danger',
- 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => 'password_mismatch'
- );
- return false;
- }
- // support pre hashed passwords
- if (preg_match('/^({SSHA256}|{SSHA}|{SHA512-CRYPT}|{SSHA512}|{MD5-CRYPT}|{PLAIN-MD5})/i', $password)) {
- $password_hashed = $password;
- }
- else {
- $password_hashed = hash_password($password);
- }
- }
- else {
- $_SESSION['return'][] = array(
- 'type' => 'danger',
- 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => 'password_empty'
- );
+ if (password_check($password, $password2) !== true) {
return false;
}
+ $password_hashed = hash_password($password);
if ($MailboxData['count'] >= $DomainData['mailboxes']) {
$_SESSION['return'][] = array(
'type' => 'danger',
@@ -1107,6 +1089,12 @@
':mailbox_attrs' => $mailbox_attrs,
':active' => $active
));
+ $stmt = $pdo->prepare("UPDATE `mailbox` SET
+ `attributes` = JSON_SET(`attributes`, '$.passwd_update', NOW())
+ WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
$stmt = $pdo->prepare("INSERT INTO `quota2` (`username`, `bytes`, `messages`)
VALUES (:username, '0', '0') ON DUPLICATE KEY UPDATE `bytes` = '0', `messages` = '0';");
$stmt->execute(array(':username' => $username));
@@ -1506,8 +1494,8 @@
);
continue;
}
- $lowspamlevel = explode(',', $_data['spam_score'])[0];
- $highspamlevel = explode(',', $_data['spam_score'])[1];
+ $lowspamlevel = explode(',', $_data['spam_score'])[0];
+ $highspamlevel = explode(',', $_data['spam_score'])[1];
if (!is_numeric($lowspamlevel) || !is_numeric($highspamlevel)) {
$_SESSION['return'][] = array(
'type' => 'danger',
@@ -1516,6 +1504,9 @@
);
continue;
}
+ if ($lowspamlevel == $highspamlevel) {
+ $highspamlevel = $highspamlevel + 0.1;
+ }
$stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username
AND (`option` = 'lowspamlevel' OR `option` = 'highspamlevel')");
$stmt->execute(array(
@@ -1581,7 +1572,7 @@
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => array('mailbox_modified', htmlspecialchars(implode(', ', $usernames)))
+ 'msg' => array('mailbox_modified', htmlspecialchars(implode(', ', (array)$usernames)))
);
}
break;
@@ -1932,6 +1923,52 @@
);
continue;
}
+ if ($_data['expand_alias'] === true || $_data['expand_alias'] == 1) {
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias`
+ WHERE `address` = :address
+ AND `domain` NOT IN (
+ SELECT `alias_domain` FROM `alias_domain`
+ )");
+ $stmt->execute(array(
+ ':address' => $address,
+ ));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results == 0) {
+ $_SESSION['return'][] = array(
+ 'type' => 'warning',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('is_not_primary_alias', htmlspecialchars($address))
+ );
+ continue;
+ }
+ $stmt = $pdo->prepare("SELECT `goto`, GROUP_CONCAT(CONCAT(SUBSTRING(`alias`.`address`, 1, LOCATE('@', `alias`.`address`) - 1), '@', `alias_domain`.`alias_domain`)) AS `missing_alias`
+ FROM `alias` JOIN `alias_domain` ON `alias_domain`.`target_domain` = `alias`.`domain`
+ WHERE CONCAT(SUBSTRING(`alias`.`address`, 1, LOCATE('@', `alias`.`address`) - 1), '@', `alias_domain`.`alias_domain`) NOT IN (
+ SELECT `address` FROM `alias` WHERE `address` != `goto`
+ )
+ AND `alias`.`address` NOT IN (
+ SELECT `address` FROM `alias` WHERE `address` = `goto`
+ )
+ AND `address` = :address ;");
+ $stmt->execute(array(
+ ':address' => $address
+ ));
+ $missing_aliases = $stmt->fetch(PDO::FETCH_ASSOC);
+ if (!empty($missing_aliases['missing_alias'])) {
+ mailbox('add', 'alias', array(
+ 'address' => $missing_aliases['missing_alias'],
+ 'goto' => $missing_aliases['goto'],
+ 'sogo_visible' => 1,
+ 'active' => 1
+ ));
+ }
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('alias_modified', htmlspecialchars($address))
+ );
+ continue;
+ }
$domain = idn_to_ascii(substr(strstr($address, '@'), 1), 0, INTL_IDNA_VARIANT_UTS46);
if ($is_now['address'] != $address) {
$local_part = strstr($address, '@', true);
@@ -2041,8 +2078,9 @@
':address' => $address
));
}
+ $gotos = array_unique($gotos);
$gotos = array_filter($gotos);
- $goto = implode(",", $gotos);
+ $goto = implode(",", (array)$gotos);
}
if (!empty($goto)) {
$stmt = $pdo->prepare("UPDATE `alias` SET
@@ -2096,6 +2134,7 @@
if (!empty($is_now)) {
$gal = (isset($_data['gal'])) ? intval($_data['gal']) : $is_now['gal'];
$description = (!empty($_data['description']) && isset($_SESSION['acl']['domain_desc']) && $_SESSION['acl']['domain_desc'] == "1") ? $_data['description'] : $is_now['description'];
+ (int)$relayhost = (isset($_data['relayhost']) && isset($_SESSION['acl']['domain_relayhost']) && $_SESSION['acl']['domain_relayhost'] == "1") ? intval($_data['relayhost']) : intval($is_now['relayhost']);
}
else {
$_SESSION['return'][] = array(
@@ -2157,7 +2196,7 @@
MAX(COALESCE(ROUND(`quota`/1048576), 0)) AS `biggest_mailbox`,
COALESCE(ROUND(SUM(`quota`)/1048576), 0) AS `quota_all`
FROM `mailbox`
- WHERE `kind` NOT REGEXP 'location|thing|group'
+ WHERE (`kind` = '' OR `kind` = NULL)
AND domain = :domain");
$stmt->execute(array(':domain' => $domain));
$MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
@@ -2300,6 +2339,7 @@
(int)$imap_access = (isset($_data['imap_access']) && isset($_SESSION['acl']['protocol_access']) && $_SESSION['acl']['protocol_access'] == "1") ? intval($_data['imap_access']) : intval($is_now['attributes']['imap_access']);
(int)$pop3_access = (isset($_data['pop3_access']) && isset($_SESSION['acl']['protocol_access']) && $_SESSION['acl']['protocol_access'] == "1") ? intval($_data['pop3_access']) : intval($is_now['attributes']['pop3_access']);
(int)$smtp_access = (isset($_data['smtp_access']) && isset($_SESSION['acl']['protocol_access']) && $_SESSION['acl']['protocol_access'] == "1") ? intval($_data['smtp_access']) : intval($is_now['attributes']['smtp_access']);
+ (int)$relayhost = (isset($_data['relayhost']) && isset($_SESSION['acl']['mailbox_relayhost']) && $_SESSION['acl']['mailbox_relayhost'] == "1") ? intval($_data['relayhost']) : intval($is_now['attributes']['relayhost']);
(int)$quota_m = (isset_has_content($_data['quota'])) ? intval($_data['quota']) : ($is_now['quota'] / 1048576);
$name = (!empty($_data['name'])) ? ltrim(rtrim($_data['name'], '>'), '<') : $is_now['name'];
$domain = $is_now['domain'];
@@ -2324,11 +2364,6 @@
);
return false;
}
- $stmt = $pdo->prepare("SELECT `quota`, `maxquota`
- FROM `domain`
- WHERE `domain` = :domain");
- $stmt->execute(array(':domain' => $domain));
- $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'][] = array(
'type' => 'danger',
@@ -2337,15 +2372,8 @@
);
continue;
}
- if ($quota_m > $DomainData['maxquota']) {
- $_SESSION['return'][] = array(
- 'type' => 'danger',
- 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => array('mailbox_quota_exceeded', $DomainData['maxquota'])
- );
- continue;
- }
- if (((($is_now['quota_used'] / 1048576) - $quota_m) + $quota_m) > $DomainData['quota']) {
+ $DomainData = mailbox('get', 'domain_details', $domain);
+ if ($quota_m > ($is_now['max_new_quota'] / 1048576)) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
@@ -2353,6 +2381,14 @@
);
continue;
}
+ if ($quota_m > $DomainData['max_quota_for_mbox']) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('mailbox_quota_exceeded', $DomainData['max_quota_for_mbox'])
+ );
+ continue;
+ }
$extra_acls = array();
if (isset($_data['extended_sender_acl'])) {
if (!isset($_SESSION['acl']['extend_sender_acl']) || $_SESSION['acl']['extend_sender_acl'] != "1" ) {
@@ -2539,39 +2575,21 @@
));
}
}
- if (!empty($password) && !empty($password2)) {
- if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
- $_SESSION['return'][] = array(
- 'type' => 'danger',
- 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => 'password_complexity'
- );
+ if (!empty($password)) {
+ if (password_check($password, $password2) !== true) {
continue;
}
- if ($password != $password2) {
- $_SESSION['return'][] = array(
- 'type' => 'danger',
- 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => 'password_mismatch'
- );
- continue;
- }
- // support pre hashed passwords
- if (preg_match('/^({SSHA256}|{SSHA}|{SHA512-CRYPT}|{SSHA512}|{MD5-CRYPT}|{PLAIN-MD5})/i', $password)) {
- $password_hashed = $password;
- }
- else {
- $password_hashed = hash_password($password);
- }
+ $password_hashed = hash_password($password);
$stmt = $pdo->prepare("UPDATE `mailbox` SET
- `password` = :password_hashed
+ `password` = :password_hashed,
+ `attributes` = JSON_SET(`attributes`, '$.passwd_update', NOW())
WHERE `username` = :username");
$stmt->execute(array(
':password_hashed' => $password_hashed,
':username' => $username
));
}
- // We could either set alias = 1 if alias = 2 or tune the Postfix alias table (that's what we did, TODO: to it the other way)
+ // We could either set alias = 1 if alias = 2 or tune the Postfix alias table (that's what we did, TODO: do it the other way)
$stmt = $pdo->prepare("UPDATE `alias` SET
`active` = :active
WHERE `address` = :address");
@@ -2587,6 +2605,7 @@
`attributes` = JSON_SET(`attributes`, '$.sogo_access', :sogo_access),
`attributes` = JSON_SET(`attributes`, '$.imap_access', :imap_access),
`attributes` = JSON_SET(`attributes`, '$.pop3_access', :pop3_access),
+ `attributes` = JSON_SET(`attributes`, '$.relayhost', :relayhost),
`attributes` = JSON_SET(`attributes`, '$.smtp_access', :smtp_access)
WHERE `username` = :username");
$stmt->execute(array(
@@ -2598,6 +2617,7 @@
':imap_access' => $imap_access,
':pop3_access' => $pop3_access,
':smtp_access' => $smtp_access,
+ ':relayhost' => $relayhost,
':username' => $username
));
$_SESSION['return'][] = array(
@@ -2819,7 +2839,7 @@
return false;
}
elseif (isset($_data) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
- $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` = :domain");
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE (`kind` = '' OR `kind` = NULL) AND `domain` = :domain");
$stmt->execute(array(
':domain' => $_data,
));
@@ -2829,7 +2849,7 @@
}
}
else {
- $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND (`domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role)");
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE (`kind` = '' OR `kind` = NULL) AND (`domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role)");
$stmt->execute(array(
':username' => $_SESSION['mailcow_cc_username'],
':role' => $_SESSION['mailcow_cc_role'],
@@ -2982,7 +3002,7 @@
while($field = array_shift($fields)) {
$shown_fields[] = $field['Field'];
}
- $stmt = $pdo->prepare("SELECT " . implode(',', $shown_fields) . ",
+ $stmt = $pdo->prepare("SELECT " . implode(',', (array)$shown_fields) . ",
`active`
FROM `imapsync` WHERE id = :id");
}
@@ -2997,7 +3017,7 @@
while($field = array_shift($fields)) {
$shown_fields[] = $field['Field'];
}
- $stmt = $pdo->prepare("SELECT " . implode(',', $shown_fields) . ",
+ $stmt = $pdo->prepare("SELECT " . implode(',', (array)$shown_fields) . ",
`active`
FROM `imapsync` WHERE id = :id");
}
@@ -3113,7 +3133,9 @@
}
$stmt = $pdo->prepare("SELECT `address`,
`goto`,
- `validity`
+ `validity`,
+ `created`,
+ `modified`
FROM `spamalias`
WHERE `goto` = :username
AND `validity` >= :unixnow");
@@ -3362,10 +3384,10 @@
if (empty($row)) {
return false;
}
- $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`,
+ $stmt = $pdo->prepare("SELECT COUNT(`username`) AS `count`,
COALESCE(SUM(`quota`), 0) AS `in_use`
FROM `mailbox`
- WHERE `kind` NOT REGEXP 'location|thing|group'
+ WHERE (`kind` = '' OR `kind` = NULL)
AND `domain` = :domain");
$stmt->execute(array(':domain' => $row['domain']));
$MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
@@ -3377,7 +3399,7 @@
$stmt->execute(array(':domain' => $row['domain']));
$SumQuotaInUse = $stmt->fetch(PDO::FETCH_ASSOC);
$rl = ratelimit('get', 'domain', $_data);
- $domaindata['max_new_mailbox_quota'] = ($row['quota'] * 1048576) - $MailboxDataDomain['in_use'];
+ $domaindata['max_new_mailbox_quota'] = ($row['quota'] * 1048576) - $MailboxDataDomain['in_use'];
if ($domaindata['max_new_mailbox_quota'] > ($row['maxquota'] * 1048576)) {
$domaindata['max_new_mailbox_quota'] = ($row['maxquota'] * 1048576);
}
@@ -3399,7 +3421,7 @@
$domaindata['msgs_total'] = 0;
}
$domaindata['mboxes_in_domain'] = $MailboxDataDomain['count'];
- $domaindata['mboxes_left'] = $row['mailboxes'] - $MailboxDataDomain['count'];
+ $domaindata['mboxes_left'] = $row['mailboxes'] - $MailboxDataDomain['count'];
$domaindata['domain_name'] = $row['domain'];
$domaindata['description'] = $row['description'];
$domaindata['max_num_aliases_for_domain'] = $row['aliases'];
@@ -3419,7 +3441,7 @@
$domaindata['relay_all_recipients_int'] = $row['relay_all_recipients'];
$domaindata['relay_unknown_only'] = $row['relay_unknown_only'];
$domaindata['relay_unknown_only_int'] = $row['relay_unknown_only'];
- $stmt = $pdo->prepare("SELECT COUNT(*) AS `alias_count` FROM `alias`
+ $stmt = $pdo->prepare("SELECT COUNT(`address`) AS `alias_count` FROM `alias`
WHERE (`domain`= :domain OR `domain` IN (SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain2))
AND `address` NOT IN (
SELECT `username` FROM `mailbox`
@@ -3430,7 +3452,7 @@
));
$AliasDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
(isset($AliasDataDomain['alias_count'])) ? $domaindata['aliases_in_domain'] = $AliasDataDomain['alias_count'] : $domaindata['aliases_in_domain'] = "0";
- $domaindata['aliases_left'] = $row['aliases'] - $AliasDataDomain['alias_count'];
+ $domaindata['aliases_left'] = $row['aliases'] - $AliasDataDomain['alias_count'];
if ($_SESSION['mailcow_cc_role'] == "admin")
{
$stmt = $pdo->prepare("SELECT GROUP_CONCAT(`username` SEPARATOR ', ') AS domain_admins FROM `domain_admins` WHERE `domain` = :domain");
@@ -3447,19 +3469,6 @@
return false;
}
$mailboxdata = array();
- $rl = ratelimit('get', 'mailbox', $_data);
- $last_imap_login = $redis->Get('last-login/imap/' . $_data);
- $last_smtp_login = $redis->Get('last-login/smtp/' . $_data);
- $last_pop3_login = $redis->Get('last-login/pop3/' . $_data);
- if ($last_imap_login === false || $GLOBALS['SHOW_LAST_LOGIN'] === false) {
- $last_imap_login = '0';
- }
- if ($last_smtp_login === false || $GLOBALS['SHOW_LAST_LOGIN'] === false) {
- $last_smtp_login = '0';
- }
- if ($last_pop3_login === false || $GLOBALS['SHOW_LAST_LOGIN'] === false) {
- $last_pop3_login = '0';
- }
if (preg_match('/y|yes/i', getenv('MASTER'))) {
$stmt = $pdo->prepare("SELECT
`domain`.`backupmx`,
@@ -3473,7 +3482,10 @@
`attributes`,
`quota2`.`messages`
FROM `mailbox`, `quota2`, `domain`
- WHERE `mailbox`.`kind` NOT REGEXP 'location|thing|group' AND `mailbox`.`username` = `quota2`.`username` AND `domain`.`domain` = `mailbox`.`domain` AND `mailbox`.`username` = :mailbox");
+ WHERE (`mailbox`.`kind` = '' OR `mailbox`.`kind` = NULL)
+ AND `mailbox`.`username` = `quota2`.`username`
+ AND `domain`.`domain` = `mailbox`.`domain`
+ AND `mailbox`.`username` = :mailbox");
}
else {
$stmt = $pdo->prepare("SELECT
@@ -3488,53 +3500,29 @@
`attributes`,
`quota2replica`.`messages`
FROM `mailbox`, `quota2replica`, `domain`
- WHERE `mailbox`.`kind` NOT REGEXP 'location|thing|group' AND `mailbox`.`username` = `quota2replica`.`username` AND `domain`.`domain` = `mailbox`.`domain` AND `mailbox`.`username` = :mailbox");
+ WHERE (`mailbox`.`kind` = '' OR `mailbox`.`kind` = NULL)
+ AND `mailbox`.`username` = `quota2replica`.`username`
+ AND `domain`.`domain` = `mailbox`.`domain`
+ AND `mailbox`.`username` = :mailbox");
}
$stmt->execute(array(
':mailbox' => $_data,
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
- $stmt = $pdo->prepare("SELECT `maxquota`, `quota` FROM `domain` WHERE `domain` = :domain");
- $stmt->execute(array(':domain' => $row['domain']));
- $DomainQuota = $stmt->fetch(PDO::FETCH_ASSOC);
- $stmt = $pdo->prepare("SELECT IFNULL(COUNT(`active`), 0) AS `pushover_active` FROM `pushover` WHERE `username` = :username AND `active` = 1");
- $stmt->execute(array(':username' => $_data));
- $PushoverActive = $stmt->fetch(PDO::FETCH_ASSOC);
- $stmt = $pdo->prepare("SELECT COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` = :domain AND `username` != :username");
- $stmt->execute(array(':domain' => $row['domain'], ':username' => $_data));
- $MailboxUsage = $stmt->fetch(PDO::FETCH_ASSOC);
- $stmt = $pdo->prepare("SELECT IFNULL(COUNT(`address`), 0) AS `sa_count` FROM `spamalias` WHERE `goto` = :address AND `validity` >= :unixnow");
- $stmt->execute(array(':address' => $_data, ':unixnow' => time()));
- $SpamaliasUsage = $stmt->fetch(PDO::FETCH_ASSOC);
- $mailboxdata['max_new_quota'] = ($DomainQuota['quota'] * 1048576) - $MailboxUsage['in_use'];
- if ($mailboxdata['max_new_quota'] > ($DomainQuota['maxquota'] * 1048576)) {
- $mailboxdata['max_new_quota'] = ($DomainQuota['maxquota'] * 1048576);
- }
+
$mailboxdata['username'] = $row['username'];
- if (!empty($rl)) {
- $mailboxdata['rl'] = $rl;
- $mailboxdata['rl_scope'] = 'mailbox';
- }
- else {
- $mailboxdata['rl'] = ratelimit('get', 'domain', $row['domain']);
- $mailboxdata['rl_scope'] = 'domain';
- }
- $mailboxdata['is_relayed'] = $row['backupmx'];
- $mailboxdata['name'] = $row['name'];
- $mailboxdata['last_imap_login'] = $last_imap_login;
- $mailboxdata['last_smtp_login'] = $last_smtp_login;
- $mailboxdata['last_pop3_login'] = $last_pop3_login;
$mailboxdata['active'] = $row['active'];
$mailboxdata['active_int'] = $row['active'];
$mailboxdata['domain'] = $row['domain'];
+ $mailboxdata['relayhost'] = $row['relayhost'];
+ $mailboxdata['name'] = $row['name'];
$mailboxdata['local_part'] = $row['local_part'];
$mailboxdata['quota'] = $row['quota'];
+ $mailboxdata['messages'] = $row['messages'];
$mailboxdata['attributes'] = json_decode($row['attributes'], true);
$mailboxdata['quota_used'] = intval($row['bytes']);
$mailboxdata['percent_in_use'] = ($row['quota'] == 0) ? '- ' : round((intval($row['bytes']) / intval($row['quota'])) * 100);
- $mailboxdata['messages'] = $row['messages'];
- $mailboxdata['spam_aliases'] = $SpamaliasUsage['sa_count'];
- $mailboxdata['pushover_active'] = ($PushoverActive['pushover_active'] == 1) ? 1 : 0;
+
if ($mailboxdata['percent_in_use'] === '- ') {
$mailboxdata['percent_class'] = "info";
}
@@ -3547,6 +3535,69 @@
else {
$mailboxdata['percent_class'] = "success";
}
+
+ // Determine last logins
+ $stmt = $pdo->prepare("SELECT MAX(`datetime`) AS `datetime`, `service` FROM `sasl_log`
+ WHERE `username` = :mailbox
+ GROUP BY `service` DESC");
+ $stmt->execute(array(':mailbox' => $_data));
+ $SaslLogsData = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($SaslLogsData as $SaslLogs) {
+ if ($SaslLogs['service'] == 'imap') {
+ $last_imap_login = strtotime($SaslLogs['datetime']);
+ }
+ else if ($SaslLogs['service'] == 'smtp') {
+ $last_smtp_login = strtotime($SaslLogs['datetime']);
+ }
+ else if ($SaslLogs['service'] == 'pop3') {
+ $last_pop3_login = strtotime($SaslLogs['datetime']);
+ }
+ }
+ if (!isset($last_imap_login) || $GLOBALS['SHOW_LAST_LOGIN'] === false) {
+ $last_imap_login = 0;
+ }
+ if (!isset($last_smtp_login) || $GLOBALS['SHOW_LAST_LOGIN'] === false) {
+ $last_smtp_login = 0;
+ }
+ if (!isset($last_pop3_login) || $GLOBALS['SHOW_LAST_LOGIN'] === false) {
+ $last_pop3_login = 0;
+ }
+ $mailboxdata['last_imap_login'] = $last_imap_login;
+ $mailboxdata['last_smtp_login'] = $last_smtp_login;
+ $mailboxdata['last_pop3_login'] = $last_pop3_login;
+
+ if (!isset($_extra) || $_extra != 'reduced') {
+ $rl = ratelimit('get', 'mailbox', $_data);
+ $stmt = $pdo->prepare("SELECT `maxquota`, `quota` FROM `domain` WHERE `domain` = :domain");
+ $stmt->execute(array(':domain' => $row['domain']));
+ $DomainQuota = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $stmt = $pdo->prepare("SELECT IFNULL(COUNT(`active`), 0) AS `pushover_active` FROM `pushover` WHERE `username` = :username AND `active` = 1");
+ $stmt->execute(array(':username' => $_data));
+ $PushoverActive = $stmt->fetch(PDO::FETCH_ASSOC);
+ $stmt = $pdo->prepare("SELECT COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE (`kind` = '' OR `kind` = NULL) AND `domain` = :domain AND `username` != :username");
+ $stmt->execute(array(':domain' => $row['domain'], ':username' => $_data));
+ $MailboxUsage = $stmt->fetch(PDO::FETCH_ASSOC);
+ $stmt = $pdo->prepare("SELECT IFNULL(COUNT(`address`), 0) AS `sa_count` FROM `spamalias` WHERE `goto` = :address AND `validity` >= :unixnow");
+ $stmt->execute(array(':address' => $_data, ':unixnow' => time()));
+ $SpamaliasUsage = $stmt->fetch(PDO::FETCH_ASSOC);
+ $mailboxdata['max_new_quota'] = ($DomainQuota['quota'] * 1048576) - $MailboxUsage['in_use'];
+ $mailboxdata['spam_aliases'] = $SpamaliasUsage['sa_count'];
+ $mailboxdata['pushover_active'] = ($PushoverActive['pushover_active'] == 1) ? 1 : 0;
+ if ($mailboxdata['max_new_quota'] > ($DomainQuota['maxquota'] * 1048576)) {
+ $mailboxdata['max_new_quota'] = ($DomainQuota['maxquota'] * 1048576);
+ }
+ if (!empty($rl)) {
+ $mailboxdata['rl'] = $rl;
+ $mailboxdata['rl_scope'] = 'mailbox';
+ }
+ else {
+ $mailboxdata['rl'] = ratelimit('get', 'domain', $row['domain']);
+ $mailboxdata['rl_scope'] = 'domain';
+ }
+ $mailboxdata['is_relayed'] = $row['backupmx'];
+ }
+
return $mailboxdata;
break;
case 'resource_details':
@@ -3826,7 +3877,7 @@
);
continue;
}
- $domain = idn_to_ascii(strtolower(trim($domain)), 0, INTL_IDNA_VARIANT_UTS46);
+ $domain = idn_to_ascii(strtolower(trim($domain)), 0, INTL_IDNA_VARIANT_UTS46);
$stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
WHERE `domain` = :domain");
$stmt->execute(array(':domain' => $domain));
@@ -4163,6 +4214,14 @@
$stmt->execute(array(
':username' => $username
));
+ $stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `fido2` WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ));
$stmt = $pdo->prepare("SELECT `address`, `goto` FROM `alias`
WHERE `goto` REGEXP :username");
$stmt->execute(array(':username' => '(^|,)'.$username.'($|,)'));
@@ -4172,7 +4231,7 @@
if (($key = array_search($username, $goto_exploded)) !== false) {
unset($goto_exploded[$key]);
}
- $gotos_rebuild = implode(',', $goto_exploded);
+ $gotos_rebuild = implode(',', (array)$goto_exploded);
$stmt = $pdo->prepare("UPDATE `alias` SET
`goto` = :goto
WHERE `address` = :address");