public
nobgit
read
NobMail
Based on mailcow: dockerized
Languages
Repository composition by tracked source files.
PHP
49%
JavaScript
35%
HTML
9%
CSS
4%
Shell
2%
Python
1%
Lua
0%
Perl
0%
Ruby
0%
SCSS
0%
Create file
Wiki Documentation
Clone
https://nobgit.com/orgs/nobgit/nobmail.git
ssh://[email protected]:2222/orgs/nobgit/nobmail.git
Commit
More structural changes
fd5a5908
data/Dockerfiles/rspamd/Dockerfile | 3 +
data/web/add.php | 6 +-
data/web/admin.php | 55 +-
data/web/css/edit.css | 24 +
data/web/edit.php | 180 +-
data/web/inc/footer.inc.php | 3 +-
data/web/inc/functions.inc.php | 5382 ++++++--------------------------
data/web/inc/functions.mailbox.inc.php | 3116 ++++++++++++++++++
data/web/inc/functions.policy.inc.php | 354 +++
data/web/inc/header.inc.php | 1 +
data/web/inc/prerequisites.inc.php | 16 +-
data/web/inc/triggers.inc.php | 67 +-
data/web/js/admin.js | 261 +-
data/web/js/api.js | 154 +
data/web/js/edit.js | 83 +
data/web/js/mailbox.js | 92 -
data/web/js/user.js | 241 +-
data/web/json_api.php | 515 ++-
data/web/lang/lang.de.php | 3 +-
data/web/lang/lang.en.php | 3 +-
data/web/user.php | 350 +--
21 files changed, 5710 insertions(+), 5199 deletions(-)
create mode 100644 data/web/css/edit.css
create mode 100644 data/web/inc/functions.mailbox.inc.php
create mode 100644 data/web/inc/functions.policy.inc.php
create mode 100644 data/web/js/api.js
create mode 100644 data/web/js/edit.js
Diff
diff --git a/data/Dockerfiles/rspamd/Dockerfile b/data/Dockerfiles/rspamd/Dockerfile
index 4a2ea589..42f2afc2 100644
--- a/data/Dockerfiles/rspamd/Dockerfile
+++ b/data/Dockerfiles/rspamd/Dockerfile
@@ -17,6 +17,9 @@ COPY settings.conf /etc/rspamd/modules.d/settings.conf
COPY antivirus.conf /etc/rspamd/modules.d/antivirus.conf
COPY dkim_signing.lua /usr/share/rspamd/lua/dkim_signing.lua
+RUN apt-get autoremove --purge \
+ && apt-get clean
+
CMD /usr/bin/rspamd -f -u _rspamd -g _rspamd
RUN rm -rf /tmp/* /var/tmp/*
diff --git a/data/web/add.php b/data/web/add.php
index d3c7ca95..b81a4e55 100644
--- a/data/web/add.php
+++ b/data/web/add.php
@@ -139,7 +139,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
<div class="col-sm-10">
<select name="target_domain" id="target_domain" title="<?=$lang['add']['select'];?>" required>
<?php
- foreach (mailbox_get_domains() as $domain) {
+ foreach (mailbox('get', 'domains') as $domain) {
echo "<option>".htmlspecialchars($domain)."</option>";
}
?>
@@ -177,7 +177,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
<div class="col-sm-10">
<select id="addSelectDomain" name="domain" id="domain" required>
<?php
- foreach (mailbox_get_domains() as $domain) {
+ foreach (mailbox('get', 'domains') as $domain) {
echo "<option>".htmlspecialchars($domain)."</option>";
}
?>
@@ -242,7 +242,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
<div class="col-sm-10">
<select name="domain" id="domain" title="<?=$lang['add']['select'];?>" required>
<?php
- foreach (mailbox_get_domains() as $domain) {
+ foreach (mailbox('get', 'domains') as $domain) {
echo "<option>".htmlspecialchars($domain)."</option>";
}
?>
diff --git a/data/web/admin.php b/data/web/admin.php
index a6f032be..8766b211 100644
--- a/data/web/admin.php
+++ b/data/web/admin.php
@@ -15,8 +15,15 @@ $tfa_data = get_tfa();
<li role="presentation">
<a href="#tab-config" aria-controls="tab-config" role="tab" data-toggle="tab"><?=$lang['admin']['configuration'];?></a>
</li>
- <li role="presentation">
- <a href="#tab-logs" aria-controls="tab-logs" role="tab" data-toggle="tab"><?=$lang['admin']['logs'];?></a>
+ <li class="dropdown">
+ <a class="dropdown-toggle" data-toggle="dropdown" href="#">Logs
+ <span class="caret"></span></a>
+ <ul class="dropdown-menu">
+ <li role="presentation"><a href="#tab-postfix-logs" aria-controls="tab-postfix-logs" role="tab" data-toggle="tab">Postfix</a></li>
+ <li role="presentation"><a href="#tab-dovecot-logs" aria-controls="tab-dovecot-logs" role="tab" data-toggle="tab">Dovecot</a></li>
+ <li role="presentation"><a href="#tab-sogo-logs" aria-controls="tab-sogo-logs" role="tab" data-toggle="tab">SOGo</a></li>
+ <li role="presentation"><a href="#tab-rspamd-history" aria-controls="tab-rspamd-history" role="tab" data-toggle="tab">Rspamd</a></li>
+ </ul>
</li>
</ul>
@@ -113,7 +120,7 @@ $tfa_data = get_tfa();
<div class="col-sm-10">
<select title="<?=$lang['admin']['search_domain_da'];?>" style="width:100%" name="domain[]" size="5" multiple>
<?php
- foreach (mailbox_get_domains() as $domain) {
+ foreach (mailbox('get', 'domains') as $domain) {
echo "<option>".htmlspecialchars($domain)."</option>";
}
?>
@@ -163,7 +170,7 @@ $tfa_data = get_tfa();
</div>
</div>
<?php
- foreach(mailbox_get_domains() as $domain) {
+ foreach(mailbox('get', 'domains') as $domain) {
if (!empty($dkim = dkim_get_key_details($domain))) {
?>
<div class="row">
@@ -192,7 +199,7 @@ $tfa_data = get_tfa();
</div>
<?php
}
- foreach(mailbox_get_alias_domains($domain) as $alias_domain) {
+ foreach(mailbox('get', 'alias_domains') as $alias_domain) {
if (!empty($dkim = dkim_get_key_details($alias_domain))) {
?>
<div class="row">
@@ -297,37 +304,43 @@ $tfa_data = get_tfa();
</div>
</div>
- <div role="tabpanel" class="tab-pane" id="tab-logs">
+ <div role="tabpanel" class="tab-pane" id="tab-postfix-logs">
<div class="panel panel-default">
- <div class="panel-heading">Dovecot
+ <div class="panel-heading">Postfix
<div class="btn-group pull-right">
<a class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['admin']['action'];?> <span class="caret"></span></a>
<ul class="dropdown-menu">
- <li><a href="#" id="refresh_dovecot_log"><?=$lang['admin']['refresh'];?></a></li>
+ <li><a href="#" id="refresh_postfix_log"><?=$lang['admin']['refresh'];?></a></li>
</ul>
</div>
</div>
<div class="panel-body">
<div class="table-responsive">
- <table class="table table-striped" id="dovecot_log"></table>
+ <table class="table table-striped" id="postfix_log"></table>
</div>
</div>
</div>
+ </div>
+
+ <div role="tabpanel" class="tab-pane" id="tab-dovecot-logs">
<div class="panel panel-default">
- <div class="panel-heading">Postfix
+ <div class="panel-heading">Dovecot
<div class="btn-group pull-right">
<a class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['admin']['action'];?> <span class="caret"></span></a>
<ul class="dropdown-menu">
- <li><a href="#" id="refresh_postfix_log"><?=$lang['admin']['refresh'];?></a></li>
+ <li><a href="#" id="refresh_dovecot_log"><?=$lang['admin']['refresh'];?></a></li>
</ul>
</div>
</div>
<div class="panel-body">
<div class="table-responsive">
- <table class="table table-striped" id="postfix_log"></table>
+ <table class="table table-striped" id="dovecot_log"></table>
</div>
</div>
</div>
+ </div>
+
+ <div role="tabpanel" class="tab-pane" id="tab-sogo-logs">
<div class="panel panel-default">
<div class="panel-heading">SOGo
<div class="btn-group pull-right">
@@ -345,6 +358,24 @@ $tfa_data = get_tfa();
</div>
</div>
+ <div role="tabpanel" class="tab-pane" id="tab-rspamd-history">
+ <div class="panel panel-default">
+ <div class="panel-heading">Rspamd history
+ <div class="btn-group pull-right">
+ <a class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['admin']['action'];?> <span class="caret"></span></a>
+ <ul class="dropdown-menu">
+ <li><a href="#" id="refresh_rspamd_history"><?=$lang['admin']['refresh'];?></a></li>
+ </ul>
+ </div>
+ </div>
+ <div class="panel-body">
+ <div class="table-responsive">
+ <table class="table table-striped" id="rspamd_history"></table>
+ </div>
+ </div>
+ </div>
+ </div>
+
</div>
</div> <!-- /container -->
<script type='text/javascript'>
diff --git a/data/web/css/edit.css b/data/web/css/edit.css
new file mode 100644
index 00000000..605a1010
--- /dev/null
+++ b/data/web/css/edit.css
@@ -0,0 +1,24 @@
+table.footable>tbody>tr.footable-empty>td {
+ font-size:15px !important;
+ font-style:italic;
+}
+.pagination a {
+ text-decoration: none !important;
+}
+.panel panel-default {
+ overflow: visible !important;
+}
+.table-responsive {
+ overflow: visible !important;
+}
+.footer-add-item {
+ display:block;
+ text-align: center;
+ font-style: italic;
+ padding: 10px;
+ background: #F5F5F5;
+}
+.mass-actions-user {
+ user-select: none;
+ padding:10px 0 10px 0;
+}
diff --git a/data/web/edit.php b/data/web/edit.php
index 9f711dc2..b13626ea 100644
--- a/data/web/edit.php
+++ b/data/web/edit.php
@@ -20,7 +20,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
if (isset($_GET["alias"]) &&
!empty($_GET["alias"])) {
$alias = $_GET["alias"];
- $result = mailbox_get_alias_details($alias);
+ $result = mailbox('get', 'alias_details', $alias);
if (!empty($result)) {
?>
<h4><?=$lang['edit']['alias'];?></h4>
@@ -138,7 +138,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
is_valid_domain_name($_GET["domain"]) &&
!empty($_GET["domain"])) {
$domain = $_GET["domain"];
- $result = mailbox_get_domain_details($domain);
+ $result = mailbox('get', 'domain_details', $domain);
if (!empty($result)) {
?>
<h4><?=$lang['edit']['domain'];?></h4>
@@ -225,119 +225,54 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
<hr>
<div class="row">
<div class="col-sm-6">
- <h4><span class="glyphicon glyphicon-thumbs-up" aria-hidden="true"></span> <?=$lang['user']['spamfilter_wl'];?></h4>
- <p><?=$lang['user']['spamfilter_wl_desc'];?></p>
- <div class="row">
- <div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_rule'];?></b></div>
- <div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_action'];?></b></div>
- </div>
- <?php
- $get_policy_list = get_policy_list($domain);
- if (empty($get_policy_list['whitelist'])):
- ?>
- <div class="row">
- <div class="col-sm-12"><i><?=$lang['user']['spamfilter_table_empty'];?></i></div>
- </div>
- <?php
- else:
- foreach($get_policy_list['whitelist'] as $wl):
- ?>
- <div class="row striped">
- <form class="form-inline" method="post">
- <div class="col-xs-6"><code><?=$wl['value'];?></code></div>
- <div class="col-xs-6">
- <?php
- if ($wl['object'] == $domain):
- ?>
- <input type="hidden" name="delete_prefid" value="<?=$wl['prefid'];?>">
- <input type="hidden" name="delete_policy_list_item">
- <input type="hidden" name="domain" value="<?=$domain;?>">
- <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a>
- <?php
- else:
- ?>
- <span style="cursor:not-allowed"><?=$lang['user']['spamfilter_table_domain_policy'];?></span>
- <?php
- endif;
- ?>
- </div>
- </form>
+ <h4><?=$lang['user']['spamfilter_wl'];?></h4>
+ <p><?=$lang['user']['spamfilter_wl_desc'];?></p>
+ <div class="table-responsive">
+ <table class="table table-striped table-condensed" id="wl_policy_domain_table"></table>
+ </div>
+ <div class="mass-actions-user">
+ <div class="btn-group">
+ <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="policy_wl_domain" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+ <a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_wl_domain" data-api-url='delete/policy_mailbox' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+ </ul>
</div>
- <?php
- endforeach;
- endif;
- ?>
- <hr style="margin:5px 0px 7px 0px">
- <div class="row">
- <form class="form-inline" method="post">
- <div class="col-xs-6">
- <input type="text" class="form-control input-sm" name="object_from" id="object_from" placeholder="*@example.org" required>
- <input type="hidden" name="object_list" value="wl">
- <input type="hidden" name="domain" value="<?=$domain;?>">
- </div>
- <div class="col-xs-6">
- <button type="submit" name="add_policy_list_item" class="btn btn-xs btn-default"><?=$lang['user']['spamfilter_table_add'];?></button>
- </div>
- </form>
- </div>
- </div>
+ </div>
+ <form class="form-inline" method="post">
+ <div class="input-group">
+ <input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
+ <input type="hidden" name="domain" value="<?= $domain ;?>">
+ <input type="hidden" name="object_list" value="wl">
+ <span class="input-group-btn">
+ <button type="submit" id="add_policy_list_item" name="add_policy_list_item" class="btn btn-default"><?=$lang['user']['spamfilter_table_add'];?></button>
+ </span>
+ </div>
+ </form>
+ </div>
<div class="col-sm-6">
- <h4><span class="glyphicon glyphicon-thumbs-down" aria-hidden="true"></span> <?=$lang['user']['spamfilter_bl'];?></h4>
- <p><?=$lang['user']['spamfilter_bl_desc'];?></p>
- <div class="row">
- <div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_rule'];?></b></div>
- <div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_action'];?></b></div>
- </div>
- <?php
- if (empty($get_policy_list['blacklist'])):
- ?>
- <div class="row">
- <div class="col-sm-12"><i><?=$lang['user']['spamfilter_table_empty'];?></i></div>
- </div>
- <?php
- else:
- foreach($get_policy_list['blacklist'] as $bl):
- ?>
- <div class="row striped">
- <form class="form-inline" method="post">
- <div class="col-xs-6"><code><?=$bl['value'];?></code></div>
- <div class="col-xs-6">
- <input type="hidden" name="delete_prefid" value="<?=$bl['prefid'];?>">
- <?php
- if ($bl['object'] == $domain):
- ?>
- <input type="hidden" name="delete_policy_list_item">
- <input type="hidden" name="domain" value="<?=$domain;?>">
- <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a>
- <?php
- else:
- ?>
- <span style="cursor:not-allowed"><?=$lang['user']['spamfilter_table_domain_policy'];?></span>
- <?php
- endif;
- ?>
- </div>
- </form>
+ <h4><?=$lang['user']['spamfilter_bl'];?></h4>
+ <p><?=$lang['user']['spamfilter_bl_desc'];?></p>
+ <div class="table-responsive">
+ <table class="table table-striped table-condensed" id="bl_policy_domain_table"></table>
+ </div>
+ <div class="mass-actions-user">
+ <div class="btn-group">
+ <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="policy_bl_domain" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+ <a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_bl_domain" data-api-url='delete/policy_mailbox' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+ </ul>
</div>
- <?php
- endforeach;
- endif;
- ?>
- <hr style="margin:5px 0px 7px 0px">
- <div class="row">
- <form class="form-inline" method="post">
- <div class="col-xs-6">
- <input type="text" class="form-control input-sm" name="object_from" id="object_from" placeholder="*@example.org" required>
- <input type="hidden" name="object_list" value="bl">
- <input type="hidden" name="domain" value="<?=$domain;?>">
- </div>
- <div class="col-xs-6">
- <button type="submit" name="add_policy_list_item" class="btn btn-xs btn-default"><?=$lang['user']['spamfilter_table_add'];?></button>
- </div>
- </form>
- </div>
- </div>
- </div>
+ </div>
+ <form class="form-inline" method="post">
+ <div class="input-group">
+ <input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
+ <input type="hidden" name="domain" value="<?= $domain ;?>">
+ <input type="hidden" name="object_list" value="bl">
+ <span class="input-group-btn">
+ <button type="submit" id="add_policy_list_item" name="add_policy_list_item" class="btn btn-default"><?=$lang['user']['spamfilter_table_add'];?></button>
+ </span>
+ </div>
+ </form>
+ </div>
+ </div>
<?php
}
else {
@@ -350,7 +285,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
is_valid_domain_name($_GET["aliasdomain"]) &&
!empty($_GET["aliasdomain"])) {
$alias_domain = $_GET["aliasdomain"];
- $result = mailbox_get_alias_domain_details($alias_domain);
+ $result = mailbox('get', 'alias_domain_details', $alias_domain);
if (!empty($result)) {
?>
<h4><?=$lang['edit']['edit_alias_domain'];?></h4>
@@ -399,7 +334,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
}
elseif (isset($_GET['mailbox']) && filter_var($_GET["mailbox"], FILTER_VALIDATE_EMAIL) && !empty($_GET["mailbox"])) {
$mailbox = $_GET["mailbox"];
- $result = mailbox_get_mailbox_details($mailbox);
+ $result = mailbox('get', 'mailbox_details', $mailbox);
if (!empty($result)) {
?>
<h4><?=$lang['edit']['mailbox'];?></h4>
@@ -426,7 +361,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
<div class="col-sm-10">
<select data-width="100%" style="width:100%" id="sender_acl" name="sender_acl[]" size="10" multiple>
<?php
- $sender_acl_handles = mailbox_get_sender_acl_handles($mailbox);
+ $sender_acl_handles = mailbox('get', 'sender_acl_handles', $mailbox);
foreach ($sender_acl_handles['sender_acl_domains']['ro'] as $domain):
?>
@@ -504,7 +439,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
}
elseif (isset($_GET['resource']) && filter_var($_GET["resource"], FILTER_VALIDATE_EMAIL) && !empty($_GET["resource"])) {
$resource = $_GET["resource"];
- $result = mailbox_get_resource_details($resource);
+ $result = mailbox('get', 'resource_details', $resource);
if (!empty($result)) {
?>
<h4><?=$lang['edit']['resource'];?></h4>
@@ -566,7 +501,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] ==
if (isset($_GET['syncjob']) &&
is_numeric($_GET['syncjob'])) {
$id = $_GET["syncjob"];
- $result = get_syncjob_details($id);
+ $result = mailbox('get', 'syncjob_details', $id);
if (!empty($result)) {
?>
<h4><?=$lang['edit']['syncjob'];?></h4>
@@ -686,6 +621,17 @@ else {
</div>
<a href="<?=$_SESSION['return_to'];?>">← <?=$lang['edit']['previous'];?></a>
</div> <!-- /container -->
+<script type='text/javascript'>
+<?php
+$lang_user = json_encode($lang['user']);
+echo "var lang = ". $lang_user . ";\n";
+echo "var table_for_domain = '". ((isset($domain)) ? $domain : null) . "';\n";
+echo "var csrf_token = '". $_SESSION['CSRF']['TOKEN'] . "';\n";
+echo "var pagination_size = '". $PAGINATION_SIZE . "';\n";
+?>
+</script>
+<script src="js/footable.min.js"></script>
+<script src="js/edit.js"></script>
<?php
require_once("inc/footer.inc.php");
?>
diff --git a/data/web/inc/footer.inc.php b/data/web/inc/footer.inc.php
index eb2d9ce8..d364a4df 100644
--- a/data/web/inc/footer.inc.php
+++ b/data/web/inc/footer.inc.php
@@ -31,7 +31,7 @@ endif;
<h4 class="modal-title"><?= $lang['footer']['confirm_delete']; ?></h4>
</div>
<div class="modal-body">
- <p><?= $lang['footer']['delete_these_items']; ?></p>
+ <p id="DeleteText"><?= $lang['footer']['delete_these_items']; ?></p>
<ul id="ItemsToDelete"></ul>
<hr>
<button class="btn btn-sm btn-danger" id="IsConfirmed"><?= $lang['footer']['delete_now']; ?></button>
@@ -48,6 +48,7 @@ endif;
<script src="/js/bootstrap-select.min.js"></script>
<script src="/js/notifications.min.js"></script>
<script src="/js/u2f-api.js"></script>
+<script src="/js/api.js"></script>
<script>
// Select language and reopen active URL without POST
function setLang(sel) {
diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php
index 40e6a86a..28f76bfd 100644
--- a/data/web/inc/functions.inc.php
+++ b/data/web/inc/functions.inc.php
@@ -278,209 +278,6 @@ function edit_admin_account($postarray) {
'msg' => sprintf($lang['success']['admin_modified'])
);
}
-function set_time_limited_aliases($postarray) {
- global $lang;
- global $pdo;
- (isset($postarray['username'])) ? $username = $postarray['username'] : $username = $_SESSION['mailcow_cc_username'];
-
- if ($_SESSION['mailcow_cc_role'] != "user" &&
- $_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (filter_var($username, FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- }
-
- try {
- $stmt = $pdo->prepare("SELECT `domain` FROM `mailbox` WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- $domain = $stmt->fetch(PDO::FETCH_ASSOC)['domain'];
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-
- switch ($postarray["set_time_limited_aliases"]) {
- case "generate":
- if (!is_numeric($postarray["validity"]) || $postarray["validity"] > 672) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['validity_missing'])
- );
- return false;
- }
- $validity = strtotime("+".$postarray["validity"]." hour");
- $letters = 'abcefghijklmnopqrstuvwxyz1234567890';
- $random_name = substr(str_shuffle($letters), 0, 24);
- try {
- $stmt = $pdo->prepare("INSERT INTO `spamalias` (`address`, `goto`, `validity`) VALUES
- (:address, :goto, :validity)");
- $stmt->execute(array(
- ':address' => $random_name . '@' . $domain,
- ':goto' => $username,
- ':validity' => $validity
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
- );
- break;
- case "deleteall":
- try {
- $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
- );
- break;
- case "delete":
- if (empty($postarray['item']) || !filter_var($postarray['item'], FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- $item = $postarray['item'];
- try {
- $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username AND `address` = :item");
- $stmt->execute(array(
- ':username' => $username,
- ':item' => $item
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
- );
- break;
- case "extendall":
- try {
- $stmt = $pdo->prepare("UPDATE `spamalias` SET `validity` = (`validity` + 3600) WHERE
- `goto` = :username AND
- `validity` >= :validity");
- $stmt->execute(array(
- ':username' => $username,
- ':validity' => time(),
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
- );
- break;
- case "extend":
- if (empty($postarray['item']) || !filter_var($postarray['item'], FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- $item = $postarray['item'];
- try {
- $stmt = $pdo->prepare("UPDATE `spamalias` SET `validity` = (`validity` + 3600) WHERE
- `goto` = :username AND
- `address` = :item AND
- `validity` >= :validity");
- $stmt->execute(array(
- ':username' => $username,
- ':item' => $item,
- ':validity' => time(),
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
- );
- break;
- }
-}
-function get_time_limited_aliases($username = null) {
- // 'username' can be be set, if not, default to mailcow_cc_username
- global $lang;
- global $pdo;
- $data = array();
- if (isset($username) && filter_var($username, FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
- return false;
- }
- }
- else {
- $username = $_SESSION['mailcow_cc_username'];
- }
- try {
- $stmt = $pdo->prepare("SELECT `address`,
- `goto`,
- `validity`
- FROM `spamalias`
- WHERE `goto` = :username
- AND `validity` >= :unixnow");
- $stmt->execute(array(':username' => $username, ':unixnow' => time()));
- $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- }
- return $data;
-}
function edit_user_account($postarray) {
global $lang;
global $pdo;
@@ -557,241 +354,230 @@ function edit_user_account($postarray) {
'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
);
}
-function get_spam_score($username = null) {
+function user_get_alias_details($username) {
+ global $lang;
global $pdo;
- $default = "5, 15";
- if (isset($username) && filter_var($username, FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
- return false;
+ if ($_SESSION['mailcow_cc_role'] == "user") {
+ $username = $_SESSION['mailcow_cc_username'];
+ }
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ return false;
+ }
+ try {
+ $data['address'] = $username;
+ $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '✘') AS `aliases` FROM `alias`
+ WHERE `goto` REGEXP :username_goto
+ AND `address` NOT LIKE '@%'
+ AND `address` != :username_address");
+ $stmt->execute(array(':username_goto' => '(^|,)'.$username.'($|,)', ':username_address' => $username));
+ $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($run)) {
+ $data['aliases'] = $row['aliases'];
+ }
+ $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(local_part, '@', alias_domain SEPARATOR ', '), '✘') AS `ad_alias` FROM `mailbox`
+ LEFT OUTER JOIN `alias_domain` on `target_domain` = `domain`
+ WHERE `username` = :username ;");
+ $stmt->execute(array(':username' => $username));
+ $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($run)) {
+ $data['ad_alias'] = $row['ad_alias'];
+ }
+ $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '✘') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` NOT LIKE '@%';");
+ $stmt->execute(array(':username' => $username));
+ $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($run)) {
+ $data['aliases_also_send_as'] = $row['send_as'];
+ }
+ $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '✘') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` LIKE '@%';");
+ $stmt->execute(array(':username' => $username));
+ $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($run)) {
+ $data['aliases_send_as_all'] = $row['send_as'];
+ }
+ $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '✘') as `address` FROM `alias` WHERE `goto` REGEXP :username AND `address` LIKE '@%';");
+ $stmt->execute(array(':username' => '(^|,)'.$username.'($|,)'));
+ $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($run)) {
+ $data['is_catch_all'] = $row['address'];
}
+ return $data;
}
- else {
- $username = $_SESSION['mailcow_cc_username'];
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
}
- try {
- $stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `object` = :username AND
- (`option` = 'lowspamlevel' OR `option` = 'highspamlevel')");
- $stmt->execute(array(':username' => $username));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
+}
+function is_valid_domain_name($domain_name) {
+ if (empty($domain_name)) {
return false;
}
- if (empty($num_results)) {
- return $default;
- }
- else {
- try {
- $stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `option` = 'highspamlevel' AND `object` = :username");
- $stmt->execute(array(':username' => $username));
- $highspamlevel = $stmt->fetch(PDO::FETCH_ASSOC);
-
- $stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `option` = 'lowspamlevel' AND `object` = :username");
- $stmt->execute(array(':username' => $username));
- $lowspamlevel = $stmt->fetch(PDO::FETCH_ASSOC);
-
- return $lowspamlevel['value'].', '.$highspamlevel['value'];
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
+ $domain_name = idn_to_ascii($domain_name);
+ return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name)
+ && preg_match("/^.{1,253}$/", $domain_name)
+ && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name));
}
-function edit_spam_score($postarray) {
- // Array items
- // 'username' can be set, defaults to mailcow_cc_username
- // 'lowspamlevel'
- // 'highspamlevel'
+function add_domain_admin($postarray) {
global $lang;
global $pdo;
- if (isset($postarray['username']) && filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $postarray['username'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- else {
- $username = $postarray['username'];
- }
- }
- else {
- $username = $_SESSION['mailcow_cc_username'];
- }
- $lowspamlevel = explode(',', $postarray['score'])[0];
- $highspamlevel = explode(',', $postarray['score'])[1];
+ $username = strtolower(trim($postarray['username']));
+ $password = $postarray['password'];
+ $password2 = $postarray['password2'];
+ $active = intval($postarray['active']);
- if (!is_numeric($lowspamlevel) || !is_numeric($highspamlevel)) {
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
- try {
- $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username
- AND (`option` = 'lowspamlevel' OR `option` = 'highspamlevel')");
- $stmt->execute(array(
- ':username' => $username
- ));
-
- $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option`, `value`)
- VALUES (:username, 'highspamlevel', :highspamlevel)");
- $stmt->execute(array(
- ':username' => $username,
- ':highspamlevel' => $highspamlevel
- ));
-
- $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option`, `value`)
- VALUES (:username, 'lowspamlevel', :lowspamlevel)");
- $stmt->execute(array(
- ':username' => $username,
- ':lowspamlevel' => $lowspamlevel
- ));
+ if (empty($postarray['domain'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
}
- catch (PDOException $e) {
- $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username
- AND (`option` = 'lowspamlevel' OR `option` = 'highspamlevel')");
- $stmt->execute(array(
- ':username' => $username
- ));
+ if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username)) || empty ($username)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
+ WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+
+ $stmt = $pdo->prepare("SELECT `username` FROM `admin`
+ WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+
+ $stmt = $pdo->prepare("SELECT `username` FROM `domain_admins`
+ WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ }
+ catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
- );
-}
-function get_policy_list($object = null) {
- // 'object' can be be set, if not, default to mailcow_cc_username
- global $lang;
- global $pdo;
- if (isset($object)) {
- if (!filter_var($object, FILTER_VALIDATE_EMAIL) && is_valid_domain_name($object)) {
- $object = idn_to_ascii(strtolower(trim($object)));
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
- return false;
- }
- }
- elseif (filter_var($object, FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
- return false;
- }
+ foreach ($num_results as $num_results_each) {
+ if ($num_results_each != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($username))
+ );
+ return false;
+ }
+ }
+ if (!empty($password) && !empty($password2)) {
+ if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_complexity'])
+ );
+ return false;
}
- }
- else {
- $object = $_SESSION['mailcow_cc_username'];
- }
- try {
- // WHITELIST
- $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='whitelist_from' AND (`object` = :username OR `object` = SUBSTRING_INDEX(:username_domain, '@' ,-1))");
- $stmt->execute(array(':username' => $object, ':username_domain' => $object));
- $rows['whitelist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
- // BLACKLIST
- $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='blacklist_from' AND (`object` = :username OR `object` = SUBSTRING_INDEX(:username_domain, '@' ,-1))");
- $stmt->execute(array(':username' => $object, ':username_domain' => $object));
- $rows['blacklist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- }
- return $rows;
-}
-function add_policy_list_item($postarray) {
- // Array data
- // Either 'domain' or 'username' can be be set
- // If none of the above is set, default to mailcow_cc_username
- //
- // If 'delete_prefid' then delete item id
- global $lang;
- global $pdo;
- $object = (isset($postarray['username'])) ? $postarray['username'] : null;
- $object = (isset($postarray['domain'])) ? $postarray['domain'] : null;
- (!isset($object)) ? $object = $_SESSION['mailcow_cc_username'] : null;
-
- if (is_valid_domain_name($object)) {
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
+ if ($password != $password2) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
+ 'msg' => sprintf($lang['danger']['password_mismatch'])
);
return false;
}
- $object = idn_to_ascii(strtolower(trim($object)));
- }
- else {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
+ $password_hashed = hash_password($password);
+ foreach ($postarray['domain'] as $domain) {
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
+ VALUES (:username, :domain, :created, :active)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':domain' => $domain,
+ ':created' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ }
+ catch (PDOException $e) {
+ delete_domain_admin(array('username' => $username));
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `active`)
+ VALUES (:username, :password_hashed, '0', :active)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':password_hashed' => $password_hashed,
+ ':active' => $active
+ ));
+ }
+ catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
+ 'msg' => 'MySQL: '.$e
);
return false;
}
- }
-
- ($postarray['object_list'] == "bl") ? $object_list = "blacklist_from" : null;
- ($postarray['object_list'] == "wl") ? $object_list = "whitelist_from" : null;
- $object_from = preg_replace('/\.+/', '.', rtrim(preg_replace("/\.\*/", "*", trim(strtolower($postarray['object_from']))), '.'));
- if (!ctype_alnum(str_replace(array('@', '.', '-', '*'), '', $object_from))) {
+ }
+ else {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => sprintf($lang['danger']['policy_list_from_invalid'])
+ 'msg' => sprintf($lang['danger']['password_empty'])
);
return false;
}
- if ($object_list != "blacklist_from" && $object_list != "whitelist_from") {
- $_SESSION['return'] = array(
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_admin_added'], htmlspecialchars($username))
+ );
+}
+function delete_domain_admin($postarray) {
+ global $pdo;
+ global $lang;
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
- try {
- $stmt = $pdo->prepare("SELECT `object` FROM `filterconf`
- WHERE (`option` = 'whitelist_from' OR `option` = 'blacklist_from')
- AND `object` = :object
- AND `value` = :object_from");
- $stmt->execute(array(':object' => $object, ':object_from' => $object_from));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['policy_list_from_exists'])
- );
- return false;
- }
- }
- catch(PDOException $e) {
+ $username = $postarray['username'];
+ if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => 'MySQL: '.$e
+ 'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
-
try {
- $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option` ,`value`)
- VALUES (:object, :object_list, :object_from)");
+ $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `admin` WHERE `username` = :username");
$stmt->execute(array(
- ':object' => $object,
- ':object_list' => $object_list,
- ':object_from' => $object_from
+ ':username' => $username,
));
}
catch (PDOException $e) {
@@ -803,91 +589,32 @@ function add_policy_list_item($postarray) {
}
$_SESSION['return'] = array(
'type' => 'success',
- 'msg' => sprintf($lang['success']['object_modified'], $object)
+ 'msg' => sprintf($lang['success']['domain_admin_removed'], htmlspecialchars($username))
);
}
-function delete_policy_list_item($postarray) {
- // Array data
- // Either 'domain' or 'username' can be be set
- // If none of the above is set, default to mailcow_cc_username
- //
- // 'delete_prefid' is item to be deleted
- global $lang;
+function get_domain_admins() {
global $pdo;
- $object = (isset($postarray['username'])) ? $postarray['username'] : null;
- $object = (isset($postarray['domain'])) ? $postarray['domain'] : null;
- (!isset($object)) ? $object = $_SESSION['mailcow_cc_username'] : null;
-
- if (is_valid_domain_name($object)) {
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- $object = idn_to_ascii(strtolower(trim($object)));
- }
- else {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- }
-
- if (!is_numeric($postarray['delete_prefid'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :object AND `prefid` = :prefid");
- $stmt->execute(array(
- ':object' => $object,
- ':prefid' => $postarray['delete_prefid']
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['object_modified'], $object)
- );
- return true;
-}
-function get_syncjobs($username = null) {
- // 'username' can be set, if not set, defaults to mailcow_cc_username
global $lang;
- global $pdo;
- $data = array();
- if (isset($username) && filter_var($username, FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
- return false;
- }
- }
- else {
- $username = $_SESSION['mailcow_cc_username'];
- }
+ $domainadmins = array();
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
try {
- $stmt = $pdo->prepare("SELECT *,
- CONCAT(LEFT(`password1`, 3), '...') AS `password1_short`,
- `active` AS `active_int`,
- CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
- FROM `imapsync`
- WHERE `user2` = :username");
- $stmt->execute(array(':username' => $username));
- $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ $stmt = $pdo->query("SELECT DISTINCT
+ `username`
+ FROM `domain_admins`
+ WHERE `username` IN (
+ SELECT `username` FROM `admin`
+ WHERE `superadmin`!='1'
+ )");
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($rows)) {
+ $domainadmins[] = $row['username'];
+ }
}
catch(PDOException $e) {
$_SESSION['return'] = array(
@@ -895,3541 +622,274 @@ function get_syncjobs($username = null) {
'msg' => 'MySQL: '.$e
);
}
- return $data;
+ return $domainadmins;
}
-function get_syncjob_details($id) {
- global $lang;
+function get_domain_admin_details($domain_admin) {
global $pdo;
- $syncjobdetails = array();
- if ($_SESSION['mailcow_cc_role'] != "user" &&
- $_SESSION['mailcow_cc_role'] != "admin") {
- return false;
+
+ global $lang;
+ $domainadmindata = array();
+ if (isset($domain_admin) && $_SESSION['mailcow_cc_role'] != "admin") {
+ return false;
+ }
+ if (!isset($domain_admin) && $_SESSION['mailcow_cc_role'] != "domainadmin") {
+ return false;
+ }
+ (!isset($domain_admin)) ? $domain_admin = $_SESSION['mailcow_cc_username'] : null;
+
+ if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $domain_admin))) {
+ return false;
}
- if (!is_numeric($id)) {
- return false;
- }
- try {
- $stmt = $pdo->prepare("SELECT * FROM `imapsync` WHERE (`user2` = :username OR 'admin' = :role) AND id = :id");
- $stmt->execute(array(':id' => $id, ':role' => $_SESSION['mailcow_cc_role'], ':username' => $_SESSION['mailcow_cc_username']));
- $syncjobdetails = $stmt->fetch(PDO::FETCH_ASSOC);
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- }
- return $syncjobdetails;
-}
-function delete_syncjob($postarray) {
- // Array items
- // 'username' can be set, defaults to mailcow_cc_username
- global $lang;
- global $pdo;
- if (isset($postarray['username']) && filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $postarray['username'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- else {
- $username = $postarray['username'];
- }
- }
- else {
- $username = $_SESSION['mailcow_cc_username'];
- }
- $id = $postarray['id'];
- if (!is_numeric($id)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("DELETE FROM `imapsync` WHERE `user2` = :username AND `id`= :id");
- $stmt->execute(array(
- ':username' => $username,
- ':id' => $id,
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
- );
- return true;
-}
-function add_syncjob($postarray) {
- // Array items
- // 'username' can be set, defaults to mailcow_cc_username
- global $lang;
- global $pdo;
- if (isset($postarray['username']) && filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $postarray['username'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- else {
- $username = $postarray['username'];
- }
- }
- else {
- $username = $_SESSION['mailcow_cc_username'];
- }
-
- $active = intval($postarray['active']);
- $delete2duplicates = intval($postarray['delete2duplicates']);
- $delete1 = intval($postarray['delete1']);
- $port1 = $postarray['port1'];
- $host1 = $postarray['host1'];
- $password1 = $postarray['password1'];
- $exclude = $postarray['exclude'];
- $maxage = $postarray['maxage'];
- $subfolder2 = $postarray['subfolder2'];
- $user1 = $postarray['user1'];
- $mins_interval = $postarray['mins_interval'];
- $enc1 = $postarray['enc1'];
-
- if (empty($subfolder2)) {
- $subfolder2 = "";
- }
- if (!isset($maxage) || !filter_var($maxage, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 32767)))) {
- $maxage = "0";
- }
- if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (!is_valid_domain_name($host1)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (@preg_match("/" . $exclude . "/", null) === false) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("SELECT `user2`, `user1` FROM `imapsync`
- WHERE `user2` = :user2 AND `user1` = :user1");
- $stmt->execute(array(':user1' => $user1, ':user2' => $username));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($host1 . ' / ' . $user1))
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("INSERT INTO `imapsync` (`user2`, `exclude`, `delete1`, `maxage`, `subfolder2`, `host1`, `authmech1`, `user1`, `password1`, `mins_interval`, `port1`, `enc1`, `delete2duplicates`, `active`)
- VALUES (:user2, :exclude, :maxage, :delete1, :subfolder2, :host1, :authmech1, :user1, :password1, :mins_interval, :port1, :enc1, :delete2duplicates, :active)");
- $stmt->execute(array(
- ':user2' => $username,
- ':exclude' => $exclude,
- ':maxage' => $maxage,
- ':delete1' => $delete1,
- ':subfolder2' => $subfolder2,
- ':host1' => $host1,
- ':authmech1' => 'PLAIN',
- ':user1' => $user1,
- ':password1' => $password1,
- ':mins_interval' => $mins_interval,
- ':port1' => $port1,
- ':enc1' => $enc1,
- ':delete2duplicates' => $delete2duplicates,
- ':active' => $active,
- ));
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
- );
- return true;
-}
-function edit_syncjob($postarray) {
- // Array items
- global $lang;
- global $pdo;
- if (!is_array($postarray['id'])) {
- $ids = array();
- $ids[] = $postarray['id'];
- }
- else {
- $ids = $postarray['id'];
- }
-
- foreach ($ids as $id) {
- $is_now = get_syncjob_details($id);
- if (!empty($is_now)) {
- $username = $is_now['user2'];
- $user1 = (!empty($postarray['user1'])) ? $postarray['user1'] : $is_now['user1'];
- $active = (isset($postarray['active'])) ? $postarray['active'] : $is_now['active_int'];
- $delete2duplicates = (isset($postarray['delete2duplicates'])) ? $postarray['delete2duplicates'] : $is_now['delete2duplicates'];
- $delete1 = (isset($postarray['delete1'])) ? $postarray['delete1'] : $is_now['delete1'];
- $port1 = (!empty($postarray['port1'])) ? $postarray['port1'] : $is_now['port1'];
- $password1 = (!empty($postarray['password1'])) ? $postarray['password1'] : $is_now['password1'];
- $host1 = (!empty($postarray['host1'])) ? $postarray['host1'] : $is_now['host1'];
- $subfolder2 = (!empty($postarray['subfolder2'])) ? $postarray['subfolder2'] : $is_now['subfolder2'];
- $enc1 = (!empty($postarray['enc1'])) ? $postarray['enc1'] : $is_now['enc1'];
- $mins_interval = (!empty($postarray['mins_interval'])) ? $postarray['mins_interval'] : $is_now['mins_interval'];
- $exclude = (!empty($postarray['exclude'])) ? $postarray['exclude'] : $is_now['exclude'];
- $maxage = (!empty($postarray['maxage'])) ? $postarray['maxage'] : $is_now['maxage'];
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (empty($subfolder2)) {
- $subfolder2 = "";
- }
- if (!isset($maxage) || !filter_var($maxage, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 32767)))) {
- $maxage = "0";
- }
- if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (!is_valid_domain_name($host1)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (@preg_match("/" . $exclude . "/", null) === false) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("UPDATE `imapsync` SET `delete1` = :delete1, `maxage` = :maxage, `subfolder2` = :subfolder2, `exclude` = :exclude, `host1` = :host1, `user1` = :user1, `password1` = :password1, `mins_interval` = :mins_interval, `port1` = :port1, `enc1` = :enc1, `delete2duplicates` = :delete2duplicates, `active` = :active
- WHERE `id` = :id");
- $stmt->execute(array(
- ':delete1' => $delete1,
- ':id' => $id,
- ':exclude' => $exclude,
- ':maxage' => $maxage,
- ':subfolder2' => $subfolder2,
- ':host1' => $host1,
- ':user1' => $user1,
- ':password1' => $password1,
- ':mins_interval' => $mins_interval,
- ':port1' => $port1,
- ':enc1' => $enc1,
- ':delete2duplicates' => $delete2duplicates,
- ':active' => $active,
- ));
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
- );
- return true;
-}
-function edit_tls_policy($postarray) {
- global $lang;
- global $pdo;
- if (isset($postarray['username']) && filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $postarray['username'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- else {
- $username = $postarray['username'];
- }
- }
- else {
- $username = $_SESSION['mailcow_cc_username'];
- }
- $tls_out = intval($postarray['tls_out']);
- $tls_in = intval($postarray['tls_in']);
- $username = $_SESSION['mailcow_cc_username'];
- if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("UPDATE `mailbox` SET `tls_enforce_out` = :tls_out, `tls_enforce_in` = :tls_in WHERE `username` = :username");
- $stmt->execute(array(
- ':tls_out' => $tls_out,
- ':tls_in' => $tls_in,
- ':username' => $username
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
- );
-}
-function get_tls_policy($username = null) {
- global $lang;
- global $pdo;
- $data = array();
- if (isset($username) && filter_var($username, FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
- return false;
- }
- }
- else {
- $username = $_SESSION['mailcow_cc_username'];
- }
- try {
- $stmt = $pdo->prepare("SELECT `tls_enforce_out`, `tls_enforce_in` FROM `mailbox` WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- $data = $stmt->fetch(PDO::FETCH_ASSOC);
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- return $data;
-}
-function edit_delimiter_action($postarray) {
- // Array items
- // 'username' can be set, defaults to mailcow_cc_username
- global $lang;
- global $redis;
- if (isset($postarray['username']) && filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $postarray['username'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- else {
- $username = $postarray['username'];
- }
- }
- else {
- $username = $_SESSION['mailcow_cc_username'];
- }
- if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
- );
- return false;
- }
- if (isset($postarray['tagged_mail_handler']) && $postarray['tagged_mail_handler'] == "subject") {
- try {
- $redis->hSet('RCPT_WANTS_SUBJECT_TAG', $username, 1);
- }
- catch (RedisException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'Redis: '.$e
- );
- return false;
- }
- }
- else {
- try {
- $redis->hDel('RCPT_WANTS_SUBJECT_TAG', $username);
- }
- catch (RedisException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'Redis: '.$e
- );
- return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
- );
- return true;
-}
-function get_delimiter_action($username = null) {
- // 'username' can be set, defaults to mailcow_cc_username
- global $lang;
- global $redis;
- $data = array();
- if (isset($username) && filter_var($username, FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
- return false;
- }
- }
- else {
- $username = $_SESSION['mailcow_cc_username'];
- }
- try {
- if ($redis->hGet('RCPT_WANTS_SUBJECT_TAG', $username)) {
- return "subject";
- }
- else {
- return "subfolder";
- }
- }
- catch (RedisException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'Redis: '.$e
- );
- return false;
- }
-}
-function user_get_alias_details($username) {
- global $lang;
- global $pdo;
- if ($_SESSION['mailcow_cc_role'] == "user") {
- $username = $_SESSION['mailcow_cc_username'];
- }
- if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
- return false;
- }
- try {
- $data['address'] = $username;
- $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '✘') AS `aliases` FROM `alias`
- WHERE `goto` REGEXP :username_goto
- AND `address` NOT LIKE '@%'
- AND `address` != :username_address");
- $stmt->execute(array(':username_goto' => '(^|,)'.$username.'($|,)', ':username_address' => $username));
- $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($run)) {
- $data['aliases'] = $row['aliases'];
- }
- $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(local_part, '@', alias_domain SEPARATOR ', '), '✘') AS `ad_alias` FROM `mailbox`
- LEFT OUTER JOIN `alias_domain` on `target_domain` = `domain`
- WHERE `username` = :username ;");
- $stmt->execute(array(':username' => $username));
- $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($run)) {
- $data['ad_alias'] = $row['ad_alias'];
- }
- $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '✘') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` NOT LIKE '@%';");
- $stmt->execute(array(':username' => $username));
- $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($run)) {
- $data['aliases_also_send_as'] = $row['send_as'];
- }
- $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '✘') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` LIKE '@%';");
- $stmt->execute(array(':username' => $username));
- $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($run)) {
- $data['aliases_send_as_all'] = $row['send_as'];
- }
- $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '✘') as `address` FROM `alias` WHERE `goto` REGEXP :username AND `address` LIKE '@%';");
- $stmt->execute(array(':username' => '(^|,)'.$username.'($|,)'));
- $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($run)) {
- $data['is_catch_all'] = $row['address'];
- }
- return $data;
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-}
-function is_valid_domain_name($domain_name) {
- if (empty($domain_name)) {
- return false;
- }
- $domain_name = idn_to_ascii($domain_name);
- return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name)
- && preg_match("/^.{1,253}$/", $domain_name)
- && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name));
-}
-function add_domain_admin($postarray) {
- global $lang;
- global $pdo;
- $username = strtolower(trim($postarray['username']));
- $password = $postarray['password'];
- $password2 = $postarray['password2'];
- $active = intval($postarray['active']);
-
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (empty($postarray['domain'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
- if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username)) || empty ($username)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
- WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
-
- $stmt = $pdo->prepare("SELECT `username` FROM `admin`
- WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
-
- $stmt = $pdo->prepare("SELECT `username` FROM `domain_admins`
- WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- foreach ($num_results as $num_results_each) {
- if ($num_results_each != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($username))
- );
- return false;
- }
- }
- if (!empty($password) && !empty($password2)) {
- if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_complexity'])
- );
- return false;
- }
- if ($password != $password2) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_mismatch'])
- );
- return false;
- }
- $password_hashed = hash_password($password);
- foreach ($postarray['domain'] as $domain) {
- if (!is_valid_domain_name($domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
- VALUES (:username, :domain, :created, :active)");
- $stmt->execute(array(
- ':username' => $username,
- ':domain' => $domain,
- ':created' => date('Y-m-d H:i:s'),
- ':active' => $active
- ));
- }
- catch (PDOException $e) {
- delete_domain_admin(array('username' => $username));
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- try {
- $stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `active`)
- VALUES (:username, :password_hashed, '0', :active)");
- $stmt->execute(array(
- ':username' => $username,
- ':password_hashed' => $password_hashed,
- ':active' => $active
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_empty'])
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_admin_added'], htmlspecialchars($username))
- );
-}
-function delete_domain_admin($postarray) {
- global $pdo;
- global $lang;
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- $username = $postarray['username'];
- if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
- $stmt->execute(array(
- ':username' => $username,
- ));
- $stmt = $pdo->prepare("DELETE FROM `admin` WHERE `username` = :username");
- $stmt->execute(array(
- ':username' => $username,
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_admin_removed'], htmlspecialchars($username))
- );
-}
-function get_domain_admins() {
- global $pdo;
- global $lang;
- $domainadmins = array();
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- try {
- $stmt = $pdo->query("SELECT DISTINCT
- `username`
- FROM `domain_admins`
- WHERE `username` IN (
- SELECT `username` FROM `admin`
- WHERE `superadmin`!='1'
- )");
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($rows)) {
- $domainadmins[] = $row['username'];
- }
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- }
- return $domainadmins;
-}
-function get_domain_admin_details($domain_admin) {
- global $pdo;
-
- global $lang;
- $domainadmindata = array();
- if (isset($domain_admin) && $_SESSION['mailcow_cc_role'] != "admin") {
- return false;
- }
- if (!isset($domain_admin) && $_SESSION['mailcow_cc_role'] != "domainadmin") {
- return false;
- }
- (!isset($domain_admin)) ? $domain_admin = $_SESSION['mailcow_cc_username'] : null;
-
- if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $domain_admin))) {
- return false;
- }
- try {
- $stmt = $pdo->prepare("SELECT
- `tfa`.`active` AS `tfa_active_int`,
- CASE `tfa`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `tfa_active`,
- `domain_admins`.`username`,
- `domain_admins`.`created`,
- `domain_admins`.`active` AS `active_int`,
- CASE `domain_admins`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
- FROM `domain_admins`
- LEFT OUTER JOIN `tfa` ON `tfa`.`username`=`domain_admins`.`username`
- WHERE `domain_admins`.`username`= :domain_admin");
- $stmt->execute(array(
- ':domain_admin' => $domain_admin
- ));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- if (empty($row)) {
- return false;
- }
- $domainadmindata['username'] = $row['username'];
- $domainadmindata['tfa_active'] = $row['tfa_active'];
- $domainadmindata['active'] = $row['active'];
- $domainadmindata['tfa_active_int'] = $row['tfa_active_int'];
- $domainadmindata['active_int'] = $row['active_int'];
- $domainadmindata['modified'] = $row['created'];
- // GET SELECTED
- $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
- WHERE `domain` IN (
- SELECT `domain` FROM `domain_admins`
- WHERE `username`= :domain_admin)");
- $stmt->execute(array(':domain_admin' => $domain_admin));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $domainadmindata['selected_domains'][] = $row['domain'];
- }
- // GET UNSELECTED
- $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
- WHERE `domain` NOT IN (
- SELECT `domain` FROM `domain_admins`
- WHERE `username`= :domain_admin)");
- $stmt->execute(array(':domain_admin' => $domain_admin));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $domainadmindata['unselected_domains'][] = $row['domain'];
- }
- if (!isset($domainadmindata['unselected_domains'])) {
- $domainadmindata['unselected_domains'] = "";
- }
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- }
- return $domainadmindata;
-}
-function set_tfa($postarray) {
- global $lang;
- global $pdo;
- global $yubi;
- global $u2f;
- global $tfa;
-
- if ($_SESSION['mailcow_cc_role'] != "domainadmin" &&
- $_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- $username = $_SESSION['mailcow_cc_username'];
-
- $stmt = $pdo->prepare("SELECT `password` FROM `admin`
- WHERE `username` = :user");
- $stmt->execute(array(':user' => $username));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- if (!verify_ssha256($row['password'], $postarray["confirm_password"])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- switch ($postarray["tfa_method"]) {
- case "yubi_otp":
- $key_id = (!isset($postarray["key_id"])) ? 'unidentified' : $postarray["key_id"];
- $yubico_id = $postarray['yubico_id'];
- $yubico_key = $postarray['yubico_key'];
- $yubi = new Auth_Yubico($yubico_id, $yubico_key);
- if (!$yubi) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (!ctype_alnum($postarray["otp_token"]) || strlen($postarray["otp_token"]) != 44) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['tfa_token_invalid'])
- );
- return false;
- }
- $yauth = $yubi->verify($postarray["otp_token"]);
- if (PEAR::isError($yauth)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'Yubico API: ' . $yauth->getMessage()
- );
- return false;
- }
- try {
- // We could also do a modhex translation here
- $yubico_modhex_id = substr($postarray["otp_token"], 0, 12);
- $stmt = $pdo->prepare("DELETE FROM `tfa`
- WHERE `username` = :username
- AND (`authmech` != 'yubi_otp')
- OR (`authmech` = 'yubi_otp' AND `secret` LIKE :modhex)");
- $stmt->execute(array(':username' => $username, ':modhex' => '%' . $yubico_modhex_id));
- $stmt = $pdo->prepare("INSERT INTO `tfa` (`key_id`, `username`, `authmech`, `active`, `secret`) VALUES
- (:key_id, :username, 'yubi_otp', '1', :secret)");
- $stmt->execute(array(':key_id' => $key_id, ':username' => $username, ':secret' => $yubico_id . ':' . $yubico_key . ':' . $yubico_modhex_id));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['object_modified'], htmlspecialchars($username))
- );
- break;
-
- case "u2f":
- $key_id = (!isset($postarray["key_id"])) ? 'unidentified' : $postarray["key_id"];
- try {
- $reg = $u2f->doRegister(json_decode($_SESSION['regReq']), json_decode($postarray['token']));
- $stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username AND `authmech` != 'u2f'");
- $stmt->execute(array(':username' => $username));
- $stmt = $pdo->prepare("INSERT INTO `tfa` (`username`, `key_id`, `authmech`, `keyHandle`, `publicKey`, `certificate`, `counter`, `active`) VALUES (?, ?, 'u2f', ?, ?, ?, ?, '1')");
- $stmt->execute(array($username, $key_id, $reg->keyHandle, $reg->publicKey, $reg->certificate, $reg->counter));
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['object_modified'], $username)
- );
- $_SESSION['regReq'] = null;
- }
- catch (Exception $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => "U2F: " . $e->getMessage()
- );
- $_SESSION['regReq'] = null;
- return false;
- }
- break;
-
- case "totp":
- $key_id = (!isset($postarray["key_id"])) ? 'unidentified' : $postarray["key_id"];
- if ($tfa->verifyCode($_POST['totp_secret'], $_POST['totp_confirm_token']) === true) {
- try {
- $stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- $stmt = $pdo->prepare("INSERT INTO `tfa` (`username`, `key_id`, `authmech`, `secret`, `active`) VALUES (?, ?, 'totp', ?, '1')");
- $stmt->execute(array($username, $key_id, $_POST['totp_secret']));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['object_modified'], $username)
- );
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'TOTP verification failed'
- );
- }
- break;
-
- case "none":
- try {
- $stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['object_modified'], htmlspecialchars($username))
- );
- break;
- }
-}
-function unset_tfa_key($postarray) {
- // Can only unset own keys
- // Needs at least one key left
- global $pdo;
- global $lang;
- $id = intval($postarray['unset_tfa_key']);
- if ($_SESSION['mailcow_cc_role'] != "domainadmin" &&
- $_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- $username = $_SESSION['mailcow_cc_username'];
- try {
- if (!is_numeric($id)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- $stmt = $pdo->prepare("SELECT COUNT(*) AS `keys` FROM `tfa`
- WHERE `username` = :username AND `active` = '1'");
- $stmt->execute(array(':username' => $username));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- if ($row['keys'] == "1") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['last_key'])
- );
- return false;
- }
- $stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username AND `id` = :id");
- $stmt->execute(array(':username' => $username, ':id' => $id));
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['object_modified'], $username)
- );
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-}
-function get_tfa($username = null) {
- global $pdo;
- if (isset($_SESSION['mailcow_cc_username'])) {
- $username = $_SESSION['mailcow_cc_username'];
- }
- elseif (empty($username)) {
- return false;
- }
-
- $stmt = $pdo->prepare("SELECT * FROM `tfa`
- WHERE `username` = :username AND `active` = '1'");
- $stmt->execute(array(':username' => $username));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
-
- switch ($row["authmech"]) {
- case "yubi_otp":
- $data['name'] = "yubi_otp";
- $data['pretty'] = "Yubico OTP";
- $stmt = $pdo->prepare("SELECT `id`, `key_id`, RIGHT(`secret`, 12) AS 'modhex' FROM `tfa` WHERE `authmech` = 'yubi_otp' AND `username` = :username");
- $stmt->execute(array(
- ':username' => $username,
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $data['additional'][] = $row;
- }
- return $data;
- break;
- case "u2f":
- $data['name'] = "u2f";
- $data['pretty'] = "Fido U2F";
- $stmt = $pdo->prepare("SELECT `id`, `key_id` FROM `tfa` WHERE `authmech` = 'u2f' AND `username` = :username");
- $stmt->execute(array(
- ':username' => $username,
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $data['additional'][] = $row;
- }
- return $data;
- break;
- case "hotp":
- $data['name'] = "hotp";
- $data['pretty'] = "HMAC-based OTP";
- return $data;
- break;
- case "totp":
- $data['name'] = "totp";
- $data['pretty'] = "Time-based OTP";
- $stmt = $pdo->prepare("SELECT `id`, `key_id`, `secret` FROM `tfa` WHERE `authmech` = 'totp' AND `username` = :username");
- $stmt->execute(array(
- ':username' => $username,
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $data['additional'][] = $row;
- }
- return $data;
- break;
- default:
- $data['name'] = 'none';
- $data['pretty'] = "-";
- return $data;
- break;
- }
-}
-function verify_tfa_login($username, $token) {
- global $pdo;
- global $lang;
- global $yubi;
- global $u2f;
- global $tfa;
-
- $stmt = $pdo->prepare("SELECT `authmech` FROM `tfa`
- WHERE `username` = :username AND `active` = '1'");
- $stmt->execute(array(':username' => $username));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
-
- switch ($row["authmech"]) {
- case "yubi_otp":
- if (!ctype_alnum($token) || strlen($token) != 44) {
- return false;
- }
- $yubico_modhex_id = substr($token, 0, 12);
- $stmt = $pdo->prepare("SELECT `id`, `secret` FROM `tfa`
- WHERE `username` = :username
- AND `authmech` = 'yubi_otp'
- AND `active`='1'
- AND `secret` LIKE :modhex");
- $stmt->execute(array(':username' => $username, ':modhex' => '%' . $yubico_modhex_id));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- $yubico_auth = explode(':', $row['secret']);
- $yubi = new Auth_Yubico($yubico_auth[0], $yubico_auth[1]);
- $yauth = $yubi->verify($token);
- if (PEAR::isError($yauth)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'Yubico Authentication error: ' . $yauth->getMessage()
- );
- return false;
- }
- else {
- $_SESSION['tfa_id'] = $row['id'];
- return true;
- }
- return false;
- break;
- case "u2f":
- try {
- $reg = $u2f->doAuthenticate(json_decode($_SESSION['authReq']), get_u2f_registrations($username), json_decode($token));
- $stmt = $pdo->prepare("UPDATE `tfa` SET `counter` = ? WHERE `id` = ?");
- $stmt->execute(array($reg->counter, $reg->id));
- $_SESSION['tfa_id'] = $reg->id;
- $_SESSION['authReq'] = null;
- return true;
- }
- catch (Exception $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => "U2F: " . $e->getMessage()
- );
- $_SESSION['regReq'] = null;
- return false;
- }
- return false;
- break;
- case "hotp":
- return false;
- break;
- case "totp":
- try {
- $stmt = $pdo->prepare("SELECT `id`, `secret` FROM `tfa`
- WHERE `username` = :username
- AND `authmech` = 'totp'
- AND `active`='1'");
- $stmt->execute(array(':username' => $username));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- if ($tfa->verifyCode($row['secret'], $_POST['token']) === true) {
- $_SESSION['tfa_id'] = $row['id'];
- return true;
- }
- return false;
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- break;
- default:
- return false;
- break;
- }
- return false;
-}
-function edit_domain_admin($postarray) {
- global $lang;
- global $pdo;
-
- if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- // Administrator
- if ($_SESSION['mailcow_cc_role'] == "admin") {
- $username = $postarray['username'];
- $username_now = $postarray['username_now'];
- $password = $postarray['password'];
- $password2 = $postarray['password2'];
- $active = intval($postarray['active']);
-
- if(isset($postarray['domain'])) {
- foreach ($postarray['domain'] as $domain) {
- if (!is_valid_domain_name($domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
- }
- }
-
- if (empty($postarray['domain'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
-
- if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
- );
- return false;
- }
- if ($username != $username_now) {
- if (empty(get_domain_admin_details($username_now)['username']) || !empty(get_domain_admin_details($username)['username'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
- );
- return false;
- }
- }
- try {
- $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
- $stmt->execute(array(
- ':username' => $username_now,
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-
- if (isset($postarray['domain'])) {
- foreach ($postarray['domain'] as $domain) {
- try {
- $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
- VALUES (:username, :domain, :created, :active)");
- $stmt->execute(array(
- ':username' => $username,
- ':domain' => $domain,
- ':created' => date('Y-m-d H:i:s'),
- ':active' => $active
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- }
-
- if (!empty($password) && !empty($password2)) {
- if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_complexity'])
- );
- return false;
- }
- if ($password != $password2) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_mismatch'])
- );
- return false;
- }
- $password_hashed = hash_password($password);
- try {
- $stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `active` = :active, `password` = :password_hashed WHERE `username` = :username2");
- $stmt->execute(array(
- ':password_hashed' => $password_hashed,
- ':username1' => $username,
- ':username2' => $username_now,
- ':active' => $active
- ));
- if (isset($postarray['disable_tfa'])) {
- $stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
- $stmt->execute(array(':username' => $username_now));
- }
- else {
- $stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username WHERE `username` = :username_now");
- $stmt->execute(array(':username' => $username, ':username_now' => $username_now));
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- else {
- try {
- $stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `active` = :active WHERE `username` = :username2");
- $stmt->execute(array(
- ':username1' => $username,
- ':username2' => $username_now,
- ':active' => $active
- ));
- if (isset($postarray['disable_tfa'])) {
- $stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- }
- else {
- $stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username WHERE `username` = :username_now");
- $stmt->execute(array(':username' => $username, ':username_now' => $username_now));
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars($username))
- );
- }
- // Domain administrator
- // Can only edit itself
- elseif ($_SESSION['mailcow_cc_role'] == "domainadmin") {
- $username = $_SESSION['mailcow_cc_username'];
- $password_old = $postarray['user_old_pass'];
- $password_new = $postarray['user_new_pass'];
- $password_new2 = $postarray['user_new_pass2'];
-
- $stmt = $pdo->prepare("SELECT `password` FROM `admin`
- WHERE `username` = :user");
- $stmt->execute(array(':user' => $username));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- if (!verify_ssha256($row['password'], $password_old)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- if (!empty($password_new2) && !empty($password_new)) {
- if ($password_new2 != $password_new) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_mismatch'])
- );
- return false;
- }
- if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password_new)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_complexity'])
- );
- return false;
- }
- $password_hashed = hash_password($password_new);
- try {
- $stmt = $pdo->prepare("UPDATE `admin` SET `password` = :password_hashed WHERE `username` = :username");
- $stmt->execute(array(
- ':password_hashed' => $password_hashed,
- ':username' => $username
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
-
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars($username))
- );
- }
-}
-function get_admin_details() {
- // No parameter to be given, only one admin should exist
- global $pdo;
- global $lang;
- $data = array();
- if ($_SESSION['mailcow_cc_role'] != 'admin') {
- return false;
- }
- try {
- $stmt = $pdo->prepare("SELECT `username`, `modified`, `created` FROM `admin` WHERE `superadmin`='1' AND active='1'");
- $stmt->execute();
- $data = $stmt->fetch(PDO::FETCH_ASSOC);
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- }
- return $data;
-}
-function dkim_add_key($postarray) {
- global $lang;
- global $pdo;
- global $redis;
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- // if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- // $_SESSION['return'] = array(
- // 'type' => 'danger',
- // 'msg' => sprintf($lang['danger']['access_denied'])
- // );
- // return false;
- // }
- $key_length = intval($postarray['key_size']);
- $dkim_selector = (isset($postarray['dkim_selector'])) ? $postarray['dkim_selector'] : 'dkim';
- $domain = $postarray['domain'];
- if (!is_valid_domain_name($domain) || !is_numeric($key_length)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
- );
- return false;
- }
-
- if (!empty(glob($GLOBALS['MC_DKIM_TXTS'] . '/' . $domain . '.dkim')) ||
- $redis->hGet('DKIM_PUB_KEYS', $domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
- );
- return false;
- }
-
- if (!ctype_alnum($dkim_selector)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
- );
- return false;
- }
-
- $config = array(
- "digest_alg" => "sha256",
- "private_key_bits" => $key_length,
- "private_key_type" => OPENSSL_KEYTYPE_RSA,
- );
- if ($keypair_ressource = openssl_pkey_new($config)) {
- $key_details = openssl_pkey_get_details($keypair_ressource);
- $pubKey = implode(array_slice(
- array_filter(
- explode(PHP_EOL, $key_details['key'])
- ), 1, -1)
- );
- // Save public key and selector to redis
- try {
- $redis->hSet('DKIM_PUB_KEYS', $domain, $pubKey);
- $redis->hSet('DKIM_SELECTORS', $domain, $dkim_selector);
- }
- catch (RedisException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'Redis: '.$e
- );
- return false;
- }
- // Export private key and save private key to redis
- openssl_pkey_export($keypair_ressource, $privKey);
- if (isset($privKey) && !empty($privKey)) {
- try {
- $redis->hSet('DKIM_PRIV_KEYS', $dkim_selector . '.' . $domain, trim($privKey));
- }
- catch (RedisException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'Redis: '.$e
- );
- return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['dkim_added'])
- );
- return true;
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
- );
- return false;
- }
-}
-function dkim_get_key_details($domain) {
- global $redis;
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- return false;
- }
- $data = array();
- if ($redis_dkim_key_data = $redis->hGet('DKIM_PUB_KEYS', $domain)) {
- $data['pubkey'] = $redis_dkim_key_data;
- $data['length'] = (strlen($data['pubkey']) < 391) ? 1024 : 2048;
- $data['dkim_txt'] = 'v=DKIM1;k=rsa;t=s;s=email;p=' . $redis_dkim_key_data;
- $data['dkim_selector'] = $redis->hGet('DKIM_SELECTORS', $domain);
- }
- return $data;
-}
-function dkim_get_blind_keys() {
- global $redis;
- global $lang;
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- return false;
- }
- $domains = array();
- foreach ($redis->hKeys('DKIM_PUB_KEYS') as $redis_dkim_domain) {
- $domains[] = $redis_dkim_domain;
- }
- return array_diff($domains, array_merge(mailbox_get_domains(), mailbox_get_alias_domains()));
-}
-function dkim_delete_key($postarray) {
- global $redis;
- global $lang;
- if (!is_array($postarray['domains'])) {
- $domains = array();
- $domains[] = $postarray['domains'];
- }
- else {
- $domains = $postarray['domains'];
- }
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- foreach ($domains as $domain) {
- if (!is_valid_domain_name($domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
- );
- return false;
- }
- try {
- $selector = $redis->hGet('DKIM_SELECTORS', $domain);
- $redis->hDel('DKIM_PUB_KEYS', $domain);
- $redis->hDel('DKIM_PRIV_KEYS', $selector . '.' . $domain);
- $redis->hDel('DKIM_SELECTORS', $domain);
- }
- catch (RedisException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'Redis: '.$e
- );
- return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['dkim_removed'], htmlspecialchars(implode(', ', $domains)))
- );
- return true;
-}
-function mailbox_add_domain($postarray) {
- // Array elements
- // domain string
- // description string
- // aliases int
- // mailboxes int
- // maxquota int
- // quota int
- // active int
- // relay_all_recipients int
- // backupmx int
- global $pdo;
- global $redis;
- global $lang;
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- $domain = idn_to_ascii(strtolower(trim($postarray['domain'])));
- $description = $postarray['description'];
- $aliases = $postarray['aliases'];
- $mailboxes = $postarray['mailboxes'];
- $maxquota = $postarray['maxquota'];
- $quota = $postarray['quota'];
-
- if ($maxquota > $quota) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
- );
- return false;
- }
-
- if ($maxquota == "0" || empty($maxquota)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['maxquota_empty'])
- );
- return false;
- }
-
- $active = intval($postarray['active']);
- $relay_all_recipients = intval($postarray['relay_all_recipients']);
- $backupmx = intval($postarray['backupmx']);
- ($relay_all_recipients == 1) ? $backupmx = '1' : null;
-
- if (!is_valid_domain_name($domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
-
- foreach (array($quota, $maxquota, $mailboxes, $aliases) as $data) {
- if (!is_numeric($data)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['object_is_not_numeric'], htmlspecialchars($data))
- );
- return false;
- }
- }
-
- try {
- $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
- WHERE `domain` = :domain");
- $stmt->execute(array(':domain' => $domain));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain`
- WHERE `alias_domain` = :domain");
- $stmt->execute(array(':domain' => $domain));
- $num_results = $num_results + count($stmt->fetchAll(PDO::FETCH_ASSOC));
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_exists'], htmlspecialchars($domain))
- );
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `transport`, `backupmx`, `active`, `relay_all_recipients`)
- VALUES (:domain, :description, :aliases, :mailboxes, :maxquota, :quota, 'virtual', :backupmx, :active, :relay_all_recipients)");
- $stmt->execute(array(
- ':domain' => $domain,
- ':description' => $description,
- ':aliases' => $aliases,
- ':mailboxes' => $mailboxes,
- ':maxquota' => $maxquota,
- ':quota' => $quota,
- ':backupmx' => $backupmx,
- ':active' => $active,
- ':relay_all_recipients' => $relay_all_recipients
- ));
- try {
- $redis->hSet('DOMAIN_MAP', $domain, 1);
- }
- catch (RedisException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'Redis: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_added'], htmlspecialchars($domain))
- );
- }
- catch (PDOException $e) {
- mailbox_delete_domain(array('domain' => $domain));
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-}
-function mailbox_add_alias($postarray) {
- // Array elements
- // address string (separated by " ", "," ";" "\n") - email address or domain
- // goto string (separated by " ", "," ";" "\n")
- // active int
- global $lang;
- global $pdo;
- $addresses = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['address']));
- $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
- $active = intval($postarray['active']);
- if (empty($addresses[0])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['alias_empty'])
- );
- return false;
- }
-
- if (empty($gotos[0])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['goto_empty'])
- );
- return false;
- }
- foreach ($addresses as $address) {
- if (empty($address)) {
- continue;
- }
-
- $stmt = $pdo->prepare("SELECT `address` FROM `alias`
- WHERE `address`= :address");
- $stmt->execute(array(':address' => $address));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['is_alias_or_mailbox'], htmlspecialchars($address))
- );
- return false;
- }
-
- $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
- $local_part = strstr($address, '@', true);
- $address = $local_part.'@'.$domain;
-
- $domaindata = mailbox_get_domain_details($domain);
- if (is_array($domaindata) && $domaindata['aliases_left'] == "0") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['max_alias_exceeded'])
- );
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
- WHERE `domain`= :domain1 OR `domain` = (SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain2)");
- $stmt->execute(array(':domain1' => $domain, ':domain2' => $domain));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results == 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_not_found'], htmlspecialchars($domain))
- );
- return false;
- }
-
- $stmt = $pdo->prepare("SELECT `address` FROM `alias`
- WHERE `address`= :address");
- $stmt->execute(array(':address' => $address));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['is_alias_or_mailbox'], htmlspecialchars($address))
- );
- return false;
- }
-
- $stmt = $pdo->prepare("SELECT `address` FROM `spamalias`
- WHERE `address`= :address");
- $stmt->execute(array(':address' => $address));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($address))
- );
- return false;
- }
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-
- if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['alias_invalid'])
- );
- return false;
- }
-
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- foreach ($gotos as &$goto) {
- if (empty($goto)) {
- continue;
- }
-
- $goto_domain = idn_to_ascii(substr(strstr($goto, '@'), 1));
- $goto_local_part = strstr($goto, '@', true);
- $goto = $goto_local_part.'@'.$goto_domain;
-
- $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
- WHERE `kind` REGEXP 'location|thing|group'
- AND `username`= :goto");
- $stmt->execute(array(':goto' => $goto));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['goto_invalid'])
- );
- return false;
- }
-
- if (!filter_var($goto, FILTER_VALIDATE_EMAIL) === true) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['goto_invalid'])
- );
- return false;
- }
- if ($goto == $address) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['alias_goto_identical'])
- );
- return false;
- }
- }
-
- $gotos = array_filter($gotos);
- $goto = implode(",", $gotos);
-
- try {
- $stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `active`)
- VALUES (:address, :goto, :domain, :active)");
-
- if (!filter_var($address, FILTER_VALIDATE_EMAIL) === true) {
- $stmt->execute(array(
- ':address' => '@'.$domain,
- ':goto' => $goto,
- ':domain' => $domain,
- ':active' => $active
- ));
- }
- else {
- $stmt->execute(array(
- ':address' => $address,
- ':goto' => $goto,
- ':domain' => $domain,
- ':active' => $active
- ));
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['alias_added'])
- );
- }
- catch (PDOException $e) {
- mailbox_delete_alias(array('address' => $address));
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['alias_added'])
- );
-}
-function mailbox_add_alias_domain($postarray) {
- // Array elements
- // active int
- // alias_domain string
- // target_domain string
- global $lang;
- global $pdo;
- $active = intval($postarray['active']);
- $alias_domain = idn_to_ascii(strtolower(trim($postarray['alias_domain'])));
- $target_domain = idn_to_ascii(strtolower(trim($postarray['target_domain'])));
-
- if (!is_valid_domain_name($alias_domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
- );
- return false;
- }
-
- if (!is_valid_domain_name($target_domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['target_domain_invalid'])
- );
- return false;
- }
-
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $target_domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- if ($alias_domain == $target_domain) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['aliasd_targetd_identical'])
- );
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
- WHERE `domain`= :target_domain");
- $stmt->execute(array(':target_domain' => $target_domain));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results == 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['targetd_not_found'])
- );
- return false;
- }
-
- $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain
- UNION
- SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain_in_domain");
- $stmt->execute(array(':alias_domain' => $alias_domain, ':alias_domain_in_domain' => $alias_domain));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['aliasd_exists'])
- );
- return false;
- }
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("INSERT INTO `alias_domain` (`alias_domain`, `target_domain`, `active`)
- VALUES (:alias_domain, :target_domain, :active)");
- $stmt->execute(array(
- ':alias_domain' => $alias_domain,
- ':target_domain' => $target_domain,
- ':active' => $active
- ));
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['aliasd_added'], htmlspecialchars($alias_domain))
- );
- }
- catch (PDOException $e) {
- mailbox_delete_alias_domain(array('alias_domain' => $alias_domain));
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-}
-function mailbox_add_mailbox($postarray) {
- // Array elements
- // active int
- // local_part string
- // domain string
- // name string (username if empty)
- // password string
- // password2 string
- // quota int (MiB)
- // active int
-
- global $pdo;
- global $lang;
- $local_part = strtolower(trim($postarray['local_part']));
- $domain = idn_to_ascii(strtolower(trim($postarray['domain'])));
- $username = $local_part . '@' . $domain;
- if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['mailbox_invalid'])
- );
- return false;
- }
- if (empty($postarray['local_part'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['mailbox_invalid'])
- );
- return false;
- }
- $password = $postarray['password'];
- $password2 = $postarray['password2'];
- $name = $postarray['name'];
- $quota_m = filter_var($postarray['quota'], FILTER_SANITIZE_NUMBER_FLOAT);
-
- if (empty($name)) {
- $name = $local_part;
- }
-
- $active = intval($postarray['active']);
-
- $quota_b = ($quota_m * 1048576);
- $maildir = $domain."/".$local_part."/";
-
- if (!is_valid_domain_name($domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
-
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("SELECT `mailboxes`, `maxquota`, `quota` FROM `domain`
- WHERE `domain` = :domain");
- $stmt->execute(array(':domain' => $domain));
- $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
-
- $stmt = $pdo->prepare("SELECT
- COUNT(*) as count,
- COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota`
- FROM `mailbox`
- WHERE `kind` NOT REGEXP 'location|thing|group'
- AND `domain` = :domain");
- $stmt->execute(array(':domain' => $domain));
- $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
-
- $stmt = $pdo->prepare("SELECT `local_part` FROM `mailbox` WHERE `local_part` = :local_part and `domain`= :domain");
- $stmt->execute(array(':local_part' => $local_part, ':domain' => $domain));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($username))
- );
- return false;
- }
-
- $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE address= :username");
- $stmt->execute(array(':username' => $username));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['is_alias'], htmlspecialchars($username))
- );
- return false;
- }
-
- $stmt = $pdo->prepare("SELECT `address` FROM `spamalias` WHERE `address`= :username");
- $stmt->execute(array(':username' => $username));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($username))
- );
- return false;
- }
-
- $stmt = $pdo->prepare("SELECT `domain` FROM `domain` WHERE `domain`= :domain");
- $stmt->execute(array(':domain' => $domain));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results == 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_not_found'], $domain)
- );
- return false;
- }
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-
- if (!is_numeric($quota_m) || $quota_m == "0") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['quota_not_0_not_numeric'])
- );
- return false;
- }
-
- if (!empty($password) && !empty($password2)) {
- if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_complexity'])
- );
- return false;
- }
- if ($password != $password2) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_mismatch'])
- );
- return false;
- }
- $password_hashed = hash_password($password);
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_empty'])
- );
- return false;
- }
-
- if ($MailboxData['count'] >= $DomainData['mailboxes']) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['max_mailbox_exceeded'], $MailboxData['count'], $DomainData['mailboxes'])
- );
- return false;
- }
-
- if ($quota_m > $DomainData['maxquota']) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['mailbox_quota_exceeded'], $DomainData['maxquota'])
- );
- return false;
- }
-
- if (($MailboxData['quota'] + $quota_m) > $DomainData['quota']) {
- $quota_left_m = ($DomainData['quota'] - $MailboxData['quota']);
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], $quota_left_m)
- );
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `active`)
- VALUES (:username, :password_hashed, :name, :maildir, :quota_b, :local_part, :domain, :active)");
- $stmt->execute(array(
- ':username' => $username,
- ':password_hashed' => $password_hashed,
- ':name' => $name,
- ':maildir' => $maildir,
- ':quota_b' => $quota_b,
- ':local_part' => $local_part,
- ':domain' => $domain,
- ':active' => $active
- ));
-
- $stmt = $pdo->prepare("INSERT INTO `quota2` (`username`, `bytes`, `messages`)
- VALUES (:username, '0', '0')");
- $stmt->execute(array(':username' => $username));
-
- $stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `active`)
- VALUES (:username1, :username2, :domain, :active)");
- $stmt->execute(array(
- ':username1' => $username,
- ':username2' => $username,
- ':domain' => $domain,
- ':active' => $active
- ));
-
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_added'], htmlspecialchars($username))
- );
- }
- catch (PDOException $e) {
- mailbox_delete_mailbox(array('username' => $username));
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-}
-function mailbox_add_resource($postarray) {
- // Array elements
- // active int
- // domain string
- // description string
- // multiple_bookings int
- // kind string
-
- global $pdo;
- global $lang;
- $domain = idn_to_ascii(strtolower(trim($postarray['domain'])));
- $description = $postarray['description'];
- $local_part = preg_replace('/[^\da-z]/i', '', preg_quote($description, '/'));
- $name = $local_part . '@' . $domain;
- $kind = $postarray['kind'];
- $active = intval($postarray['active']);
- $multiple_bookings = intval($postarray['multiple_bookings']);
-
- if (!filter_var($name, FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['resource_invalid'])
- );
- return false;
- }
-
- if (empty($description)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['description_invalid'])
- );
- return false;
- }
-
- if ($kind != 'location' && $kind != 'group' && $kind != 'thing') {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['resource_invalid'])
- );
- return false;
- }
-
- if (!is_valid_domain_name($domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
-
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `username` = :name");
- $stmt->execute(array(':name' => $name));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($name))
- );
- return false;
- }
-
- $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE address= :name");
- $stmt->execute(array(':name' => $name));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['is_alias'], htmlspecialchars($name))
- );
- return false;
- }
-
- $stmt = $pdo->prepare("SELECT `address` FROM `spamalias` WHERE `address`= :name");
- $stmt->execute(array(':name' => $name));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($name))
- );
- return false;
- }
-
- $stmt = $pdo->prepare("SELECT `domain` FROM `domain` WHERE `domain`= :domain");
- $stmt->execute(array(':domain' => $domain));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results == 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_not_found'], $domain)
- );
- return false;
- }
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `active`, `multiple_bookings`, `kind`)
- VALUES (:name, 'RESOURCE', :description, 'RESOURCE', 0, :local_part, :domain, :active, :multiple_bookings, :kind)");
- $stmt->execute(array(
- ':name' => $name,
- ':description' => $description,
- ':local_part' => $local_part,
- ':domain' => $domain,
- ':active' => $active,
- ':kind' => $kind,
- ':multiple_bookings' => $multiple_bookings
- ));
-
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['resource_added'], htmlspecialchars($name))
- );
- }
- catch (PDOException $e) {
- mailbox_delete_resource(array('name' => $name));
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-}
-function mailbox_edit_alias_domain($postarray) {
- // active int
- // target_domain string
- // alias_domain string/array of strings
- global $lang;
- global $pdo;
- if (!is_array($postarray['alias_domain'])) {
- $alias_domains = array();
- $alias_domains[] = $postarray['alias_domain'];
- }
- else {
- $alias_domains = $postarray['alias_domain'];
- }
- foreach ($alias_domains as $alias_domain) {
- $alias_domain = idn_to_ascii(strtolower(trim($alias_domain)));
- $is_now = mailbox_get_alias_domain_details($alias_domain);
- if (!empty($is_now)) {
- $active = (isset($postarray['active'])) ? $postarray['active'] : $is_now['active_int'];
- $target_domain = (!empty($postarray['target_domain'])) ? idn_to_ascii(strtolower(trim($postarray['target_domain']))) : $is_now['target_domain'];
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
- );
- return false;
- }
- if (!is_valid_domain_name($target_domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['target_domain_invalid'])
- );
- return false;
- }
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $target_domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (empty(mailbox_get_domain_details($target_domain))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['target_domain_invalid'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("UPDATE `alias_domain` SET
- `target_domain` = :target_domain,
- `active` = :active
- WHERE `alias_domain` = :alias_domain");
- $stmt->execute(array(
- ':alias_domain' => $alias_domain,
- ':target_domain' => $target_domain,
- ':active' => $active
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['aliasd_modified'], htmlspecialchars(implode(', ', $alias_domains)))
- );
-}
-function mailbox_edit_alias($postarray) {
- // We can edit multiple addresses at once, but only set one "goto" and/or "active" attribute for all
- // address string or array containing strings | email | required
- // goto string | separated by " ", "," ";" "\n", email or domain | optional
- // active set (active) or unset (inactive)
- global $lang;
- global $pdo;
- if (!is_array($postarray['address'])) {
- $addresses = array();
- $addresses[] = $postarray['address'];
- }
- else {
- $addresses = $postarray['address'];
- }
- foreach ($addresses as $address) {
- $is_now = mailbox_get_alias_details($address);
- if (!empty($is_now)) {
- $active = (isset($postarray['active'])) ? $postarray['active'] : $is_now['active_int'];
- $goto = (!empty($postarray['goto'])) ? $postarray['goto'] : $is_now['goto'];
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['alias_invalid'])
- );
- return false;
- }
-
- $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
- foreach ($gotos as &$goto) {
- if (empty($goto)) {
- continue;
- }
- if (!filter_var($goto, FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' =>sprintf($lang['danger']['goto_invalid'])
- );
- return false;
- }
- if ($goto == $address) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['alias_goto_identical'])
- );
- return false;
- }
- }
- $gotos = array_filter($gotos);
- $goto = implode(",", $gotos);
-
- $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
- $local_part = strstr($address, '@', true);
-
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['alias_invalid'])
- );
- return false;
- }
-
- try {
- if (!empty($goto)) {
- $stmt = $pdo->prepare("UPDATE `alias` SET
- `goto` = :goto,
- `active`= :active
- WHERE `address` = :address");
- $stmt->execute(array(
- ':goto' => $goto,
- ':active' => $active,
- ':address' => $address
- ));
- }
- else {
- $stmt = $pdo->prepare("UPDATE `alias` SET
- `active`= :active
- WHERE `address` = :address");
- $stmt->execute(array(
- ':active' => $active,
- ':address' => $address
- ));
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['alias_modified'], htmlspecialchars(implode(', ', $addresses)))
- );
-}
-function mailbox_edit_domain($postarray) {
- // Array elements
- // domain string
- // description string
- // active int
- // relay_all_recipients int
- // backupmx int
- // aliases float
- // mailboxes float
- // maxquota float
- // quota float (Byte)
- // active int
-
- global $lang;
- global $pdo;
-
- if (!is_array($postarray['domain'])) {
- $domains = array();
- $domains[] = $postarray['domain'];
- }
- else {
- $domains = $postarray['domain'];
- }
- foreach ($domains as $domain) {
- $domain = idn_to_ascii($domain);
- if (!is_valid_domain_name($domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
- if ($_SESSION['mailcow_cc_role'] == "domainadmin" &&
- hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- $description = $postarray['description'];
- $active = intval($postarray['active']);
- try {
- $stmt = $pdo->prepare("UPDATE `domain` SET
- `description` = :description
- WHERE `domain` = :domain");
- $stmt->execute(array(
- ':description' => $description,
- ':domain' => $domain
- ));
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_modified'], htmlspecialchars($domain))
- );
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- elseif ($_SESSION['mailcow_cc_role'] == "admin") {
- $is_now = mailbox_get_domain_details($domain);
- if (!empty($is_now)) {
- $active = (isset($postarray['active'])) ? $postarray['active'] : $is_now['active_int'];
- $backupmx = (isset($postarray['backupmx'])) ? $postarray['backupmx'] : $is_now['backupmx_int'];
- $relay_all_recipients = (isset($postarray['relay_all_recipients'])) ? $postarray['relay_all_recipients'] : $is_now['relay_all_recipients_int'];
- $aliases = (!empty($postarray['aliases'])) ? $postarray['aliases'] : $is_now['max_num_aliases_for_domain'];
- $mailboxes = (!empty($postarray['mailboxes'])) ? $postarray['mailboxes'] : $is_now['max_num_mboxes_for_domain'];
- $maxquota = (!empty($postarray['maxquota'])) ? $postarray['maxquota'] : ($is_now['max_new_mailbox_quota'] / 1048576);
- $quota = (!empty($postarray['quota'])) ? $postarray['quota'] : ($is_now['max_quota_for_domain'] / 1048576);
- $description = (!empty($postarray['description'])) ? $postarray['description'] : $is_now['description'];
- ($relay_all_recipients == '1') ? $backupmx = '1' : null;
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
- try {
- // todo: should be using api here
- $stmt = $pdo->prepare("SELECT
- COUNT(*) AS count,
- 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'
- AND domain = :domain");
- $stmt->execute(array(':domain' => $domain));
- $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
- // todo: should be using api here
- $stmt = $pdo->prepare("SELECT COUNT(*) AS `count` FROM `alias`
- WHERE domain = :domain
- AND address NOT IN (
- SELECT `username` FROM `mailbox`
- )");
- $stmt->execute(array(':domain' => $domain));
- $AliasData = $stmt->fetch(PDO::FETCH_ASSOC);
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-
- if ($maxquota > $quota) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
- );
- return false;
- }
-
- if ($maxquota == "0" || empty($maxquota)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['maxquota_empty'])
- );
- return false;
- }
-
- if ($MailboxData['biggest_mailbox'] > $maxquota) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['max_quota_in_use'], $MailboxData['biggest_mailbox'])
- );
- return false;
- }
-
- if ($MailboxData['quota_all'] > $quota) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_quota_m_in_use'], $MailboxData['quota_all'])
- );
- return false;
- }
-
- if ($MailboxData['count'] > $mailboxes) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['mailboxes_in_use'], $MailboxData['count'])
- );
- return false;
- }
-
- if ($AliasData['count'] > $aliases) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['aliases_in_use'], $AliasData['count'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("UPDATE `domain` SET
- `relay_all_recipients` = :relay_all_recipients,
- `backupmx` = :backupmx,
- `active` = :active,
- `quota` = :quota,
- `maxquota` = :maxquota,
- `mailboxes` = :mailboxes,
- `aliases` = :aliases,
- `description` = :description
- WHERE `domain` = :domain");
- $stmt->execute(array(
- ':relay_all_recipients' => $relay_all_recipients,
- ':backupmx' => $backupmx,
- ':active' => $active,
- ':quota' => $quota,
- ':maxquota' => $maxquota,
- ':mailboxes' => $mailboxes,
- ':aliases' => $aliases,
- ':description' => $description,
- ':domain' => $domain
- ));
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_modified'], htmlspecialchars($domain))
- );
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- }
-}
-function mailbox_edit_mailbox($postarray) {
- global $lang;
- global $pdo;
- if (!is_array($postarray['username'])) {
- $usernames = array();
- $usernames[] = $postarray['username'];
- }
- else {
- $usernames = $postarray['username'];
- }
- foreach ($usernames as $username) {
- if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
- );
- return false;
- }
- $is_now = mailbox_get_mailbox_details($username);
- if (!empty($is_now)) {
- $active = (isset($postarray['active'])) ? $postarray['active'] : $is_now['active_int'];
- $name = (!empty($postarray['name'])) ? $postarray['name'] : $is_now['name'];
- $domain = $is_now['domain'];
- $quota_m = (!empty($postarray['quota'])) ? $postarray['quota'] : ($is_now['quota'] / 1048576);
- $quota_b = $quota_m * 1048576;
- $password = (!empty($postarray['password'])) ? $postarray['password'] : null;
- $password2 = (!empty($postarray['password2'])) ? $postarray['password2'] : null;
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("SELECT `quota`, `maxquota`
- FROM `domain`
- WHERE `domain` = :domain");
- $stmt->execute(array(':domain' => $domain));
- $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (!is_numeric($quota_m) || $quota_m == "0") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['quota_not_0_not_numeric'], htmlspecialchars($quota_m))
- );
- return false;
- }
- if ($quota_m > $DomainData['maxquota']) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['mailbox_quota_exceeded'], $DomainData['maxquota'])
- );
- return false;
- }
- if (((($is_now['quota_used'] / 1048576) - $quota_m) + $quota_m) > $DomainData['quota']) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], ($is_now['max_new_quota'] / 1048576))
- );
- return false;
- }
-
- if (isset($postarray['sender_acl'])) {
- // Get sender_acl items set by admin
- $sender_acl_admin = array_merge(
- mailbox_get_sender_acl_handles($username)['sender_acl_domains']['ro'],
- mailbox_get_sender_acl_handles($username)['sender_acl_addresses']['ro']
- );
-
- // Get sender_acl items from POST array
- $sender_acl_domain_admin = ($postarray['sender_acl'] == "0") ? array() : $postarray['sender_acl'];
-
- if (!empty($sender_acl_domain_admin) || !empty($sender_acl_admin)) {
- // Check items in POST array
- foreach ($sender_acl_domain_admin as $sender_acl) {
- if (!filter_var($sender_acl, FILTER_VALIDATE_EMAIL) && !is_valid_domain_name(ltrim($sender_acl, '@'))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
- );
- return false;
- }
- if (is_valid_domain_name(ltrim($sender_acl, '@'))) {
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], ltrim($sender_acl, '@'))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
- );
- return false;
- }
- }
- if (filter_var($sender_acl, FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $sender_acl)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
- );
- return false;
- }
- }
- }
-
- // Merge both arrays
- $sender_acl_merged = array_merge($sender_acl_domain_admin, $sender_acl_admin);
-
- try {
- $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-
- foreach ($sender_acl_merged as $sender_acl) {
- $domain = ltrim($sender_acl, '@');
- if (is_valid_domain_name($domain)) {
- $sender_acl = '@' . $domain;
- }
- try {
- $stmt = $pdo->prepare("INSERT INTO `sender_acl` (`send_as`, `logged_in_as`)
- VALUES (:sender_acl, :username)");
- $stmt->execute(array(
- ':sender_acl' => $sender_acl,
- ':username' => $username
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- }
- else {
- try {
- $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- }
- if (!empty($password) && !empty($password2)) {
- if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_complexity'])
- );
- return false;
- }
- if ($password != $password2) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_mismatch'])
- );
- return false;
- }
- $password_hashed = hash_password($password);
- try {
- $stmt = $pdo->prepare("UPDATE `alias` SET
- `active` = :active
- WHERE `address` = :address");
- $stmt->execute(array(
- ':address' => $username,
- ':active' => $active
- ));
- $stmt = $pdo->prepare("UPDATE `mailbox` SET
- `active` = :active,
- `password` = :password_hashed,
- `name`= :name,
- `quota` = :quota_b
- WHERE `username` = :username");
- $stmt->execute(array(
- ':password_hashed' => $password_hashed,
- ':active' => $active,
- ':name' => $name,
- ':quota_b' => $quota_b,
- ':username' => $username
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- try {
- $stmt = $pdo->prepare("UPDATE `alias` SET
- `active` = :active
- WHERE `address` = :address");
- $stmt->execute(array(
- ':address' => $username,
- ':active' => $active
- ));
- $stmt = $pdo->prepare("UPDATE `mailbox` SET
- `active` = :active,
- `name`= :name,
- `quota` = :quota_b
- WHERE `username` = :username");
- $stmt->execute(array(
- ':active' => $active,
- ':name' => $name,
- ':quota_b' => $quota_b,
- ':username' => $username
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_modified'], implode(', ', $usernames))
- );
- return true;
-}
-function mailbox_edit_resource($postarray) {
- global $lang;
- global $pdo;
-
- if (!is_array($postarray['name'])) {
- $names = array();
- $names[] = $postarray['name'];
- }
- else {
- $names = $postarray['name'];
- }
- foreach ($names as $name) {
- $is_now = mailbox_get_resource_details($name);
- if (!empty($is_now)) {
- $active = (isset($postarray['active'])) ? $postarray['active'] : $is_now['active_int'];
- $multiple_bookings = (isset($postarray['multiple_bookings'])) ? $postarray['multiple_bookings'] : $is_now['multiple_bookings_int'];
- $description = (!empty($postarray['description'])) ? $postarray['description'] : $is_now['description'];
- $kind = (!empty($postarray['kind'])) ? $postarray['kind'] : $is_now['kind'];
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['resource_invalid'])
- );
- return false;
- }
-
- if (!filter_var($name, FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['resource_invalid'])
- );
- return false;
- }
-
- if (empty($description)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['description_invalid'])
- );
- return false;
- }
-
- if ($kind != 'location' && $kind != 'group' && $kind != 'thing') {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['resource_invalid'])
- );
- return false;
- }
-
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $name)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("UPDATE `mailbox` SET
- `active` = :active,
- `name`= :description,
- `kind`= :kind,
- `multiple_bookings`= :multiple_bookings
- WHERE `username` = :name");
- $stmt->execute(array(
- ':active' => $active,
- ':description' => $description,
- ':multiple_bookings' => $multiple_bookings,
- ':kind' => $kind,
- ':name' => $name
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['resource_modified'], implode(', ', $names))
- );
- return true;
-}
-function mailbox_get_mailboxes($domain = null) {
- global $lang;
- global $pdo;
- $mailboxes = array();
- if (isset($domain) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- return false;
- }
- elseif (isset($domain) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- try {
- $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` != 'ALL' AND `domain` = :domain");
- $stmt->execute(array(
- ':domain' => $domain,
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $mailboxes[] = $row['username'];
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- else {
- try {
- $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->execute(array(
- ':username' => $_SESSION['mailcow_cc_username'],
- ':role' => $_SESSION['mailcow_cc_role'],
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $mailboxes[] = $row['username'];
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- return $mailboxes;
-}
-function mailbox_get_resources($domain = null) {
- global $lang;
- global $pdo;
- $resources = array();
- if (isset($domain) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- return false;
- }
- elseif (isset($domain) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- try {
- $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' AND `domain` != 'ALL' AND `domain` = :domain");
- $stmt->execute(array(
- ':domain' => $domain,
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $resources[] = $row['username'];
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- else {
- try {
- $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' 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'],
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $resources[] = $row['username'];
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- return $resources;
-}
-function mailbox_get_alias_domains($domain = null) {
- // Get all domains assigned to mailcow_cc_username or domain, if set
- // Domain admin needs to be active
- // Domain does not need to be active
- global $lang;
- global $pdo;
- $aliasdomains = array();
- if (isset($domain) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- return false;
- }
- elseif (isset($domain) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- try {
- $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain");
- $stmt->execute(array(
- ':domain' => $domain,
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $aliasdomains[] = $row['alias_domain'];
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- else {
- try {
- $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `target_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'],
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $aliasdomains[] = $row['alias_domain'];
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- return $aliasdomains;
-}
-function mailbox_get_aliases($domain) {
- global $lang;
- global $pdo;
- $aliases = array();
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `address` != `goto` AND `domain` = :domain");
- $stmt->execute(array(
- ':domain' => $domain,
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $aliases[] = $row['address'];
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- return $aliases;
-}
-function mailbox_get_alias_details($address) {
- global $lang;
- global $pdo;
- $aliasdata = array();
- try {
- $stmt = $pdo->prepare("SELECT
- `domain`,
- `goto`,
- `address`,
- `active` as `active_int`,
- CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
- `created`,
- `modified`
- FROM `alias`
- WHERE `address` = :address AND `address` != `goto`");
- $stmt->execute(array(
- ':address' => $address,
- ));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain");
- $stmt->execute(array(
- ':domain' => $row['domain'],
- ));
- $row_alias_domain = $stmt->fetch(PDO::FETCH_ASSOC);
- if (isset($row_alias_domain['target_domain']) && !empty($row_alias_domain['target_domain'])) {
- $aliasdata['in_primary_domain'] = $row_alias_domain['target_domain'];
- }
- else {
- $aliasdata['in_primary_domain'] = "";
- }
- $aliasdata['domain'] = $row['domain'];
- $aliasdata['goto'] = $row['goto'];
- $aliasdata['address'] = $row['address'];
- (!filter_var($aliasdata['address'], FILTER_VALIDATE_EMAIL)) ? $aliasdata['is_catch_all'] = 1 : $aliasdata['is_catch_all'] = 0;
- $aliasdata['active'] = $row['active'];
- $aliasdata['active_int'] = $row['active_int'];
- $aliasdata['created'] = $row['created'];
- $aliasdata['modified'] = $row['modified'];
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdata['domain'])) {
- return false;
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- return $aliasdata;
-}
-function mailbox_get_alias_domain_details($aliasdomain) {
- global $lang;
- global $pdo;
- $aliasdomaindata = array();
try {
$stmt = $pdo->prepare("SELECT
- `alias_domain`,
- `target_domain`,
- `active` AS `active_int`,
- CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
- `created`,
- `modified`
- FROM `alias_domain`
- WHERE `alias_domain` = :aliasdomain");
+ `tfa`.`active` AS `tfa_active_int`,
+ CASE `tfa`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `tfa_active`,
+ `domain_admins`.`username`,
+ `domain_admins`.`created`,
+ `domain_admins`.`active` AS `active_int`,
+ CASE `domain_admins`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
+ FROM `domain_admins`
+ LEFT OUTER JOIN `tfa` ON `tfa`.`username`=`domain_admins`.`username`
+ WHERE `domain_admins`.`username`= :domain_admin");
$stmt->execute(array(
- ':aliasdomain' => $aliasdomain,
+ ':domain_admin' => $domain_admin
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
- $aliasdomaindata['alias_domain'] = $row['alias_domain'];
- $aliasdomaindata['target_domain'] = $row['target_domain'];
- $aliasdomaindata['active'] = $row['active'];
- $aliasdomaindata['active_int'] = $row['active_int'];
- $aliasdomaindata['created'] = $row['created'];
- $aliasdomaindata['modified'] = $row['modified'];
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdomaindata['target_domain'])) {
- return false;
- }
- return $aliasdomaindata;
-}
-function mailbox_get_domains() {
- // Get all domains assigned to mailcow_cc_username
- // Domain admin needs to be active
- // Domain does not need to be active
- global $lang;
- global $pdo;
- $domains = array();
- if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
- return false;
- }
- try {
+ if (empty($row)) {
+ return false;
+ }
+ $domainadmindata['username'] = $row['username'];
+ $domainadmindata['tfa_active'] = $row['tfa_active'];
+ $domainadmindata['active'] = $row['active'];
+ $domainadmindata['tfa_active_int'] = $row['tfa_active_int'];
+ $domainadmindata['active_int'] = $row['active_int'];
+ $domainadmindata['modified'] = $row['created'];
+ // GET SELECTED
$stmt = $pdo->prepare("SELECT `domain` FROM `domain`
- WHERE (`domain` IN (
- SELECT `domain` from `domain_admins`
- WHERE (`active`='1' AND `username` = :username))
- )
- OR ('admin'= :role)
- AND `domain` != 'ALL'");
- $stmt->execute(array(
- ':username' => $_SESSION['mailcow_cc_username'],
- ':role' => $_SESSION['mailcow_cc_role'],
- ));
+ WHERE `domain` IN (
+ SELECT `domain` FROM `domain_admins`
+ WHERE `username`= :domain_admin)");
+ $stmt->execute(array(':domain_admin' => $domain_admin));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $domainadmindata['selected_domains'][] = $row['domain'];
+ }
+ // GET UNSELECTED
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
+ WHERE `domain` NOT IN (
+ SELECT `domain` FROM `domain_admins`
+ WHERE `username`= :domain_admin)");
+ $stmt->execute(array(':domain_admin' => $domain_admin));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
while($row = array_shift($rows)) {
- $domains[] = $row['domain'];
+ $domainadmindata['unselected_domains'][] = $row['domain'];
+ }
+ if (!isset($domainadmindata['unselected_domains'])) {
+ $domainadmindata['unselected_domains'] = "";
}
}
- catch (PDOException $e) {
+ catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
- return false;
}
- return $domains;
+ return $domainadmindata;
}
-function mailbox_get_domain_details($domain) {
+function set_tfa($postarray) {
global $lang;
global $pdo;
+ global $yubi;
+ global $u2f;
+ global $tfa;
- $domaindata = array();
- $domain = idn_to_ascii(strtolower(trim($domain)));
-
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain");
- $stmt->execute(array(
- ':domain' => $domain
- ));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- if (!empty($row)) {
- $domain = $row['target_domain'];
- }
-
- $stmt = $pdo->prepare("SELECT
- `domain`,
- `description`,
- `aliases`,
- `mailboxes`,
- `maxquota`,
- `quota`,
- `relay_all_recipients` as `relay_all_recipients_int`,
- `backupmx` as `backupmx_int`,
- `active` as `active_int`,
- CASE `relay_all_recipients` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `relay_all_recipients`,
- CASE `backupmx` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `backupmx`,
- CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
- FROM `domain` WHERE `domain`= :domain");
- $stmt->execute(array(
- ':domain' => $domain
- ));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- if (empty($row)) {
+ if ($_SESSION['mailcow_cc_role'] != "domainadmin" &&
+ $_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
return false;
- }
-
- $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`,
- COALESCE(SUM(`quota`), 0) AS `in_use`
- FROM `mailbox`
- WHERE `kind` NOT REGEXP 'location|thing|group'
- AND `domain` = :domain");
- $stmt->execute(array(':domain' => $row['domain']));
- $MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
-
- $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);
- }
- $domaindata['quota_used_in_domain'] = $MailboxDataDomain['in_use'];
- $domaindata['mboxes_in_domain'] = $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'];
- $domaindata['max_num_mboxes_for_domain'] = $row['mailboxes'];
- $domaindata['max_quota_for_mbox'] = $row['maxquota'] * 1048576;
- $domaindata['max_quota_for_domain'] = $row['quota'] * 1048576;
- $domaindata['backupmx'] = $row['backupmx'];
- $domaindata['backupmx_int'] = $row['backupmx_int'];
- $domaindata['active'] = $row['active'];
- $domaindata['active_int'] = $row['active_int'];
- $domaindata['relay_all_recipients'] = $row['relay_all_recipients'];
- $domaindata['relay_all_recipients_int'] = $row['relay_all_recipients_int'];
-
- $stmt = $pdo->prepare("SELECT COUNT(*) 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`
- )");
- $stmt->execute(array(
- ':domain' => $domain,
- ':domain2' => $domain
- ));
- $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'];
}
- catch (PDOException $e) {
+ $username = $_SESSION['mailcow_cc_username'];
+
+ $stmt = $pdo->prepare("SELECT `password` FROM `admin`
+ WHERE `username` = :user");
+ $stmt->execute(array(':user' => $username));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ if (!verify_ssha256($row['password'], $postarray["confirm_password"])) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => 'MySQL: '.$e
+ 'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
+
+ switch ($postarray["tfa_method"]) {
+ case "yubi_otp":
+ $key_id = (!isset($postarray["key_id"])) ? 'unidentified' : $postarray["key_id"];
+ $yubico_id = $postarray['yubico_id'];
+ $yubico_key = $postarray['yubico_key'];
+ $yubi = new Auth_Yubico($yubico_id, $yubico_key);
+ if (!$yubi) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (!ctype_alnum($postarray["otp_token"]) || strlen($postarray["otp_token"]) != 44) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['tfa_token_invalid'])
+ );
+ return false;
+ }
+ $yauth = $yubi->verify($postarray["otp_token"]);
+ if (PEAR::isError($yauth)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Yubico API: ' . $yauth->getMessage()
+ );
+ return false;
+ }
+ try {
+ // We could also do a modhex translation here
+ $yubico_modhex_id = substr($postarray["otp_token"], 0, 12);
+ $stmt = $pdo->prepare("DELETE FROM `tfa`
+ WHERE `username` = :username
+ AND (`authmech` != 'yubi_otp')
+ OR (`authmech` = 'yubi_otp' AND `secret` LIKE :modhex)");
+ $stmt->execute(array(':username' => $username, ':modhex' => '%' . $yubico_modhex_id));
+ $stmt = $pdo->prepare("INSERT INTO `tfa` (`key_id`, `username`, `authmech`, `active`, `secret`) VALUES
+ (:key_id, :username, 'yubi_otp', '1', :secret)");
+ $stmt->execute(array(':key_id' => $key_id, ':username' => $username, ':secret' => $yubico_id . ':' . $yubico_key . ':' . $yubico_modhex_id));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['object_modified'], htmlspecialchars($username))
+ );
+ break;
- return $domaindata;
-}
-function mailbox_get_mailbox_details($mailbox) {
- global $lang;
- global $pdo;
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $mailbox)) {
- return false;
- }
- $mailboxdata = array();
- try {
- $stmt = $pdo->prepare("SELECT
- `domain`.`backupmx`,
- `mailbox`.`username`,
- `mailbox`.`name`,
- `mailbox`.`active` AS `active_int`,
- CASE `mailbox`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
- `mailbox`.`domain`,
- `mailbox`.`quota`,
- `quota2`.`bytes`,
- `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");
- $stmt->execute(array(
- ':mailbox' => $mailbox,
- ));
- $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 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' => $mailbox));
- $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' => $mailbox, ':unixnow' => time()));
- $SpamaliasUsage = $stmt->fetch(PDO::FETCH_ASSOC);
+ case "u2f":
+ $key_id = (!isset($postarray["key_id"])) ? 'unidentified' : $postarray["key_id"];
+ try {
+ $reg = $u2f->doRegister(json_decode($_SESSION['regReq']), json_decode($postarray['token']));
+ $stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username AND `authmech` != 'u2f'");
+ $stmt->execute(array(':username' => $username));
+ $stmt = $pdo->prepare("INSERT INTO `tfa` (`username`, `key_id`, `authmech`, `keyHandle`, `publicKey`, `certificate`, `counter`, `active`) VALUES (?, ?, 'u2f', ?, ?, ?, ?, '1')");
+ $stmt->execute(array($username, $key_id, $reg->keyHandle, $reg->publicKey, $reg->certificate, $reg->counter));
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['object_modified'], $username)
+ );
+ $_SESSION['regReq'] = null;
+ }
+ catch (Exception $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => "U2F: " . $e->getMessage()
+ );
+ $_SESSION['regReq'] = null;
+ return false;
+ }
+ break;
- $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);
- }
+ case "totp":
+ $key_id = (!isset($postarray["key_id"])) ? 'unidentified' : $postarray["key_id"];
+ if ($tfa->verifyCode($_POST['totp_secret'], $_POST['totp_confirm_token']) === true) {
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ $stmt = $pdo->prepare("INSERT INTO `tfa` (`username`, `key_id`, `authmech`, `secret`, `active`) VALUES (?, ?, 'totp', ?, '1')");
+ $stmt->execute(array($username, $key_id, $_POST['totp_secret']));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['object_modified'], $username)
+ );
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'TOTP verification failed'
+ );
+ }
+ break;
- $mailboxdata['username'] = $row['username'];
- $mailboxdata['is_relayed'] = $row['backupmx'];
- $mailboxdata['name'] = $row['name'];
- $mailboxdata['active'] = $row['active'];
- $mailboxdata['active_int'] = $row['active_int'];
- $mailboxdata['domain'] = $row['domain'];
- $mailboxdata['quota'] = $row['quota'];
- $mailboxdata['quota_used'] = intval($row['bytes']);
- $mailboxdata['percent_in_use'] = round((intval($row['bytes']) / intval($row['quota'])) * 100);
- $mailboxdata['messages'] = $row['messages'];
- $mailboxdata['spam_aliases'] = $SpamaliasUsage['sa_count'];
- if ($mailboxdata['percent_in_use'] >= 90) {
- $mailboxdata['percent_class'] = "danger";
- }
- elseif ($mailboxdata['percent_in_use'] >= 75) {
- $mailboxdata['percent_class'] = "warning";
+ case "none":
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['object_modified'], htmlspecialchars($username))
+ );
+ break;
+ }
+}
+function unset_tfa_key($postarray) {
+ // Can only unset own keys
+ // Needs at least one key left
+ global $pdo;
+ global $lang;
+ $id = intval($postarray['unset_tfa_key']);
+ if ($_SESSION['mailcow_cc_role'] != "domainadmin" &&
+ $_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ $username = $_SESSION['mailcow_cc_username'];
+ try {
+ if (!is_numeric($id)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
}
- else {
- $mailboxdata['percent_class'] = "success";
+ $stmt = $pdo->prepare("SELECT COUNT(*) AS `keys` FROM `tfa`
+ WHERE `username` = :username AND `active` = '1'");
+ $stmt->execute(array(':username' => $username));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ if ($row['keys'] == "1") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['last_key'])
+ );
+ return false;
}
+ $stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username AND `id` = :id");
+ $stmt->execute(array(':username' => $username, ':id' => $id));
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['object_modified'], $username)
+ );
}
catch (PDOException $e) {
$_SESSION['return'] = array(
@@ -4438,141 +898,149 @@ function mailbox_get_mailbox_details($mailbox) {
);
return false;
}
- return $mailboxdata;
}
-function mailbox_get_resource_details($resource) {
- global $lang;
+function get_tfa($username = null) {
global $pdo;
- $resourcedata = array();
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $resource)) {
- return false;
- }
- try {
- $stmt = $pdo->prepare("SELECT
- `username`,
- `name`,
- `kind`,
- `multiple_bookings` AS `multiple_bookings_int`,
- `local_part`,
- `active` AS `active_int`,
- CASE `multiple_bookings` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `multiple_bookings`,
- CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
- `domain`
- FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' AND `username` = :resource");
- $stmt->execute(array(
- ':resource' => $resource,
- ));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- $resourcedata['name'] = $row['username'];
- $resourcedata['kind'] = $row['kind'];
- $resourcedata['multiple_bookings'] = $row['multiple_bookings'];
- $resourcedata['multiple_bookings_int'] = $row['multiple_bookings_int'];
- $resourcedata['description'] = $row['name'];
- $resourcedata['active'] = $row['active'];
- $resourcedata['active_int'] = $row['active_int'];
- $resourcedata['domain'] = $row['domain'];
- $resourcedata['local_part'] = $row['local_part'];
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
+ if (isset($_SESSION['mailcow_cc_username'])) {
+ $username = $_SESSION['mailcow_cc_username'];
}
- if (!isset($resourcedata['domain']) ||
- (isset($resourcedata['domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $resourcedata['domain']))) {
+ elseif (empty($username)) {
return false;
}
+
+ $stmt = $pdo->prepare("SELECT * FROM `tfa`
+ WHERE `username` = :username AND `active` = '1'");
+ $stmt->execute(array(':username' => $username));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
- return $resourcedata;
+ switch ($row["authmech"]) {
+ case "yubi_otp":
+ $data['name'] = "yubi_otp";
+ $data['pretty'] = "Yubico OTP";
+ $stmt = $pdo->prepare("SELECT `id`, `key_id`, RIGHT(`secret`, 12) AS 'modhex' FROM `tfa` WHERE `authmech` = 'yubi_otp' AND `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $data['additional'][] = $row;
+ }
+ return $data;
+ break;
+ case "u2f":
+ $data['name'] = "u2f";
+ $data['pretty'] = "Fido U2F";
+ $stmt = $pdo->prepare("SELECT `id`, `key_id` FROM `tfa` WHERE `authmech` = 'u2f' AND `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $data['additional'][] = $row;
+ }
+ return $data;
+ break;
+ case "hotp":
+ $data['name'] = "hotp";
+ $data['pretty'] = "HMAC-based OTP";
+ return $data;
+ break;
+ case "totp":
+ $data['name'] = "totp";
+ $data['pretty'] = "Time-based OTP";
+ $stmt = $pdo->prepare("SELECT `id`, `key_id`, `secret` FROM `tfa` WHERE `authmech` = 'totp' AND `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $data['additional'][] = $row;
+ }
+ return $data;
+ break;
+ default:
+ $data['name'] = 'none';
+ $data['pretty'] = "-";
+ return $data;
+ break;
+ }
}
-function mailbox_delete_domain($postarray) {
- global $lang;
- global $redis;
+function verify_tfa_login($username, $token) {
global $pdo;
- if (!is_array($postarray['domain'])) {
- $domains = array();
- $domains[] = $postarray['domain'];
- }
- else {
- $domains = $postarray['domain'];
- }
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- foreach ($domains as $domain) {
- if (!is_valid_domain_name($domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
- $domain = idn_to_ascii(strtolower(trim($domain)));
+ global $lang;
+ global $yubi;
+ global $u2f;
+ global $tfa;
+ $stmt = $pdo->prepare("SELECT `authmech` FROM `tfa`
+ WHERE `username` = :username AND `active` = '1'");
+ $stmt->execute(array(':username' => $username));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ switch ($row["authmech"]) {
+ case "yubi_otp":
+ if (!ctype_alnum($token) || strlen($token) != 44) {
+ return false;
+ }
+ $yubico_modhex_id = substr($token, 0, 12);
+ $stmt = $pdo->prepare("SELECT `id`, `secret` FROM `tfa`
+ WHERE `username` = :username
+ AND `authmech` = 'yubi_otp'
+ AND `active`='1'
+ AND `secret` LIKE :modhex");
+ $stmt->execute(array(':username' => $username, ':modhex' => '%' . $yubico_modhex_id));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ $yubico_auth = explode(':', $row['secret']);
+ $yubi = new Auth_Yubico($yubico_auth[0], $yubico_auth[1]);
+ $yauth = $yubi->verify($token);
+ if (PEAR::isError($yauth)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Yubico Authentication error: ' . $yauth->getMessage()
+ );
+ return false;
+ }
+ else {
+ $_SESSION['tfa_id'] = $row['id'];
+ return true;
+ }
+ return false;
+ break;
+ case "u2f":
try {
- $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
- WHERE `domain` = :domain");
- $stmt->execute(array(':domain' => $domain));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ $reg = $u2f->doAuthenticate(json_decode($_SESSION['authReq']), get_u2f_registrations($username), json_decode($token));
+ $stmt = $pdo->prepare("UPDATE `tfa` SET `counter` = ? WHERE `id` = ?");
+ $stmt->execute(array($reg->counter, $reg->id));
+ $_SESSION['tfa_id'] = $reg->id;
+ $_SESSION['authReq'] = null;
+ return true;
}
- catch(PDOException $e) {
+ catch (Exception $e) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => 'MySQL: '.$e
+ 'msg' => "U2F: " . $e->getMessage()
);
+ $_SESSION['regReq'] = null;
return false;
}
- if ($num_results != 0 || !empty($num_results)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_not_empty'])
- );
+ return false;
+ break;
+ case "hotp":
return false;
- }
-
+ break;
+ case "totp":
try {
- $stmt = $pdo->prepare("DELETE FROM `domain` WHERE `domain` = :domain");
- $stmt->execute(array(
- ':domain' => $domain,
- ));
- $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `domain` = :domain");
- $stmt->execute(array(
- ':domain' => $domain,
- ));
- $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `domain` = :domain");
- $stmt->execute(array(
- ':domain' => $domain,
- ));
- $stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `target_domain` = :domain");
- $stmt->execute(array(
- ':domain' => $domain,
- ));
- $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `domain` = :domain");
- $stmt->execute(array(
- ':domain' => $domain,
- ));
- $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` LIKE :domain");
- $stmt->execute(array(
- ':domain' => '%@'.$domain,
- ));
- $stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :domain");
- $stmt->execute(array(
- ':domain' => '%@'.$domain,
- ));
- $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `address` = :domain");
- $stmt->execute(array(
- ':domain' => '%@'.$domain,
- ));
- $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :domain");
- $stmt->execute(array(
- ':domain' => '%@'.$domain,
- ));
+ $stmt = $pdo->prepare("SELECT `id`, `secret` FROM `tfa`
+ WHERE `username` = :username
+ AND `authmech` = 'totp'
+ AND `active`='1'");
+ $stmt->execute(array(':username' => $username));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ if ($tfa->verifyCode($row['secret'], $_POST['token']) === true) {
+ $_SESSION['tfa_id'] = $row['id'];
+ return true;
+ }
+ return false;
}
catch (PDOException $e) {
$_SESSION['return'] = array(
@@ -4581,62 +1049,72 @@ function mailbox_delete_domain($postarray) {
);
return false;
}
- try {
- $redis->hDel('DOMAIN_MAP', $domain);
- }
- catch (RedisException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'Redis: '.$e
- );
+ break;
+ default:
return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_removed'], htmlspecialchars($domain))
- );
- return true;
+ break;
+ }
+ return false;
}
-function mailbox_delete_alias($postarray) {
- // $postarray['address'] can be a single element or an array
+function edit_domain_admin($postarray) {
global $lang;
global $pdo;
- if (!is_array($postarray['address'])) {
- $addresses = array();
- $addresses[] = $postarray['address'];
- }
- else {
- $addresses = $postarray['address'];
- }
- foreach ($addresses as $address) {
- $local_part = strstr($address, '@', true);
- $domain = mailbox_get_alias_details($address)['domain'];
- try {
- $stmt = $pdo->prepare("SELECT `goto` FROM `alias` WHERE `address` = :address");
- $stmt->execute(array(':address' => $address));
- $gotos = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ // Administrator
+ if ($_SESSION['mailcow_cc_role'] == "admin") {
+ $username = $postarray['username'];
+ $username_now = $postarray['username_now'];
+ $password = $postarray['password'];
+ $password2 = $postarray['password2'];
+ $active = intval($postarray['active']);
+
+ if(isset($postarray['domain'])) {
+ foreach ($postarray['domain'] as $domain) {
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ }
}
- catch(PDOException $e) {
+
+ if (empty($postarray['domain'])) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => 'MySQL: '.$e
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
);
return false;
}
- $goto_array = explode(',', $gotos['goto']);
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
+ 'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
+ if ($username != $username_now) {
+ if (empty(get_domain_admin_details($username_now)['username']) || !empty(get_domain_admin_details($username)['username'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ }
try {
- $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `address` = :address AND `address` NOT IN (SELECT `username` FROM `mailbox`)");
+ $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
$stmt->execute(array(
- ':address' => $address
+ ':username' => $username_now,
));
}
catch (PDOException $e) {
@@ -4646,406 +1124,347 @@ function mailbox_delete_alias($postarray) {
);
return false;
}
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['alias_removed'], htmlspecialchars(implode(', ', $addresses)))
- );
-}
-function mailbox_delete_alias_domain($postarray) {
- global $lang;
- global $pdo;
- if (!is_array($postarray['alias_domain'])) {
- $alias_domains = array();
- $alias_domains[] = $postarray['alias_domain'];
- }
- else {
- $alias_domains = $postarray['alias_domain'];
- }
- foreach ($alias_domains as $alias_domain) {
- if (!is_valid_domain_name($alias_domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
+ if (isset($postarray['domain'])) {
+ foreach ($postarray['domain'] as $domain) {
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
+ VALUES (:username, :domain, :created, :active)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':domain' => $domain,
+ ':created' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
}
- try {
- $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
- WHERE `alias_domain`= :alias_domain");
- $stmt->execute(array(':alias_domain' => $alias_domain));
- $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if (!empty($password) && !empty($password2)) {
+ if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_complexity'])
+ );
+ return false;
+ }
+ if ($password != $password2) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_mismatch'])
+ );
+ return false;
+ }
+ $password_hashed = hash_password($password);
+ try {
+ $stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `active` = :active, `password` = :password_hashed WHERE `username` = :username2");
+ $stmt->execute(array(
+ ':password_hashed' => $password_hashed,
+ ':username1' => $username,
+ ':username2' => $username_now,
+ ':active' => $active
+ ));
+ if (isset($postarray['disable_tfa'])) {
+ $stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username_now));
+ }
+ else {
+ $stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username WHERE `username` = :username_now");
+ $stmt->execute(array(':username' => $username, ':username_now' => $username_now));
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
}
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
+ else {
+ try {
+ $stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `active` = :active WHERE `username` = :username2");
+ $stmt->execute(array(
+ ':username1' => $username,
+ ':username2' => $username_now,
+ ':active' => $active
+ ));
+ if (isset($postarray['disable_tfa'])) {
+ $stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ }
+ else {
+ $stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username WHERE `username` = :username_now");
+ $stmt->execute(array(':username' => $username, ':username_now' => $username_now));
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
}
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $DomainData['target_domain'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars($username))
+ );
+ }
+ // Domain administrator
+ // Can only edit itself
+ elseif ($_SESSION['mailcow_cc_role'] == "domainadmin") {
+ $username = $_SESSION['mailcow_cc_username'];
+ $password_old = $postarray['user_old_pass'];
+ $password_new = $postarray['user_new_pass'];
+ $password_new2 = $postarray['user_new_pass2'];
+
+ $stmt = $pdo->prepare("SELECT `password` FROM `admin`
+ WHERE `username` = :user");
+ $stmt->execute(array(':user' => $username));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ if (!verify_ssha256($row['password'], $password_old)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
- try {
- $stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `alias_domain` = :alias_domain");
- $stmt->execute(array(
- ':alias_domain' => $alias_domain,
- ));
- $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `domain` = :alias_domain");
- $stmt->execute(array(
- ':alias_domain' => $alias_domain,
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
+
+ if (!empty($password_new2) && !empty($password_new)) {
+ if ($password_new2 != $password_new) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_mismatch'])
+ );
+ return false;
+ }
+ if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password_new)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_complexity'])
+ );
+ return false;
+ }
+ $password_hashed = hash_password($password_new);
+ try {
+ $stmt = $pdo->prepare("UPDATE `admin` SET `password` = :password_hashed WHERE `username` = :username");
+ $stmt->execute(array(
+ ':password_hashed' => $password_hashed,
+ ':username' => $username
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
}
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['alias_domain_removed'], htmlspecialchars(implode(', ', $alias_domains)))
- );
+
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars($username))
+ );
+ }
}
-function mailbox_delete_mailbox($postarray) {
- global $lang;
+function get_admin_details() {
+ // No parameter to be given, only one admin should exist
global $pdo;
- if (!is_array($postarray['username'])) {
- $usernames = array();
- $usernames[] = $postarray['username'];
+ global $lang;
+ $data = array();
+ if ($_SESSION['mailcow_cc_role'] != 'admin') {
+ return false;
}
- else {
- $usernames = $postarray['username'];
+ try {
+ $stmt = $pdo->prepare("SELECT `username`, `modified`, `created` FROM `admin` WHERE `superadmin`='1' AND active='1'");
+ $stmt->execute();
+ $data = $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ }
+ return $data;
+}
+function dkim_add_key($postarray) {
+ global $lang;
+ global $pdo;
+ global $redis;
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ // if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ // $_SESSION['return'] = array(
+ // 'type' => 'danger',
+ // 'msg' => sprintf($lang['danger']['access_denied'])
+ // );
+ // return false;
+ // }
+ $key_length = intval($postarray['key_size']);
+ $dkim_selector = (isset($postarray['dkim_selector'])) ? $postarray['dkim_selector'] : 'dkim';
+ $domain = $postarray['domain'];
+ if (!is_valid_domain_name($domain) || !is_numeric($key_length)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
+ );
+ return false;
}
- foreach ($usernames as $username) {
- if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
+ if (!empty(glob($GLOBALS['MC_DKIM_TXTS'] . '/' . $domain . '.dkim')) ||
+ $redis->hGet('DKIM_PUB_KEYS', $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
+ 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
);
return false;
- }
+ }
+
+ if (!ctype_alnum($dkim_selector)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
+ );
+ return false;
+ }
+ $config = array(
+ "digest_alg" => "sha256",
+ "private_key_bits" => $key_length,
+ "private_key_type" => OPENSSL_KEYTYPE_RSA,
+ );
+ if ($keypair_ressource = openssl_pkey_new($config)) {
+ $key_details = openssl_pkey_get_details($keypair_ressource);
+ $pubKey = implode(array_slice(
+ array_filter(
+ explode(PHP_EOL, $key_details['key'])
+ ), 1, -1)
+ );
+ // Save public key and selector to redis
try {
- $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `goto` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `username` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `imapsync` WHERE `user2` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_user_profile` WHERE `c_uid` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_acl` WHERE `c_object` LIKE '%/" . $username . "/%' OR `c_uid` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_store` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_quick_contact` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_quick_appointment` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_folder_info` WHERE `c_path2` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- $stmt = $pdo->prepare("SELECT `address`, `goto` FROM `alias`
- WHERE `goto` REGEXP :username");
- $stmt->execute(array(':username' => '(^|,)'.$username.'($|,)'));
- $GotoData = $stmt->fetchAll(PDO::FETCH_ASSOC);
- foreach ($GotoData as $gotos) {
- $goto_exploded = explode(',', $gotos['goto']);
- if (($key = array_search($username, $goto_exploded)) !== false) {
- unset($goto_exploded[$key]);
- }
- $gotos_rebuild = implode(',', $goto_exploded);
- $stmt = $pdo->prepare("UPDATE `alias` SET
- `goto` = :goto
- WHERE `address` = :address");
- $stmt->execute(array(
- ':goto' => $gotos_rebuild,
- ':address' => $gotos['address']
- ));
- }
+ $redis->hSet('DKIM_PUB_KEYS', $domain, $pubKey);
+ $redis->hSet('DKIM_SELECTORS', $domain, $dkim_selector);
}
- catch (PDOException $e) {
+ catch (RedisException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => 'MySQL: '.$e
+ 'msg' => 'Redis: '.$e
);
return false;
}
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['mailbox_removed'], htmlspecialchars(implode(', ', $usernames)))
- );
+ // Export private key and save private key to redis
+ openssl_pkey_export($keypair_ressource, $privKey);
+ if (isset($privKey) && !empty($privKey)) {
+ try {
+ $redis->hSet('DKIM_PRIV_KEYS', $dkim_selector . '.' . $domain, trim($privKey));
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Redis: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['dkim_added'])
+ );
+ return true;
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
+ );
+ return false;
+ }
+}
+function dkim_get_key_details($domain) {
+ global $redis;
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ return false;
+ }
+ $data = array();
+ if ($redis_dkim_key_data = $redis->hGet('DKIM_PUB_KEYS', $domain)) {
+ $data['pubkey'] = $redis_dkim_key_data;
+ $data['length'] = (strlen($data['pubkey']) < 391) ? 1024 : 2048;
+ $data['dkim_txt'] = 'v=DKIM1;k=rsa;t=s;s=email;p=' . $redis_dkim_key_data;
+ $data['dkim_selector'] = $redis->hGet('DKIM_SELECTORS', $domain);
+ }
+ return $data;
}
-function mailbox_reset_eas($username) {
+function dkim_get_blind_keys() {
+ global $redis;
global $lang;
- global $pdo;
-
- (isset($postarray['username'])) ? $username = $postarray['username'] : $username = $_SESSION['mailcow_cc_username'];
-
- if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- try {
- $stmt = $pdo->prepare("DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['eas_reset'], htmlspecialchars($username))
- );
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ return false;
+ }
+ $domains = array();
+ foreach ($redis->hKeys('DKIM_PUB_KEYS') as $redis_dkim_domain) {
+ $domains[] = $redis_dkim_domain;
+ }
+ return array_diff($domains, array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains')));
}
-function mailbox_delete_resource($postarray) {
+function dkim_delete_key($postarray) {
+ global $redis;
global $lang;
- global $pdo;
- if (!is_array($postarray['name'])) {
- $names = array();
- $names[] = $postarray['name'];
+ if (!is_array($postarray['domains'])) {
+ $domains = array();
+ $domains[] = $postarray['domains'];
}
else {
- $names = $postarray['name'];
+ $domains = $postarray['domains'];
}
- foreach ($names as $name) {
- if (!filter_var($name, FILTER_VALIDATE_EMAIL)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $name)) {
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ foreach ($domains as $domain) {
+ if (!is_valid_domain_name($domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
+ 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
);
return false;
}
try {
- $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `username` = :username");
- $stmt->execute(array(
- ':username' => $name
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_user_profile` WHERE `c_uid` = :username");
- $stmt->execute(array(
- ':username' => $name
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username");
- $stmt->execute(array(
- ':username' => $name
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_acl` WHERE `c_object` LIKE '%/" . $name . "/%' OR `c_uid` = :username");
- $stmt->execute(array(
- ':username' => $name
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_store` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
- $stmt->execute(array(
- ':username' => $name
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_quick_contact` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
- $stmt->execute(array(
- ':username' => $name
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_quick_appointment` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
- $stmt->execute(array(
- ':username' => $name
- ));
- $stmt = $pdo->prepare("DELETE FROM `sogo_folder_info` WHERE `c_path2` = :username");
- $stmt->execute(array(
- ':username' => $name
- ));
+ $selector = $redis->hGet('DKIM_SELECTORS', $domain);
+ $redis->hDel('DKIM_PUB_KEYS', $domain);
+ $redis->hDel('DKIM_PRIV_KEYS', $selector . '.' . $domain);
+ $redis->hDel('DKIM_SELECTORS', $domain);
}
- catch (PDOException $e) {
+ catch (RedisException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => 'MySQL: '.$e
+ 'msg' => 'Redis: '.$e
);
return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['resource_removed'], htmlspecialchars(implode(', ', $names)))
- );
-}
-function mailbox_get_sender_acl_handles($mailbox) {
- global $pdo;
- global $lang;
- if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
- return false;
- }
-
- $data['sender_acl_domains']['ro'] = array();
- $data['sender_acl_domains']['rw'] = array();
- $data['sender_acl_domains']['selectable'] = array();
- $data['sender_acl_addresses']['ro'] = array();
- $data['sender_acl_addresses']['rw'] = array();
- $data['sender_acl_addresses']['selectable'] = array();
- $data['fixed_sender_aliases'] = array();
-
- try {
- // Fixed addresses
- $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` REGEXP :goto AND `address` NOT LIKE '@%'");
- $stmt->execute(array(':goto' => '(^|,)'.$mailbox.'($|,)'));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($rows)) {
- $data['fixed_sender_aliases'][] = $row['address'];
- }
- $stmt = $pdo->prepare("SELECT CONCAT(`local_part`, '@', `alias_domain`.`alias_domain`) AS `alias_domain_alias` FROM `mailbox`, `alias_domain`
- WHERE `alias_domain`.`target_domain` = `mailbox`.`domain`
- AND `mailbox`.`username` = :username");
- $stmt->execute(array(':username' => $mailbox));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($rows)) {
- if (!empty($row['alias_domain_alias'])) {
- $data['fixed_sender_aliases'][] = $row['alias_domain_alias'];
- }
- }
-
- // Return array $data['sender_acl_domains/addresses']['ro'] with read-only objects
- // Return array $data['sender_acl_domains/addresses']['rw'] with read-write objects (can be deleted)
- $stmt = $pdo->prepare("SELECT REPLACE(`send_as`, '@', '') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as AND `send_as` LIKE '@%'");
- $stmt->execute(array(':logged_in_as' => $mailbox));
- $domain_rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($domain_row = array_shift($domain_rows)) {
- if (is_valid_domain_name($domain_row['send_as']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain_row['send_as'])) {
- $data['sender_acl_domains']['ro'][] = $domain_row['send_as'];
- continue;
- }
- if (is_valid_domain_name($domain_row['send_as']) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain_row['send_as'])) {
- $data['sender_acl_domains']['rw'][] = $domain_row['send_as'];
- continue;
- }
- }
-
- $stmt = $pdo->prepare("SELECT `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as AND `send_as` NOT LIKE '@%'");
- $stmt->execute(array(':logged_in_as' => $mailbox));
- $address_rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($address_row = array_shift($address_rows)) {
- if (filter_var($address_row['send_as'], FILTER_VALIDATE_EMAIL) && !hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $address_row['send_as'])) {
- $data['sender_acl_addresses']['ro'][] = $address_row['send_as'];
- continue;
- }
- if (filter_var($address_row['send_as'], FILTER_VALIDATE_EMAIL) && hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $address_row['send_as'])) {
- $data['sender_acl_addresses']['rw'][] = $address_row['send_as'];
- continue;
- }
- }
-
- $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
- WHERE `domain` NOT IN (
- SELECT REPLACE(`send_as`, '@', '') FROM `sender_acl`
- WHERE `logged_in_as` = :logged_in_as
- AND `send_as` LIKE '@%')");
- $stmt->execute(array(
- ':logged_in_as' => $mailbox,
- ));
- $rows_domain = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row_domain = array_shift($rows_domain)) {
- if (is_valid_domain_name($row_domain['domain']) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row_domain['domain'])) {
- $data['sender_acl_domains']['selectable'][] = $row_domain['domain'];
- }
- }
-
- $stmt = $pdo->prepare("SELECT `address` FROM `alias`
- WHERE `goto` != :goto
- AND `address` NOT IN (
- SELECT `send_as` FROM `sender_acl`
- WHERE `logged_in_as` = :logged_in_as
- AND `send_as` NOT LIKE '@%')");
- $stmt->execute(array(
- ':logged_in_as' => $mailbox,
- ':goto' => $mailbox
- ));
- $rows_mbox = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($rows_mbox)) {
- if (filter_var($row['address'], FILTER_VALIDATE_EMAIL) && hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row['address'])) {
- $data['sender_acl_addresses']['selectable'][] = $row['address'];
- }
}
}
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- return $data;
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['dkim_removed'], htmlspecialchars(implode(', ', $domains)))
+ );
+ return true;
}
function get_u2f_registrations($username) {
global $pdo;
@@ -5220,6 +1639,19 @@ function get_logs($container, $lines = 100) {
return $data_array;
}
}
+ if ($container == "rspamd-history") {
+ $curl = curl_init();
+ curl_setopt($curl, CURLOPT_URL,"http://rspamd-mailcow:11334/history");
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ $history = curl_exec($curl);
+ if (!curl_errno($ch)) {
+ $data_array = json_decode($history, true);
+ curl_close($curl);
+ return $data_array['rows'];
+ }
+ curl_close($curl);
+ return false;
+ }
return false;
}
?>
diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php
new file mode 100644
index 00000000..53a93c53
--- /dev/null
+++ b/data/web/inc/functions.mailbox.inc.php
@@ -0,0 +1,3116 @@
+<?php
+function mailbox($_action, $_type, $_data = null) {
+ global $pdo;
+ global $redis;
+ global $lang;
+ switch ($_action) {
+ case 'add':
+ switch ($_type) {
+ case 'time_limited_alias':
+ if (isset($_data['username']) && filter_var($_data['username'], FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data['username'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ else {
+ $username = $_data['username'];
+ }
+ }
+ else {
+ $username = $_SESSION['mailcow_cc_username'];
+ }
+ if (!is_numeric($_data["validity"]) || $_data["validity"] > 672) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['validity_missing'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `domain` FROM `mailbox` WHERE `username` = :username");
+ $stmt->execute(array(':username' => $_SESSION['mailcow_cc_username']));
+ $domain = $stmt->fetch(PDO::FETCH_ASSOC)['domain'];
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $validity = strtotime("+".$_data["validity"]." hour");
+ $letters = 'abcefghijklmnopqrstuvwxyz1234567890';
+ $random_name = substr(str_shuffle($letters), 0, 24);
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `spamalias` (`address`, `goto`, `validity`) VALUES
+ (:address, :goto, :validity)");
+ $stmt->execute(array(
+ ':address' => $random_name . '@' . $domain,
+ ':goto' => $username,
+ ':validity' => $validity
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($usernames))
+ );
+ break;
+ case 'syncjob':
+ if (isset($_data['username']) && filter_var($_data['username'], FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data['username'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ else {
+ $username = $_data['username'];
+ }
+ }
+ else {
+ $username = $_SESSION['mailcow_cc_username'];
+ }
+ $active = intval($_data['active']);
+ $delete2duplicates = intval($_data['delete2duplicates']);
+ $delete1 = intval($_data['delete1']);
+ $port1 = $_data['port1'];
+ $host1 = $_data['host1'];
+ $password1 = $_data['password1'];
+ $exclude = $_data['exclude'];
+ $maxage = $_data['maxage'];
+ $subfolder2 = $_data['subfolder2'];
+ $user1 = $_data['user1'];
+ $mins_interval = $_data['mins_interval'];
+ $enc1 = $_data['enc1'];
+ if (empty($subfolder2)) {
+ $subfolder2 = "";
+ }
+ if (!isset($maxage) || !filter_var($maxage, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 32767)))) {
+ $maxage = "0";
+ }
+ if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (!is_valid_domain_name($host1)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (@preg_match("/" . $exclude . "/", null) === false) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `user2`, `user1` FROM `imapsync`
+ WHERE `user2` = :user2 AND `user1` = :user1");
+ $stmt->execute(array(':user1' => $user1, ':user2' => $username));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($host1 . ' / ' . $user1))
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `imapsync` (`user2`, `exclude`, `delete1`, `maxage`, `subfolder2`, `host1`, `authmech1`, `user1`, `password1`, `mins_interval`, `port1`, `enc1`, `delete2duplicates`, `active`)
+ VALUES (:user2, :exclude, :maxage, :delete1, :subfolder2, :host1, :authmech1, :user1, :password1, :mins_interval, :port1, :enc1, :delete2duplicates, :active)");
+ $stmt->execute(array(
+ ':user2' => $username,
+ ':exclude' => $exclude,
+ ':maxage' => $maxage,
+ ':delete1' => $delete1,
+ ':subfolder2' => $subfolder2,
+ ':host1' => $host1,
+ ':authmech1' => 'PLAIN',
+ ':user1' => $user1,
+ ':password1' => $password1,
+ ':mins_interval' => $mins_interval,
+ ':port1' => $port1,
+ ':enc1' => $enc1,
+ ':delete2duplicates' => $delete2duplicates,
+ ':active' => $active,
+ ));
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
+ );
+ return true;
+ break;
+ case 'domain':
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ $domain = idn_to_ascii(strtolower(trim($_data['domain'])));
+ $description = $_data['description'];
+ $aliases = $_data['aliases'];
+ $mailboxes = $_data['mailboxes'];
+ $maxquota = $_data['maxquota'];
+ $quota = $_data['quota'];
+ if ($maxquota > $quota) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
+ );
+ return false;
+ }
+ if ($maxquota == "0" || empty($maxquota)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['maxquota_empty'])
+ );
+ return false;
+ }
+ $active = intval($_data['active']);
+ $relay_all_recipients = intval($_data['relay_all_recipients']);
+ $backupmx = intval($_data['backupmx']);
+ ($relay_all_recipients == 1) ? $backupmx = '1' : null;
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ foreach (array($quota, $maxquota, $mailboxes, $aliases) as $data) {
+ if (!is_numeric($data)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['object_is_not_numeric'], htmlspecialchars($data))
+ );
+ return false;
+ }
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
+ WHERE `domain` = :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain`
+ WHERE `alias_domain` = :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $num_results = $num_results + count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_exists'], htmlspecialchars($domain))
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `transport`, `backupmx`, `active`, `relay_all_recipients`)
+ VALUES (:domain, :description, :aliases, :mailboxes, :maxquota, :quota, 'virtual', :backupmx, :active, :relay_all_recipients)");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ':description' => $description,
+ ':aliases' => $aliases,
+ ':mailboxes' => $mailboxes,
+ ':maxquota' => $maxquota,
+ ':quota' => $quota,
+ ':backupmx' => $backupmx,
+ ':active' => $active,
+ ':relay_all_recipients' => $relay_all_recipients
+ ));
+ try {
+ $redis->hSet('DOMAIN_MAP', $domain, 1);
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Redis: '.$e
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_added'], htmlspecialchars($domain))
+ );
+ }
+ catch (PDOException $e) {
+ mailbox('delete', 'domain', array('domain' => $domain));
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ break;
+ case 'alias':
+ $addresses = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['address']));
+ $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['goto']));
+ $active = intval($_data['active']);
+ if (empty($addresses[0])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['alias_empty'])
+ );
+ return false;
+ }
+ if (empty($gotos[0])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['goto_empty'])
+ );
+ return false;
+ }
+ foreach ($addresses as $address) {
+ if (empty($address)) {
+ continue;
+ }
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias`
+ WHERE `address`= :address");
+ $stmt->execute(array(':address' => $address));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['is_alias_or_mailbox'], htmlspecialchars($address))
+ );
+ return false;
+ }
+ $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
+ $local_part = strstr($address, '@', true);
+ $address = $local_part.'@'.$domain;
+ $domaindata = mailbox('get', 'domain_details', $domain);
+ if (is_array($domaindata) && $domaindata['aliases_left'] == "0") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['max_alias_exceeded'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
+ WHERE `domain`= :domain1 OR `domain` = (SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain2)");
+ $stmt->execute(array(':domain1' => $domain, ':domain2' => $domain));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results == 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_not_found'], htmlspecialchars($domain))
+ );
+ return false;
+ }
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias`
+ WHERE `address`= :address");
+ $stmt->execute(array(':address' => $address));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['is_alias_or_mailbox'], htmlspecialchars($address))
+ );
+ return false;
+ }
+ $stmt = $pdo->prepare("SELECT `address` FROM `spamalias`
+ WHERE `address`= :address");
+ $stmt->execute(array(':address' => $address));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($address))
+ );
+ return false;
+ }
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['alias_invalid'])
+ );
+ return false;
+ }
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ foreach ($gotos as &$goto) {
+ if (empty($goto)) {
+ continue;
+ }
+ $goto_domain = idn_to_ascii(substr(strstr($goto, '@'), 1));
+ $goto_local_part = strstr($goto, '@', true);
+ $goto = $goto_local_part.'@'.$goto_domain;
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
+ WHERE `kind` REGEXP 'location|thing|group'
+ AND `username`= :goto");
+ $stmt->execute(array(':goto' => $goto));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['goto_invalid'])
+ );
+ return false;
+ }
+ if (!filter_var($goto, FILTER_VALIDATE_EMAIL) === true) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['goto_invalid'])
+ );
+ return false;
+ }
+ if ($goto == $address) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['alias_goto_identical'])
+ );
+ return false;
+ }
+ }
+ $gotos = array_filter($gotos);
+ $goto = implode(",", $gotos);
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `active`)
+ VALUES (:address, :goto, :domain, :active)");
+ if (!filter_var($address, FILTER_VALIDATE_EMAIL) === true) {
+ $stmt->execute(array(
+ ':address' => '@'.$domain,
+ ':goto' => $goto,
+ ':domain' => $domain,
+ ':active' => $active
+ ));
+ }
+ else {
+ $stmt->execute(array(
+ ':address' => $address,
+ ':goto' => $goto,
+ ':domain' => $domain,
+ ':active' => $active
+ ));
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['alias_added'])
+ );
+ }
+ catch (PDOException $e) {
+ mailbox('delete', 'alias', array('address' => $address));
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['alias_added'])
+ );
+ break;
+ case 'alias_domain':
+ $active = intval($_data['active']);
+ $alias_domain = idn_to_ascii(strtolower(trim($_data['alias_domain'])));
+ $target_domain = idn_to_ascii(strtolower(trim($_data['target_domain'])));
+ if (!is_valid_domain_name($alias_domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
+ );
+ return false;
+ }
+ if (!is_valid_domain_name($target_domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['target_domain_invalid'])
+ );
+ return false;
+ }
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $target_domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if ($alias_domain == $target_domain) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['aliasd_targetd_identical'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
+ WHERE `domain`= :target_domain");
+ $stmt->execute(array(':target_domain' => $target_domain));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results == 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['targetd_not_found'])
+ );
+ return false;
+ }
+ $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain
+ UNION
+ SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain_in_domain");
+ $stmt->execute(array(':alias_domain' => $alias_domain, ':alias_domain_in_domain' => $alias_domain));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['aliasd_exists'])
+ );
+ return false;
+ }
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `alias_domain` (`alias_domain`, `target_domain`, `active`)
+ VALUES (:alias_domain, :target_domain, :active)");
+ $stmt->execute(array(
+ ':alias_domain' => $alias_domain,
+ ':target_domain' => $target_domain,
+ ':active' => $active
+ ));
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['aliasd_added'], htmlspecialchars($alias_domain))
+ );
+ }
+ catch (PDOException $e) {
+ mailbox('delete', 'alias_domain', array('alias_domain' => $alias_domain));
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ break;
+ case 'mailbox':
+ $local_part = strtolower(trim($_data['local_part']));
+ $domain = idn_to_ascii(strtolower(trim($_data['domain'])));
+ $username = $local_part . '@' . $domain;
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['mailbox_invalid'])
+ );
+ return false;
+ }
+ if (empty($_data['local_part'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['mailbox_invalid'])
+ );
+ return false;
+ }
+ $password = $_data['password'];
+ $password2 = $_data['password2'];
+ $name = $_data['name'];
+ $quota_m = filter_var($_data['quota'], FILTER_SANITIZE_NUMBER_FLOAT);
+ if (empty($name)) {
+ $name = $local_part;
+ }
+ $active = intval($_data['active']);
+ $quota_b = ($quota_m * 1048576);
+ $maildir = $domain."/".$local_part."/";
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `mailboxes`, `maxquota`, `quota` FROM `domain`
+ WHERE `domain` = :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
+ $stmt = $pdo->prepare("SELECT
+ COUNT(*) as count,
+ COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota`
+ FROM `mailbox`
+ WHERE `kind` NOT REGEXP 'location|thing|group'
+ AND `domain` = :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
+ $stmt = $pdo->prepare("SELECT `local_part` FROM `mailbox` WHERE `local_part` = :local_part and `domain`= :domain");
+ $stmt->execute(array(':local_part' => $local_part, ':domain' => $domain));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($username))
+ );
+ return false;
+ }
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE address= :username");
+ $stmt->execute(array(':username' => $username));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['is_alias'], htmlspecialchars($username))
+ );
+ return false;
+ }
+ $stmt = $pdo->prepare("SELECT `address` FROM `spamalias` WHERE `address`= :username");
+ $stmt->execute(array(':username' => $username));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($username))
+ );
+ return false;
+ }
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain` WHERE `domain`= :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results == 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_not_found'], $domain)
+ );
+ return false;
+ }
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if (!is_numeric($quota_m) || $quota_m == "0") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['quota_not_0_not_numeric'])
+ );
+ return false;
+ }
+ if (!empty($password) && !empty($password2)) {
+ if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_complexity'])
+ );
+ return false;
+ }
+ if ($password != $password2) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_mismatch'])
+ );
+ return false;
+ }
+ $password_hashed = hash_password($password);
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_empty'])
+ );
+ return false;
+ }
+ if ($MailboxData['count'] >= $DomainData['mailboxes']) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['max_mailbox_exceeded'], $MailboxData['count'], $DomainData['mailboxes'])
+ );
+ return false;
+ }
+ if ($quota_m > $DomainData['maxquota']) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['mailbox_quota_exceeded'], $DomainData['maxquota'])
+ );
+ return false;
+ }
+ if (($MailboxData['quota'] + $quota_m) > $DomainData['quota']) {
+ $quota_left_m = ($DomainData['quota'] - $MailboxData['quota']);
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], $quota_left_m)
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `active`)
+ VALUES (:username, :password_hashed, :name, :maildir, :quota_b, :local_part, :domain, :active)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':password_hashed' => $password_hashed,
+ ':name' => $name,
+ ':maildir' => $maildir,
+ ':quota_b' => $quota_b,
+ ':local_part' => $local_part,
+ ':domain' => $domain,
+ ':active' => $active
+ ));
+ $stmt = $pdo->prepare("INSERT INTO `quota2` (`username`, `bytes`, `messages`)
+ VALUES (:username, '0', '0')");
+ $stmt->execute(array(':username' => $username));
+ $stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `active`)
+ VALUES (:username1, :username2, :domain, :active)");
+ $stmt->execute(array(
+ ':username1' => $username,
+ ':username2' => $username,
+ ':domain' => $domain,
+ ':active' => $active
+ ));
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_added'], htmlspecialchars($username))
+ );
+ }
+ catch (PDOException $e) {
+ mailbox('delete', 'mailbox', array('username' => $username));
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ break;
+ case 'resource':
+ $domain = idn_to_ascii(strtolower(trim($_data['domain'])));
+ $description = $_data['description'];
+ $local_part = preg_replace('/[^\da-z]/i', '', preg_quote($description, '/'));
+ $name = $local_part . '@' . $domain;
+ $kind = $_data['kind'];
+ $active = intval($_data['active']);
+ $multiple_bookings = intval($_data['multiple_bookings']);
+ if (!filter_var($name, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['resource_invalid'])
+ );
+ return false;
+ }
+ if (empty($description)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['description_invalid'])
+ );
+ return false;
+ }
+
+ if ($kind != 'location' && $kind != 'group' && $kind != 'thing') {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['resource_invalid'])
+ );
+ return false;
+ }
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `username` = :name");
+ $stmt->execute(array(':name' => $name));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($name))
+ );
+ return false;
+ }
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE address= :name");
+ $stmt->execute(array(':name' => $name));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['is_alias'], htmlspecialchars($name))
+ );
+ return false;
+ }
+ $stmt = $pdo->prepare("SELECT `address` FROM `spamalias` WHERE `address`= :name");
+ $stmt->execute(array(':name' => $name));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($name))
+ );
+ return false;
+ }
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain` WHERE `domain`= :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results == 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_not_found'], $domain)
+ );
+ return false;
+ }
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `active`, `multiple_bookings`, `kind`)
+ VALUES (:name, 'RESOURCE', :description, 'RESOURCE', 0, :local_part, :domain, :active, :multiple_bookings, :kind)");
+ $stmt->execute(array(
+ ':name' => $name,
+ ':description' => $description,
+ ':local_part' => $local_part,
+ ':domain' => $domain,
+ ':active' => $active,
+ ':kind' => $kind,
+ ':multiple_bookings' => $multiple_bookings
+ ));
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['resource_added'], htmlspecialchars($name))
+ );
+ }
+ catch (PDOException $e) {
+ mailbox('delete', 'resource', array('name' => $name));
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ break;
+ }
+ break;
+ case 'edit':
+ switch ($_type) {
+ case 'alias_domain':
+ if (!is_array($_data['alias_domain'])) {
+ $alias_domains = array();
+ $alias_domains[] = $_data['alias_domain'];
+ }
+ else {
+ $alias_domains = $_data['alias_domain'];
+ }
+ foreach ($alias_domains as $alias_domain) {
+ $alias_domain = idn_to_ascii(strtolower(trim($alias_domain)));
+ $is_now = mailbox('get', 'alias_domain_details', $alias_domain);
+ if (!empty($is_now)) {
+ $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
+ $target_domain = (!empty($_data['target_domain'])) ? idn_to_ascii(strtolower(trim($_data['target_domain']))) : $is_now['target_domain'];
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
+ );
+ return false;
+ }
+ if (!is_valid_domain_name($target_domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['target_domain_invalid'])
+ );
+ return false;
+ }
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $target_domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (empty(mailbox('get', 'domain_details', $target_domain))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['target_domain_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("UPDATE `alias_domain` SET
+ `target_domain` = :target_domain,
+ `active` = :active
+ WHERE `alias_domain` = :alias_domain");
+ $stmt->execute(array(
+ ':alias_domain' => $alias_domain,
+ ':target_domain' => $target_domain,
+ ':active' => $active
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['aliasd_modified'], htmlspecialchars(implode(', ', $alias_domains)))
+ );
+ break;
+ case 'tls_policy':
+ if (!is_array($_data['username'])) {
+ $usernames = array();
+ $usernames[] = $_data['username'];
+ }
+ else {
+ $usernames = $_data['username'];
+ }
+ foreach ($usernames as $username) {
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL) || !hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ $tls_enforce_out = intval($_data['tls_enforce_out']);
+ $tls_enforce_in = intval($_data['tls_enforce_in']);
+ $is_now = mailbox('get', 'tls_policy', $username);
+ if (!empty($is_now)) {
+ $tls_enforce_in = (isset($_data['tls_enforce_in'])) ? $_data['tls_enforce_in'] : $is_now['tls_enforce_in'];
+ $tls_enforce_out = (isset($_data['tls_enforce_out'])) ? $_data['tls_enforce_out'] : $is_now['tls_enforce_out'];
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("UPDATE `mailbox` SET `tls_enforce_out` = :tls_out, `tls_enforce_in` = :tls_in WHERE `username` = :username");
+ $stmt->execute(array(
+ ':tls_out' => $tls_enforce_out,
+ ':tls_in' => $tls_enforce_in,
+ ':username' => $username
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], implode(', ', $usernames))
+ );
+ break;
+ case 'spam_score':
+ if (!is_array($_data['username'])) {
+ $usernames = array();
+ $usernames[] = $_data['username'];
+ }
+ else {
+ $usernames = $_data['username'];
+ }
+ foreach ($usernames as $username) {
+ $lowspamlevel = explode(',', $_data['spam_score'])[0];
+ $highspamlevel = explode(',', $_data['spam_score'])[1];
+ if (!is_numeric($lowspamlevel) || !is_numeric($highspamlevel)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username
+ AND (`option` = 'lowspamlevel' OR `option` = 'highspamlevel')");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option`, `value`)
+ VALUES (:username, 'highspamlevel', :highspamlevel)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':highspamlevel' => $highspamlevel
+ ));
+ $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option`, `value`)
+ VALUES (:username, 'lowspamlevel', :lowspamlevel)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':lowspamlevel' => $lowspamlevel
+ ));
+ }
+ catch (PDOException $e) {
+ $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username
+ AND (`option` = 'lowspamlevel' OR `option` = 'highspamlevel')");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], implode(', ', $usernames))
+ );
+ break;
+ case 'time_limited_alias':
+ if (!is_array($_data['address'])) {
+ $addresses = array();
+ $addresses[] = $_data['address'];
+ }
+ else {
+ $addresses = $_data['address'];
+ }
+ foreach ($addresses as $address) {
+ try {
+ $stmt = $pdo->prepare("SELECT `goto` FROM `spamalias` WHERE `address` = :address");
+ $stmt->execute(array(':address' => $address));
+ $goto = $stmt->fetch(PDO::FETCH_ASSOC)['goto'];
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $goto)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("UPDATE `spamalias` SET `validity` = (`validity` + 3600) WHERE
+ `address` = :address AND
+ `validity` >= :validity");
+ $stmt->execute(array(
+ ':address' => $address,
+ ':validity' => time()
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars(implode(', ', $usernames)))
+ );
+ break;
+ case 'delimiter_action':
+ if (!is_array($_data['username'])) {
+ $usernames = array();
+ $usernames[] = $_data['username'];
+ }
+ else {
+ $usernames = $_data['username'];
+ }
+ foreach ($usernames as $username) {
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL) || !hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (isset($_data['tagged_mail_handler']) && $_data['tagged_mail_handler'] == "subject") {
+ try {
+ $redis->hSet('RCPT_WANTS_SUBJECT_TAG', $username, 1);
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Redis: '.$e
+ );
+ return false;
+ }
+ }
+ else {
+ try {
+ $redis->hDel('RCPT_WANTS_SUBJECT_TAG', $username);
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Redis: '.$e
+ );
+ return false;
+ }
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], implode(', ', $usernames))
+ );
+ break;
+ case 'syncjob':
+ if (!is_array($_data['id'])) {
+ $ids = array();
+ $ids[] = $_data['id'];
+ }
+ else {
+ $ids = $_data['id'];
+ }
+ foreach ($ids as $id) {
+ $is_now = mailbox('get', 'syncjob_details', $id);
+ if (!empty($is_now)) {
+ $username = $is_now['user2'];
+ $user1 = (!empty($_data['user1'])) ? $_data['user1'] : $is_now['user1'];
+ $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
+ $delete2duplicates = (isset($_data['delete2duplicates'])) ? $_data['delete2duplicates'] : $is_now['delete2duplicates'];
+ $delete1 = (isset($_data['delete1'])) ? $_data['delete1'] : $is_now['delete1'];
+ $port1 = (!empty($_data['port1'])) ? $_data['port1'] : $is_now['port1'];
+ $password1 = (!empty($_data['password1'])) ? $_data['password1'] : $is_now['password1'];
+ $host1 = (!empty($_data['host1'])) ? $_data['host1'] : $is_now['host1'];
+ $subfolder2 = (!empty($_data['subfolder2'])) ? $_data['subfolder2'] : $is_now['subfolder2'];
+ $enc1 = (!empty($_data['enc1'])) ? $_data['enc1'] : $is_now['enc1'];
+ $mins_interval = (!empty($_data['mins_interval'])) ? $_data['mins_interval'] : $is_now['mins_interval'];
+ $exclude = (!empty($_data['exclude'])) ? $_data['exclude'] : $is_now['exclude'];
+ $maxage = (!empty($_data['maxage'])) ? $_data['maxage'] : $is_now['maxage'];
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (empty($subfolder2)) {
+ $subfolder2 = "";
+ }
+ if (!isset($maxage) || !filter_var($maxage, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 32767)))) {
+ $maxage = "0";
+ }
+ if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (!is_valid_domain_name($host1)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (@preg_match("/" . $exclude . "/", null) === false) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("UPDATE `imapsync` SET `delete1` = :delete1, `maxage` = :maxage, `subfolder2` = :subfolder2, `exclude` = :exclude, `host1` = :host1, `user1` = :user1, `password1` = :password1, `mins_interval` = :mins_interval, `port1` = :port1, `enc1` = :enc1, `delete2duplicates` = :delete2duplicates, `active` = :active
+ WHERE `id` = :id");
+ $stmt->execute(array(
+ ':delete1' => $delete1,
+ ':id' => $id,
+ ':exclude' => $exclude,
+ ':maxage' => $maxage,
+ ':subfolder2' => $subfolder2,
+ ':host1' => $host1,
+ ':user1' => $user1,
+ ':password1' => $password1,
+ ':mins_interval' => $mins_interval,
+ ':port1' => $port1,
+ ':enc1' => $enc1,
+ ':delete2duplicates' => $delete2duplicates,
+ ':active' => $active,
+ ));
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
+ );
+ return true;
+ break;
+ case 'alias':
+ if (!is_array($_data['address'])) {
+ $addresses = array();
+ $addresses[] = $_data['address'];
+ }
+ else {
+ $addresses = $_data['address'];
+ }
+ foreach ($addresses as $address) {
+ $is_now = mailbox('get', 'alias_details', $address);
+ if (!empty($is_now)) {
+ $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
+ $goto = (!empty($_data['goto'])) ? $_data['goto'] : $is_now['goto'];
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['alias_invalid'])
+ );
+ return false;
+ }
+
+ $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['goto']));
+ foreach ($gotos as &$goto) {
+ if (empty($goto)) {
+ continue;
+ }
+ if (!filter_var($goto, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' =>sprintf($lang['danger']['goto_invalid'])
+ );
+ return false;
+ }
+ if ($goto == $address) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['alias_goto_identical'])
+ );
+ return false;
+ }
+ }
+ $gotos = array_filter($gotos);
+ $goto = implode(",", $gotos);
+
+ $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
+ $local_part = strstr($address, '@', true);
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['alias_invalid'])
+ );
+ return false;
+ }
+ try {
+ if (!empty($goto)) {
+ $stmt = $pdo->prepare("UPDATE `alias` SET
+ `goto` = :goto,
+ `active`= :active
+ WHERE `address` = :address");
+ $stmt->execute(array(
+ ':goto' => $goto,
+ ':active' => $active,
+ ':address' => $address
+ ));
+ }
+ else {
+ $stmt = $pdo->prepare("UPDATE `alias` SET
+ `active`= :active
+ WHERE `address` = :address");
+ $stmt->execute(array(
+ ':active' => $active,
+ ':address' => $address
+ ));
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['alias_modified'], htmlspecialchars(implode(', ', $addresses)))
+ );
+ break;
+ case 'domain':
+ if (!is_array($_data['domain'])) {
+ $domains = array();
+ $domains[] = $_data['domain'];
+ }
+ else {
+ $domains = $_data['domain'];
+ }
+ foreach ($domains as $domain) {
+ $domain = idn_to_ascii($domain);
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ if ($_SESSION['mailcow_cc_role'] == "domainadmin" &&
+ hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $description = $_data['description'];
+ $active = intval($_data['active']);
+ try {
+ $stmt = $pdo->prepare("UPDATE `domain` SET
+ `description` = :description
+ WHERE `domain` = :domain");
+ $stmt->execute(array(
+ ':description' => $description,
+ ':domain' => $domain
+ ));
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_modified'], htmlspecialchars($domain))
+ );
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ elseif ($_SESSION['mailcow_cc_role'] == "admin") {
+ $is_now = mailbox('get', 'domain_details', $domain);
+ if (!empty($is_now)) {
+ $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
+ $backupmx = (isset($_data['backupmx'])) ? $_data['backupmx'] : $is_now['backupmx_int'];
+ $relay_all_recipients = (isset($_data['relay_all_recipients'])) ? $_data['relay_all_recipients'] : $is_now['relay_all_recipients_int'];
+ $aliases = (!empty($_data['aliases'])) ? $_data['aliases'] : $is_now['max_num_aliases_for_domain'];
+ $mailboxes = (!empty($_data['mailboxes'])) ? $_data['mailboxes'] : $is_now['max_num_mboxes_for_domain'];
+ $maxquota = (!empty($_data['maxquota'])) ? $_data['maxquota'] : ($is_now['max_new_mailbox_quota'] / 1048576);
+ $quota = (!empty($_data['quota'])) ? $_data['quota'] : ($is_now['max_quota_for_domain'] / 1048576);
+ $description = (!empty($_data['description'])) ? $_data['description'] : $is_now['description'];
+ ($relay_all_recipients == '1') ? $backupmx = '1' : null;
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ try {
+ // todo: should be using api here
+ $stmt = $pdo->prepare("SELECT
+ COUNT(*) AS count,
+ 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'
+ AND domain = :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
+ // todo: should be using api here
+ $stmt = $pdo->prepare("SELECT COUNT(*) AS `count` FROM `alias`
+ WHERE domain = :domain
+ AND address NOT IN (
+ SELECT `username` FROM `mailbox`
+ )");
+ $stmt->execute(array(':domain' => $domain));
+ $AliasData = $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if ($maxquota > $quota) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
+ );
+ return false;
+ }
+ if ($maxquota == "0" || empty($maxquota)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['maxquota_empty'])
+ );
+ return false;
+ }
+ if ($MailboxData['biggest_mailbox'] > $maxquota) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['max_quota_in_use'], $MailboxData['biggest_mailbox'])
+ );
+ return false;
+ }
+ if ($MailboxData['quota_all'] > $quota) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_quota_m_in_use'], $MailboxData['quota_all'])
+ );
+ return false;
+ }
+ if ($MailboxData['count'] > $mailboxes) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['mailboxes_in_use'], $MailboxData['count'])
+ );
+ return false;
+ }
+ if ($AliasData['count'] > $aliases) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['aliases_in_use'], $AliasData['count'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("UPDATE `domain` SET
+ `relay_all_recipients` = :relay_all_recipients,
+ `backupmx` = :backupmx,
+ `active` = :active,
+ `quota` = :quota,
+ `maxquota` = :maxquota,
+ `mailboxes` = :mailboxes,
+ `aliases` = :aliases,
+ `description` = :description
+ WHERE `domain` = :domain");
+ $stmt->execute(array(
+ ':relay_all_recipients' => $relay_all_recipients,
+ ':backupmx' => $backupmx,
+ ':active' => $active,
+ ':quota' => $quota,
+ ':maxquota' => $maxquota,
+ ':mailboxes' => $mailboxes,
+ ':aliases' => $aliases,
+ ':description' => $description,
+ ':domain' => $domain
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_modified'], htmlspecialchars(implode(', ', $domains)))
+ );
+ break;
+ case 'mailbox':
+ if (!is_array($_data['username'])) {
+ $usernames = array();
+ $usernames[] = $_data['username'];
+ }
+ else {
+ $usernames = $_data['username'];
+ }
+ foreach ($usernames as $username) {
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ $is_now = mailbox('get', 'mailbox_details', $username);
+ if (!empty($is_now)) {
+ $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
+ $name = (!empty($_data['name'])) ? $_data['name'] : $is_now['name'];
+ $domain = $is_now['domain'];
+ $quota_m = (!empty($_data['quota'])) ? $_data['quota'] : ($is_now['quota'] / 1048576);
+ $quota_b = $quota_m * 1048576;
+ $password = (!empty($_data['password'])) ? $_data['password'] : null;
+ $password2 = (!empty($_data['password2'])) ? $_data['password2'] : null;
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `quota`, `maxquota`
+ FROM `domain`
+ WHERE `domain` = :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (!is_numeric($quota_m) || $quota_m == "0") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['quota_not_0_not_numeric'], htmlspecialchars($quota_m))
+ );
+ return false;
+ }
+ if ($quota_m > $DomainData['maxquota']) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['mailbox_quota_exceeded'], $DomainData['maxquota'])
+ );
+ return false;
+ }
+ if (((($is_now['quota_used'] / 1048576) - $quota_m) + $quota_m) > $DomainData['quota']) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], ($is_now['max_new_quota'] / 1048576))
+ );
+ return false;
+ }
+ if (isset($_data['sender_acl'])) {
+ // Get sender_acl items set by admin
+ $sender_acl_admin = array_merge(
+ mailbox('get', 'sender_acl_handles', $username)['sender_acl_domains']['ro'],
+ mailbox('get', 'sender_acl_handles', $username)['sender_acl_addresses']['ro']
+ );
+ // Get sender_acl items from POST array
+ $sender_acl_domain_admin = ($_data['sender_acl'] == "0") ? array() : $_data['sender_acl'];
+ if (!empty($sender_acl_domain_admin) || !empty($sender_acl_admin)) {
+ // Check items in POST array
+ foreach ($sender_acl_domain_admin as $sender_acl) {
+ if (!filter_var($sender_acl, FILTER_VALIDATE_EMAIL) && !is_valid_domain_name(ltrim($sender_acl, '@'))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
+ );
+ return false;
+ }
+ if (is_valid_domain_name(ltrim($sender_acl, '@'))) {
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], ltrim($sender_acl, '@'))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
+ );
+ return false;
+ }
+ }
+ if (filter_var($sender_acl, FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $sender_acl)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
+ );
+ return false;
+ }
+ }
+ }
+ // Merge both arrays
+ $sender_acl_merged = array_merge($sender_acl_domain_admin, $sender_acl_admin);
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ foreach ($sender_acl_merged as $sender_acl) {
+ $domain = ltrim($sender_acl, '@');
+ if (is_valid_domain_name($domain)) {
+ $sender_acl = '@' . $domain;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `sender_acl` (`send_as`, `logged_in_as`)
+ VALUES (:sender_acl, :username)");
+ $stmt->execute(array(
+ ':sender_acl' => $sender_acl,
+ ':username' => $username
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ }
+ else {
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ }
+ if (!empty($password) && !empty($password2)) {
+ if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_complexity'])
+ );
+ return false;
+ }
+ if ($password != $password2) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_mismatch'])
+ );
+ return false;
+ }
+ $password_hashed = hash_password($password);
+ try {
+ $stmt = $pdo->prepare("UPDATE `alias` SET
+ `active` = :active
+ WHERE `address` = :address");
+ $stmt->execute(array(
+ ':address' => $username,
+ ':active' => $active
+ ));
+ $stmt = $pdo->prepare("UPDATE `mailbox` SET
+ `active` = :active,
+ `password` = :password_hashed,
+ `name`= :name,
+ `quota` = :quota_b
+ WHERE `username` = :username");
+ $stmt->execute(array(
+ ':password_hashed' => $password_hashed,
+ ':active' => $active,
+ ':name' => $name,
+ ':quota_b' => $quota_b,
+ ':username' => $username
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ try {
+ $stmt = $pdo->prepare("UPDATE `alias` SET
+ `active` = :active
+ WHERE `address` = :address");
+ $stmt->execute(array(
+ ':address' => $username,
+ ':active' => $active
+ ));
+ $stmt = $pdo->prepare("UPDATE `mailbox` SET
+ `active` = :active,
+ `name`= :name,
+ `quota` = :quota_b
+ WHERE `username` = :username");
+ $stmt->execute(array(
+ ':active' => $active,
+ ':name' => $name,
+ ':quota_b' => $quota_b,
+ ':username' => $username
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], implode(', ', $usernames))
+ );
+ break;
+ case 'resource':
+ if (!is_array($_data['name'])) {
+ $names = array();
+ $names[] = $_data['name'];
+ }
+ else {
+ $names = $_data['name'];
+ }
+ foreach ($names as $name) {
+ $is_now = mailbox('get', 'resource_details', $name);
+ if (!empty($is_now)) {
+ $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
+ $multiple_bookings = (isset($_data['multiple_bookings'])) ? $_data['multiple_bookings'] : $is_now['multiple_bookings_int'];
+ $description = (!empty($_data['description'])) ? $_data['description'] : $is_now['description'];
+ $kind = (!empty($_data['kind'])) ? $_data['kind'] : $is_now['kind'];
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['resource_invalid'])
+ );
+ return false;
+ }
+ if (!filter_var($name, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['resource_invalid'])
+ );
+ return false;
+ }
+ if (empty($description)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['description_invalid'])
+ );
+ return false;
+ }
+ if ($kind != 'location' && $kind != 'group' && $kind != 'thing') {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['resource_invalid'])
+ );
+ return false;
+ }
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $name)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("UPDATE `mailbox` SET
+ `active` = :active,
+ `name`= :description,
+ `kind`= :kind,
+ `multiple_bookings`= :multiple_bookings
+ WHERE `username` = :name");
+ $stmt->execute(array(
+ ':active' => $active,
+ ':description' => $description,
+ ':multiple_bookings' => $multiple_bookings,
+ ':kind' => $kind,
+ ':name' => $name
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['resource_modified'], implode(', ', $names))
+ );
+ break;
+ }
+ break;
+ case 'get':
+ switch ($_type) {
+ case 'sender_acl_handles':
+ if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
+ return false;
+ }
+ $data['sender_acl_domains']['ro'] = array();
+ $data['sender_acl_domains']['rw'] = array();
+ $data['sender_acl_domains']['selectable'] = array();
+ $data['sender_acl_addresses']['ro'] = array();
+ $data['sender_acl_addresses']['rw'] = array();
+ $data['sender_acl_addresses']['selectable'] = array();
+ $data['fixed_sender_aliases'] = array();
+ try {
+ // Fixed addresses
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` REGEXP :goto AND `address` NOT LIKE '@%'");
+ $stmt->execute(array(':goto' => '(^|,)'.$_data.'($|,)'));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($rows)) {
+ $data['fixed_sender_aliases'][] = $row['address'];
+ }
+ $stmt = $pdo->prepare("SELECT CONCAT(`local_part`, '@', `alias_domain`.`alias_domain`) AS `alias_domain_alias` FROM `mailbox`, `alias_domain`
+ WHERE `alias_domain`.`target_domain` = `mailbox`.`domain`
+ AND `mailbox`.`username` = :username");
+ $stmt->execute(array(':username' => $_data));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($rows)) {
+ if (!empty($row['alias_domain_alias'])) {
+ $data['fixed_sender_aliases'][] = $row['alias_domain_alias'];
+ }
+ }
+ // Return array $data['sender_acl_domains/addresses']['ro'] with read-only objects
+ // Return array $data['sender_acl_domains/addresses']['rw'] with read-write objects (can be deleted)
+ $stmt = $pdo->prepare("SELECT REPLACE(`send_as`, '@', '') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as AND `send_as` LIKE '@%'");
+ $stmt->execute(array(':logged_in_as' => $_data));
+ $domain_rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($domain_row = array_shift($domain_rows)) {
+ if (is_valid_domain_name($domain_row['send_as']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain_row['send_as'])) {
+ $data['sender_acl_domains']['ro'][] = $domain_row['send_as'];
+ continue;
+ }
+ if (is_valid_domain_name($domain_row['send_as']) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain_row['send_as'])) {
+ $data['sender_acl_domains']['rw'][] = $domain_row['send_as'];
+ continue;
+ }
+ }
+ $stmt = $pdo->prepare("SELECT `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as AND `send_as` NOT LIKE '@%'");
+ $stmt->execute(array(':logged_in_as' => $_data));
+ $address_rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($address_row = array_shift($address_rows)) {
+ if (filter_var($address_row['send_as'], FILTER_VALIDATE_EMAIL) && !hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $address_row['send_as'])) {
+ $data['sender_acl_addresses']['ro'][] = $address_row['send_as'];
+ continue;
+ }
+ if (filter_var($address_row['send_as'], FILTER_VALIDATE_EMAIL) && hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $address_row['send_as'])) {
+ $data['sender_acl_addresses']['rw'][] = $address_row['send_as'];
+ continue;
+ }
+ }
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
+ WHERE `domain` NOT IN (
+ SELECT REPLACE(`send_as`, '@', '') FROM `sender_acl`
+ WHERE `logged_in_as` = :logged_in_as
+ AND `send_as` LIKE '@%')");
+ $stmt->execute(array(
+ ':logged_in_as' => $_data,
+ ));
+ $rows_domain = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row_domain = array_shift($rows_domain)) {
+ if (is_valid_domain_name($row_domain['domain']) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row_domain['domain'])) {
+ $data['sender_acl_domains']['selectable'][] = $row_domain['domain'];
+ }
+ }
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias`
+ WHERE `goto` != :goto
+ AND `address` NOT IN (
+ SELECT `send_as` FROM `sender_acl`
+ WHERE `logged_in_as` = :logged_in_as
+ AND `send_as` NOT LIKE '@%')");
+ $stmt->execute(array(
+ ':logged_in_as' => $_data,
+ ':goto' => $_data
+ ));
+ $rows_mbox = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($rows_mbox)) {
+ if (filter_var($row['address'], FILTER_VALIDATE_EMAIL) && hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row['address'])) {
+ $data['sender_acl_addresses']['selectable'][] = $row['address'];
+ }
+ }
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $data;
+ break;
+ case 'mailboxes':
+ $mailboxes = array();
+ if (isset($_data) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ elseif (isset($_data) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ try {
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` != 'ALL' AND `domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $_data,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $mailboxes[] = $row['username'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ else {
+ try {
+ $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->execute(array(
+ ':username' => $_SESSION['mailcow_cc_username'],
+ ':role' => $_SESSION['mailcow_cc_role'],
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $mailboxes[] = $row['username'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ return $mailboxes;
+ break;
+ case 'tls_policy':
+ $policydata = array();
+ if (isset($_data) && filter_var($_data, FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ }
+ else {
+ $_data = $_SESSION['mailcow_cc_username'];
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `tls_enforce_out`, `tls_enforce_in` FROM `mailbox` WHERE `username` = :username");
+ $stmt->execute(array(':username' => $_data));
+ $policydata = $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $policydata;
+ break;
+ case 'syncjob_details':
+ $syncjobdetails = array();
+ if (!is_numeric($_data)) {
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT * FROM `imapsync` WHERE id = :id");
+ $stmt->execute(array(':id' => $_data));
+ $syncjobdetails = $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ }
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $syncjobdetails['user2'])) {
+ return false;
+ }
+ return $syncjobdetails;
+ break;
+ case 'syncjobs':
+ $syncjobdata = array();
+ if (isset($_data) && filter_var($_data, FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ }
+ else {
+ $_data = $_SESSION['mailcow_cc_username'];
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT *,
+ CONCAT(LEFT(`password1`, 3), '...') AS `password1_short`,
+ `active` AS `active_int`,
+ CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
+ FROM `imapsync`
+ WHERE `user2` = :username");
+ $stmt->execute(array(':username' => $_data));
+ $syncjobdata = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ }
+ return $syncjobdata;
+ break;
+ case 'spam_score':
+ $default = "5, 15";
+ $policydata = array();
+ if (isset($_data) && filter_var($_data, FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ }
+ else {
+ $_data = $_SESSION['mailcow_cc_username'];
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `object` = :username AND
+ (`option` = 'lowspamlevel' OR `option` = 'highspamlevel')");
+ $stmt->execute(array(':username' => $_data));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if (empty($num_results)) {
+ return $default;
+ }
+ else {
+ try {
+ $stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `option` = 'highspamlevel' AND `object` = :username");
+ $stmt->execute(array(':username' => $_data));
+ $highspamlevel = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `option` = 'lowspamlevel' AND `object` = :username");
+ $stmt->execute(array(':username' => $_data));
+ $lowspamlevel = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ return $lowspamlevel['value'].', '.$highspamlevel['value'];
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ break;
+ case 'time_limited_aliases':
+ $tladata = array();
+ if (isset($_data) && filter_var($_data, FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ }
+ else {
+ $_data = $_SESSION['mailcow_cc_username'];
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `address`,
+ `goto`,
+ `validity`
+ FROM `spamalias`
+ WHERE `goto` = :username
+ AND `validity` >= :unixnow");
+ $stmt->execute(array(':username' => $_data, ':unixnow' => time()));
+ $tladata = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ }
+ return $tladata;
+ break;
+ case 'delimiter_action':
+ $policydata = array();
+ if (isset($_data) && filter_var($_data, FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ }
+ else {
+ $_data = $_SESSION['mailcow_cc_username'];
+ }
+ try {
+ if ($redis->hGet('RCPT_WANTS_SUBJECT_TAG', $_data)) {
+ return "subject";
+ }
+ else {
+ return "subfolder";
+ }
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Redis: '.$e
+ );
+ return false;
+ }
+ break;
+ case 'resources':
+ $resources = array();
+ if (isset($_data) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ elseif (isset($_data) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ try {
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' AND `domain` != 'ALL' AND `domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $_data,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $resources[] = $row['username'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ else {
+ try {
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' 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'],
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $resources[] = $row['username'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ return $resources;
+ break;
+ case 'alias_domains':
+ $aliasdomains = array();
+ if (isset($_data) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ elseif (isset($_data) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ try {
+ $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $_data,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $aliasdomains[] = $row['alias_domain'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ else {
+ try {
+ $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `target_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'],
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $aliasdomains[] = $row['alias_domain'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ return $aliasdomains;
+ break;
+ case 'aliases':
+ $aliases = array();
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `address` != `goto` AND `domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $_data,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $aliases[] = $row['address'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $aliases;
+ break;
+ case 'alias_details':
+ $aliasdata = array();
+ try {
+ $stmt = $pdo->prepare("SELECT
+ `domain`,
+ `goto`,
+ `address`,
+ `active` as `active_int`,
+ CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
+ `created`,
+ `modified`
+ FROM `alias`
+ WHERE `address` = :address AND `address` != `goto`");
+ $stmt->execute(array(
+ ':address' => $_data,
+ ));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $row['domain'],
+ ));
+ $row_alias_domain = $stmt->fetch(PDO::FETCH_ASSOC);
+ if (isset($row_alias_domain['target_domain']) && !empty($row_alias_domain['target_domain'])) {
+ $aliasdata['in_primary_domain'] = $row_alias_domain['target_domain'];
+ }
+ else {
+ $aliasdata['in_primary_domain'] = "";
+ }
+ $aliasdata['domain'] = $row['domain'];
+ $aliasdata['goto'] = $row['goto'];
+ $aliasdata['address'] = $row['address'];
+ (!filter_var($aliasdata['address'], FILTER_VALIDATE_EMAIL)) ? $aliasdata['is_catch_all'] = 1 : $aliasdata['is_catch_all'] = 0;
+ $aliasdata['active'] = $row['active'];
+ $aliasdata['active_int'] = $row['active_int'];
+ $aliasdata['created'] = $row['created'];
+ $aliasdata['modified'] = $row['modified'];
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdata['domain'])) {
+ return false;
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $aliasdata;
+ break;
+ case 'alias_domain_details':
+ $aliasdomaindata = array();
+ try {
+ $stmt = $pdo->prepare("SELECT
+ `alias_domain`,
+ `target_domain`,
+ `active` AS `active_int`,
+ CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
+ `created`,
+ `modified`
+ FROM `alias_domain`
+ WHERE `alias_domain` = :aliasdomain");
+ $stmt->execute(array(
+ ':aliasdomain' => $_data,
+ ));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ $aliasdomaindata['alias_domain'] = $row['alias_domain'];
+ $aliasdomaindata['target_domain'] = $row['target_domain'];
+ $aliasdomaindata['active'] = $row['active'];
+ $aliasdomaindata['active_int'] = $row['active_int'];
+ $aliasdomaindata['created'] = $row['created'];
+ $aliasdomaindata['modified'] = $row['modified'];
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdomaindata['target_domain'])) {
+ return false;
+ }
+ return $aliasdomaindata;
+ break;
+ case 'domains':
+ $domains = array();
+ if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
+ WHERE (`domain` IN (
+ SELECT `domain` from `domain_admins`
+ WHERE (`active`='1' AND `username` = :username))
+ )
+ OR ('admin'= :role)
+ AND `domain` != 'ALL'");
+ $stmt->execute(array(
+ ':username' => $_SESSION['mailcow_cc_username'],
+ ':role' => $_SESSION['mailcow_cc_role'],
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $domains[] = $row['domain'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $domains;
+ break;
+ case 'domain_details':
+ $domaindata = array();
+ $_data = idn_to_ascii(strtolower(trim($_data)));
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $_data
+ ));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ if (!empty($row)) {
+ $_data = $row['target_domain'];
+ }
+ $stmt = $pdo->prepare("SELECT
+ `domain`,
+ `description`,
+ `aliases`,
+ `mailboxes`,
+ `maxquota`,
+ `quota`,
+ `relay_all_recipients` as `relay_all_recipients_int`,
+ `backupmx` as `backupmx_int`,
+ `active` as `active_int`,
+ CASE `relay_all_recipients` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `relay_all_recipients`,
+ CASE `backupmx` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `backupmx`,
+ CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
+ FROM `domain` WHERE `domain`= :domain");
+ $stmt->execute(array(
+ ':domain' => $_data
+ ));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ if (empty($row)) {
+ return false;
+ }
+ $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`,
+ COALESCE(SUM(`quota`), 0) AS `in_use`
+ FROM `mailbox`
+ WHERE `kind` NOT REGEXP 'location|thing|group'
+ AND `domain` = :domain");
+ $stmt->execute(array(':domain' => $row['domain']));
+ $MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
+ $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);
+ }
+ $domaindata['quota_used_in_domain'] = $MailboxDataDomain['in_use'];
+ $domaindata['mboxes_in_domain'] = $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'];
+ $domaindata['max_num_mboxes_for_domain'] = $row['mailboxes'];
+ $domaindata['max_quota_for_mbox'] = $row['maxquota'] * 1048576;
+ $domaindata['max_quota_for_domain'] = $row['quota'] * 1048576;
+ $domaindata['backupmx'] = $row['backupmx'];
+ $domaindata['backupmx_int'] = $row['backupmx_int'];
+ $domaindata['active'] = $row['active'];
+ $domaindata['active_int'] = $row['active_int'];
+ $domaindata['relay_all_recipients'] = $row['relay_all_recipients'];
+ $domaindata['relay_all_recipients_int'] = $row['relay_all_recipients_int'];
+ $stmt = $pdo->prepare("SELECT COUNT(*) 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`
+ )");
+ $stmt->execute(array(
+ ':domain' => $_data,
+ ':domain2' => $_data
+ ));
+ $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'];
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $domaindata;
+ break;
+ case 'mailbox_details':
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ $mailboxdata = array();
+ try {
+ $stmt = $pdo->prepare("SELECT
+ `domain`.`backupmx`,
+ `mailbox`.`username`,
+ `mailbox`.`name`,
+ `mailbox`.`active` AS `active_int`,
+ CASE `mailbox`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
+ `mailbox`.`domain`,
+ `mailbox`.`quota`,
+ `quota2`.`bytes`,
+ `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");
+ $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 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'];
+ $mailboxdata['is_relayed'] = $row['backupmx'];
+ $mailboxdata['name'] = $row['name'];
+ $mailboxdata['active'] = $row['active'];
+ $mailboxdata['active_int'] = $row['active_int'];
+ $mailboxdata['domain'] = $row['domain'];
+ $mailboxdata['quota'] = $row['quota'];
+ $mailboxdata['quota_used'] = intval($row['bytes']);
+ $mailboxdata['percent_in_use'] = round((intval($row['bytes']) / intval($row['quota'])) * 100);
+ $mailboxdata['messages'] = $row['messages'];
+ $mailboxdata['spam_aliases'] = $SpamaliasUsage['sa_count'];
+ if ($mailboxdata['percent_in_use'] >= 90) {
+ $mailboxdata['percent_class'] = "danger";
+ }
+ elseif ($mailboxdata['percent_in_use'] >= 75) {
+ $mailboxdata['percent_class'] = "warning";
+ }
+ else {
+ $mailboxdata['percent_class'] = "success";
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $mailboxdata;
+ break;
+ case 'resource_details':
+ $resourcedata = array();
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT
+ `username`,
+ `name`,
+ `kind`,
+ `multiple_bookings` AS `multiple_bookings_int`,
+ `local_part`,
+ `active` AS `active_int`,
+ CASE `multiple_bookings` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `multiple_bookings`,
+ CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
+ `domain`
+ FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' AND `username` = :resource");
+ $stmt->execute(array(
+ ':resource' => $_data,
+ ));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ $resourcedata['name'] = $row['username'];
+ $resourcedata['kind'] = $row['kind'];
+ $resourcedata['multiple_bookings'] = $row['multiple_bookings'];
+ $resourcedata['multiple_bookings_int'] = $row['multiple_bookings_int'];
+ $resourcedata['description'] = $row['name'];
+ $resourcedata['active'] = $row['active'];
+ $resourcedata['active_int'] = $row['active_int'];
+ $resourcedata['domain'] = $row['domain'];
+ $resourcedata['local_part'] = $row['local_part'];
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if (!isset($resourcedata['domain']) ||
+ (isset($resourcedata['domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $resourcedata['domain']))) {
+ return false;
+ }
+ return $resourcedata;
+ break;
+ }
+ break;
+ case 'delete':
+ switch ($_type) {
+ case 'syncjob':
+ if (!is_array($_data['id'])) {
+ $ids = array();
+ $ids[] = $_data['id'];
+ }
+ else {
+ $ids = $_data['id'];
+ }
+ foreach ($ids as $id) {
+ if (!is_numeric($id)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => $id
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `user2` FROM `imapsync` WHERE id = :id");
+ $stmt->execute(array(':id' => $id));
+ $user2 = $stmt->fetch(PDO::FETCH_ASSOC)['user2'];
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $user2)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ $stmt = $pdo->prepare("DELETE FROM `imapsync` WHERE `id`= :id");
+ $stmt->execute(array(':id' => $id));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => 'Deleted syncjob id/s ' . implode(', ', $ids)
+ );
+ return true;
+ break;
+ case 'time_limited_alias':
+ if (!is_array($_data['address'])) {
+ $addresses = array();
+ $addresses[] = $_data['address'];
+ }
+ else {
+ $addresses = $_data['address'];
+ }
+ foreach ($addresses as $address) {
+ try {
+ $stmt = $pdo->prepare("SELECT `goto` FROM `spamalias` WHERE `address` = :address");
+ $stmt->execute(array(':address' => $address));
+ $goto = $stmt->fetch(PDO::FETCH_ASSOC)['goto'];
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $goto)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username AND `address` = :item");
+ $stmt->execute(array(
+ ':username' => $goto,
+ ':item' => $address
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($usernames))
+ );
+ break;
+ case 'eas_cache':
+ if (!is_array($_data['username'])) {
+ $usernames = array();
+ $usernames[] = $_data['username'];
+ }
+ else {
+ $usernames = $_data['username'];
+ }
+ foreach ($usernames as $username) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['eas_reset'], htmlspecialchars(implode(', ', $usernames)))
+ );
+ break;
+ case 'domain':
+ if (!is_array($_data['domain'])) {
+ $domains = array();
+ $domains[] = $_data['domain'];
+ }
+ else {
+ $domains = $_data['domain'];
+ }
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ foreach ($domains as $domain) {
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ $domain = idn_to_ascii(strtolower(trim($domain)));
+ try {
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
+ WHERE `domain` = :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if ($num_results != 0 || !empty($num_results)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_not_empty'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `domain` WHERE `domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `target_domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` LIKE :domain");
+ $stmt->execute(array(
+ ':domain' => '%@'.$domain,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :domain");
+ $stmt->execute(array(
+ ':domain' => '%@'.$domain,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `address` = :domain");
+ $stmt->execute(array(
+ ':domain' => '%@'.$domain,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :domain");
+ $stmt->execute(array(
+ ':domain' => '%@'.$domain,
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ try {
+ $redis->hDel('DOMAIN_MAP', $domain);
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Redis: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_removed'], htmlspecialchars(implode(', ', $domains)))
+ );
+ return true;
+ break;
+ case 'alias':
+ if (!is_array($_data['address'])) {
+ $addresses = array();
+ $addresses[] = $_data['address'];
+ }
+ else {
+ $addresses = $_data['address'];
+ }
+ foreach ($addresses as $address) {
+ $local_part = strstr($address, '@', true);
+ $domain = mailbox('get', 'alias_details', $address)['domain'];
+ try {
+ $stmt = $pdo->prepare("SELECT `goto` FROM `alias` WHERE `address` = :address");
+ $stmt->execute(array(':address' => $address));
+ $gotos = $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $goto_array = explode(',', $gotos['goto']);
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `address` = :address AND `address` NOT IN (SELECT `username` FROM `mailbox`)");
+ $stmt->execute(array(
+ ':address' => $address
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['alias_removed'], htmlspecialchars(implode(', ', $addresses)))
+ );
+ break;
+ case 'alias_domain':
+ if (!is_array($_data['alias_domain'])) {
+ $alias_domains = array();
+ $alias_domains[] = $_data['alias_domain'];
+ }
+ else {
+ $alias_domains = $_data['alias_domain'];
+ }
+ foreach ($alias_domains as $alias_domain) {
+ if (!is_valid_domain_name($alias_domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
+ WHERE `alias_domain`= :alias_domain");
+ $stmt->execute(array(':alias_domain' => $alias_domain));
+ $DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $DomainData['target_domain'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `alias_domain` = :alias_domain");
+ $stmt->execute(array(
+ ':alias_domain' => $alias_domain,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `domain` = :alias_domain");
+ $stmt->execute(array(
+ ':alias_domain' => $alias_domain,
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['alias_domain_removed'], htmlspecialchars(implode(', ', $alias_domains)))
+ );
+ break;
+ case 'mailbox':
+ if (!is_array($_data['username'])) {
+ $usernames = array();
+ $usernames[] = $_data['username'];
+ }
+ else {
+ $usernames = $_data['username'];
+ }
+ foreach ($usernames as $username) {
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `alias` WHERE `goto` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `imapsync` WHERE `user2` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_user_profile` WHERE `c_uid` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_acl` WHERE `c_object` LIKE '%/" . $username . "/%' OR `c_uid` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_store` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_quick_contact` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_quick_appointment` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_folder_info` WHERE `c_path2` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("SELECT `address`, `goto` FROM `alias`
+ WHERE `goto` REGEXP :username");
+ $stmt->execute(array(':username' => '(^|,)'.$username.'($|,)'));
+ $GotoData = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($GotoData as $gotos) {
+ $goto_exploded = explode(',', $gotos['goto']);
+ if (($key = array_search($username, $goto_exploded)) !== false) {
+ unset($goto_exploded[$key]);
+ }
+ $gotos_rebuild = implode(',', $goto_exploded);
+ $stmt = $pdo->prepare("UPDATE `alias` SET
+ `goto` = :goto
+ WHERE `address` = :address");
+ $stmt->execute(array(
+ ':goto' => $gotos_rebuild,
+ ':address' => $gotos['address']
+ ));
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_removed'], htmlspecialchars(implode(', ', $usernames)))
+ );
+ break;
+ case 'resource':
+ if (!is_array($_data['name'])) {
+ $names = array();
+ $names[] = $_data['name'];
+ }
+ else {
+ $names = $_data['name'];
+ }
+ foreach ($names as $name) {
+ if (!filter_var($name, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $name)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $name
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_user_profile` WHERE `c_uid` = :username");
+ $stmt->execute(array(
+ ':username' => $name
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username");
+ $stmt->execute(array(
+ ':username' => $name
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_acl` WHERE `c_object` LIKE '%/" . $name . "/%' OR `c_uid` = :username");
+ $stmt->execute(array(
+ ':username' => $name
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_store` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
+ $stmt->execute(array(
+ ':username' => $name
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_quick_contact` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
+ $stmt->execute(array(
+ ':username' => $name
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_quick_appointment` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
+ $stmt->execute(array(
+ ':username' => $name
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `sogo_folder_info` WHERE `c_path2` = :username");
+ $stmt->execute(array(
+ ':username' => $name
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['resource_removed'], htmlspecialchars(implode(', ', $names)))
+ );
+ break;
+ }
+ break;
+ }
+}
\ No newline at end of file
diff --git a/data/web/inc/functions.policy.inc.php b/data/web/inc/functions.policy.inc.php
new file mode 100644
index 00000000..01ef13ab
--- /dev/null
+++ b/data/web/inc/functions.policy.inc.php
@@ -0,0 +1,354 @@
+<?php
+
+function policy($_action, $_scope, $_data = null) {
+ global $pdo;
+ global $redis;
+ global $lang;
+ switch ($_action) {
+ case 'add':
+ switch ($_scope) {
+ case 'domain':
+ $object = $_data['domain'];
+ if (is_valid_domain_name($object)) {
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ $object = idn_to_ascii(strtolower(trim($object)));
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if ($_data['object_list'] == "bl") {
+ $object_list = "blacklist_from";
+ }
+ elseif ($_data['object_list'] == "wl") {
+ $object_list = "whitelist_from";
+ }
+ $object_from = preg_replace('/\.+/', '.', rtrim(preg_replace("/\.\*/", "*", trim(strtolower($_data['object_from']))), '.'));
+ if (!ctype_alnum(str_replace(array('@', '.', '-', '*'), '', $object_from))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['policy_list_from_invalid'])
+ );
+ return false;
+ }
+ if ($object_list != "blacklist_from" && $object_list != "whitelist_from") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `object` FROM `filterconf`
+ WHERE (`option` = 'whitelist_from' OR `option` = 'blacklist_from')
+ AND `object` = :object
+ AND `value` = :object_from");
+ $stmt->execute(array(':object' => $object, ':object_from' => $object_from));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['policy_list_from_exists'])
+ );
+ return false;
+ }
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option` ,`value`)
+ VALUES (:object, :object_list, :object_from)");
+ $stmt->execute(array(
+ ':object' => $object,
+ ':object_list' => $object_list,
+ ':object_from' => $object_from
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_modified'], $object)
+ );
+ break;
+ case 'mailbox':
+ $object = $_data['username'];
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if ($_data['object_list'] == "bl") {
+ $object_list = "blacklist_from";
+ }
+ elseif ($_data['object_list'] == "wl") {
+ $object_list = "whitelist_from";
+ }
+ $object_from = preg_replace('/\.+/', '.', rtrim(preg_replace("/\.\*/", "*", trim(strtolower($_data['object_from']))), '.'));
+ if (!ctype_alnum(str_replace(array('@', '.', '-', '*'), '', $object_from))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['policy_list_from_invalid'])
+ );
+ return false;
+ }
+ if ($object_list != "blacklist_from" && $object_list != "whitelist_from") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `object` FROM `filterconf`
+ WHERE (`option` = 'whitelist_from' OR `option` = 'blacklist_from')
+ AND `object` = :object
+ AND `value` = :object_from");
+ $stmt->execute(array(':object' => $object, ':object_from' => $object_from));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['policy_list_from_exists'])
+ );
+ return false;
+ }
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option` ,`value`)
+ VALUES (:object, :object_list, :object_from)");
+ $stmt->execute(array(
+ ':object' => $object,
+ ':object_list' => $object_list,
+ ':object_from' => $object_from
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], $object)
+ );
+ break;
+ }
+ break;
+ case 'delete':
+ switch ($_scope) {
+ case 'domain':
+ if (!is_array($_data['prefid'])) {
+ $prefids = array();
+ $prefids[] = $_data['prefid'];
+ }
+ else {
+ $prefids = $_data['prefid'];
+ }
+ foreach ($prefids as $prefid) {
+ if (!is_numeric($prefid)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `object` FROM `filterconf` WHERE `prefid` = :prefid");
+ $stmt->execute(array(':prefid' => $prefid));
+ $object = $stmt->fetch(PDO::FETCH_ASSOC)['object'];
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ }
+ if (is_valid_domain_name($object)) {
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ $object = idn_to_ascii(strtolower(trim($object)));
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :object AND `prefid` = :prefid");
+ $stmt->execute(array(
+ ':object' => $object,
+ ':prefid' => $prefid
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['items_deleted'], implode(', ', $prefids))
+ );
+ break;
+ case 'mailbox':
+ if (!is_array($_data['prefid'])) {
+ $prefids = array();
+ $prefids[] = $_data['prefid'];
+ }
+ else {
+ $prefids = $_data['prefid'];
+ }
+ foreach ($prefids as $prefid) {
+ if (!is_numeric($prefid)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `object` FROM `filterconf` WHERE `prefid` = :prefid");
+ $stmt->execute(array(':prefid' => $prefid));
+ $object = $stmt->fetch(PDO::FETCH_ASSOC)['object'];
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ }
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :object AND `prefid` = :prefid");
+ $stmt->execute(array(
+ ':object' => $object,
+ ':prefid' => $prefid
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['items_deleted'], implode(', ', $prefids))
+ );
+ break;
+ }
+ break;
+ case 'get':
+ switch ($_scope) {
+ case 'domain':
+ if (!is_valid_domain_name($_data)) {
+ return false;
+ }
+ else {
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ $_data = idn_to_ascii(strtolower(trim($_data)));
+ }
+ try {
+ // WHITELIST
+ $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='whitelist_from' AND (`object` LIKE :object_mail OR `object` = :object_domain)");
+ $stmt->execute(array(':object_mail' => '%@' . $_data, ':object_domain' => $_data));
+ $rows['whitelist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ // BLACKLIST
+ $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='blacklist_from' AND (`object` LIKE :object_mail OR `object` = :object_domain)");
+ $stmt->execute(array(':object_mail' => '%@' . $_data, ':object_domain' => $_data));
+ $rows['blacklist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ }
+ return $rows;
+ break;
+ case 'mailbox':
+ if (isset($_data) && filter_var($_data, FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ }
+ else {
+ $_data = $_SESSION['mailcow_cc_username'];
+ }
+ $domain = mailbox('get', 'mailbox_details', $_data)['domain'];
+ if (empty($domain)) {
+ return false;
+ }
+ try {
+ // WHITELIST
+ $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='whitelist_from' AND (`object` = :username OR `object` = :domain)");
+ $stmt->execute(array(':username' => $_data, ':domain' => $domain));
+ $rows['whitelist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ // BLACKLIST
+ $stmt = $pdo->prepare("SELECT `object`, `value`, `prefid` FROM `filterconf` WHERE `option`='blacklist_from' AND (`object` = :username OR `object` = :domain)");
+ $stmt->execute(array(':username' => $_data, ':domain' => $domain));
+ $rows['blacklist'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ }
+ return $rows;
+ break;
+ }
+ break;
+ }
+}
\ No newline at end of file
diff --git a/data/web/inc/header.inc.php b/data/web/inc/header.inc.php
index 170335e3..7845d75b 100644
--- a/data/web/inc/header.inc.php
+++ b/data/web/inc/header.inc.php
@@ -22,6 +22,7 @@
<?= (preg_match("/mailbox.php/i", $_SERVER['REQUEST_URI'])) ? '<link rel="stylesheet" href="/css/mailbox.css">' : null; ?>
<?= (preg_match("/admin.php/i", $_SERVER['REQUEST_URI'])) ? '<link rel="stylesheet" href="/css/admin.css">' : null; ?>
<?= (preg_match("/user.php/i", $_SERVER['REQUEST_URI'])) ? '<link rel="stylesheet" href="/css/user.css">' : null; ?>
+<?= (preg_match("/edit.php/i", $_SERVER['REQUEST_URI'])) ? '<link rel="stylesheet" href="/css/edit.css">' : null; ?>
<link rel="shortcut icon" href="/favicon.png" type="image/png">
<link rel="icon" href="/favicon.png" type="image/png">
</head>
diff --git a/data/web/inc/prerequisites.inc.php b/data/web/inc/prerequisites.inc.php
index 57ff479a..867bc106 100644
--- a/data/web/inc/prerequisites.inc.php
+++ b/data/web/inc/prerequisites.inc.php
@@ -42,28 +42,24 @@ try {
}
catch (PDOException $e) {
?>
-<center style='font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;'>?? Connection failed, database may be in warm-up state, please try again later.<br /><br />The following error was reported:<br/> <?=$e->getMessage();?></center>
+<center style='font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;'>Connection failed, database may be in warm-up state, please try again later.<br /><br />The following error was reported:<br/> <?=$e->getMessage();?></center>
<?php
exit;
}
// Set language
-$_SESSION['mailcow_locale'] = strtolower(trim($DEFAULT_LANG));
-
+if (!isset($_SESSION['mailcow_locale'])) {
+ $_SESSION['mailcow_locale'] = strtolower(trim($DEFAULT_LANG));
+}
if (isset($_GET['lang']) && in_array($_GET['lang'], $AVAILABLE_LANGUAGES)) {
$_SESSION['mailcow_locale'] = $_GET['lang'];
}
-elseif (isset($_COOKIE['language']) && in_array($_COOKIE['language'], $AVAILABLE_LANGUAGES)) {
- $_SESSION['mailcow_locale'] = $_COOKIE['language'];
-}
-if (isset($_SESSION['mailcow_locale']) && !file_exists($_SERVER['DOCUMENT_ROOT'] . '/lang/lang.'.$_SESSION['mailcow_locale'].'.php')) {
- $_SESSION['mailcow_locale'] = strtolower(trim($DEFAULT_LANG));
-}
-setcookie('language', $_SESSION['mailcow_locale']);
require_once $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.en.php';
include $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.'.$_SESSION['mailcow_locale'].'.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.mailbox.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.policy.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/init_db.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.inc.php';
init_db_schema();
diff --git a/data/web/inc/triggers.inc.php b/data/web/inc/triggers.inc.php
index 5d8e7b7d..43e65484 100644
--- a/data/web/inc/triggers.inc.php
+++ b/data/web/inc/triggers.inc.php
@@ -44,10 +44,7 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admin") {
if (isset($_GET["duallogin"])) {
if (filter_var($_GET["duallogin"], FILTER_VALIDATE_EMAIL)) {
- $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `username` = :duallogin");
- $stmt->execute(array(':duallogin' => $_GET["duallogin"]));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- if ($num_results != 0) {
+ if (!empty(mailbox('get', 'mailbox_details', $_GET["duallogin"]))) {
$_SESSION["dual-login"]["username"] = $_SESSION['mailcow_cc_username'];
$_SESSION["dual-login"]["role"] = $_SESSION['mailcow_cc_role'];
$_SESSION['mailcow_cc_username'] = $_GET["duallogin"];
@@ -83,35 +80,14 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "user
if (isset($_POST["edit_user_account"])) {
edit_user_account($_POST);
}
- if (isset($_POST["mailbox_reset_eas"])) {
- mailbox_reset_eas($_POST);
- }
- if (isset($_POST["edit_spam_score"])) {
- edit_spam_score($_POST);
- }
- if (isset($_POST["edit_delimiter_action"])) {
- edit_delimiter_action($_POST);
- }
if (isset($_POST["add_policy_list_item"])) {
- add_policy_list_item($_POST);
- }
- if (isset($_POST["delete_policy_list_item"])) {
- delete_policy_list_item($_POST);
- }
- if (isset($_POST["edit_tls_policy"])) {
- edit_tls_policy($_POST);
+ policy('add', 'mailbox', $_POST);
}
if (isset($_POST["add_syncjob"])) {
- add_syncjob($_POST);
+ mailbox('add', 'syncjob', $_POST);
}
if (isset($_POST["edit_syncjob"])) {
- edit_syncjob($_POST);
- }
- if (isset($_POST["delete_syncjob"])) {
- delete_syncjob($_POST);
- }
- if (isset($_POST["set_time_limited_aliases"])) {
- set_time_limited_aliases($_POST);
+ mailbox('edit', 'syncjob', $_POST);
}
}
if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin")) {
@@ -125,55 +101,52 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
unset_tfa_key($_POST);
}
if (isset($_POST["add_policy_list_item"])) {
- add_policy_list_item($_POST);
- }
- if (isset($_POST["delete_policy_list_item"])) {
- delete_policy_list_item($_POST);
+ policy('add', 'domain', $_POST);
}
if (isset($_POST["mailbox_add_domain"])) {
- mailbox_add_domain($_POST);
+ mailbox('add', 'domain', $_POST);
}
if (isset($_POST["mailbox_add_alias"])) {
- mailbox_add_alias($_POST);
+ mailbox('add', 'alias', $_POST);
}
if (isset($_POST["mailbox_add_alias_domain"])) {
- mailbox_add_alias_domain($_POST);
+ mailbox('add', 'alias_domain', $_POST);
}
if (isset($_POST["mailbox_add_mailbox"])) {
- mailbox_add_mailbox($_POST);
+ mailbox('add', 'mailbox', $_POST);
}
if (isset($_POST["mailbox_add_resource"])) {
- mailbox_add_resource($_POST);
+ mailbox('add', 'resource', $_POST);
}
if (isset($_POST["mailbox_edit_alias"])) {
- mailbox_edit_alias($_POST);
+ mailbox('edit', 'alias', $_POST);
}
if (isset($_POST["mailbox_edit_domain"])) {
- mailbox_edit_domain($_POST);
+ mailbox('edit', 'domain', $_POST);
}
if (isset($_POST["mailbox_edit_mailbox"])) {
- mailbox_edit_mailbox($_POST);
+ mailbox('edit', 'mailbox', $_POST);
}
if (isset($_POST["mailbox_edit_alias_domain"])) {
- mailbox_edit_alias_domain($_POST);
+ mailbox('edit', 'alias_domain', $_POST);
}
if (isset($_POST["mailbox_edit_resource"])) {
- mailbox_edit_resource($_POST);
+ mailbox('edit', 'resource', $_POST);
}
if (isset($_POST["mailbox_delete_domain"])) {
- mailbox_delete_domain($_POST);
+ mailbox('delete', 'domain', $_POST);
}
if (isset($_POST["mailbox_delete_alias"])) {
- mailbox_delete_alias($_POST);
+ mailbox('delete', 'delete_alias', $_POST);
}
if (isset($_POST["mailbox_delete_alias_domain"])) {
- mailbox_delete_alias_domain($_POST);
+ mailbox('delete', 'alias_domain', $_POST);
}
if (isset($_POST["mailbox_delete_mailbox"])) {
- mailbox_delete_mailbox($_POST);
+ mailbox('delete', 'mailbox', $_POST);
}
if (isset($_POST["mailbox_delete_resource"])) {
- mailbox_delete_resource($_POST);
+ mailbox('delete', 'resource', $_POST);
}
}
?>
diff --git a/data/web/js/admin.js b/data/web/js/admin.js
index 9d6642b9..810653ee 100644
--- a/data/web/js/admin.js
+++ b/data/web/js/admin.js
@@ -1,76 +1,20 @@
-$(document).ready(function() {
- // Collect values of input fields with name multi_select with same data-id to js array multi_data[data-id]
- var multi_data = [];
- $(document).on('change', 'input[name=multi_select]:checkbox', function() {
- if ($(this).is(':checked') && $(this).data('id')) {
- var id = $(this).data('id');
- if (typeof multi_data[id] == "undefined") {
- multi_data[id] = [];
- }
- multi_data[id].push($(this).val());
- }
- else {
- var id = $(this).data('id');
- multi_data[id].splice($.inArray($(this).val(), multi_data[id]),1);
- }
- });
- // Select checkbox by click on parent tr
- $(document).on('click', 'tbody>tr', function(e) {
- if (e.target.type == "checkbox") {
- e.stopPropagation();
- } else {
- var checkbox = $(this).find(':checkbox');
- checkbox.trigger('click');
- }
- });
- // Select or deselect all checkboxes with same data-id
- $(document).on('click', '#toggle_multi_select_all', function(e) {
- e.preventDefault();
- id = $(this).data("id");
- multi_data[id] = [];
- var all_checkboxes = $("input[data-id=" + id + "]:enabled");
- all_checkboxes.prop("checked", !all_checkboxes.prop("checked")).change();
- });
- // General API edit function
- $(document).on('click', '#delete_selected', function(e) {
- e.preventDefault();
- var id = $(this).data('id');
- if (typeof multi_data[id] == "undefined" || multi_data[id] == "") return;
- data_array = multi_data[id];
- api_url = $(this).data('api-url');
- $(document).on('show.bs.modal','#ConfirmDeleteModal', function () {
- $("#ItemsToDelete").empty();
- for (var i in data_array) {
- $("#ItemsToDelete").append("<li>" + data_array[i] + "</li>");
- }
- })
- $('#ConfirmDeleteModal').modal({
- backdrop: 'static',
- keyboard: false
- })
- .one('click', '#IsConfirmed', function(e) {
- $.ajax({
- type: "POST",
- dataType: "json",
- data: { "items": JSON.stringify(data_array), "csrf_token": csrf_token },
- url: '/api/v1/' + api_url,
- jsonp: false,
- complete: function (data) {
- location.reload(true);
- }
- });
- })
- .one('click', '#isCanceled', function(e) {
- $('#ConfirmDeleteModal').modal('hide');
- });;
- });
-
-});
jQuery(function($){
function unix_time_format(tm) {
var date = new Date(tm ? tm * 1000 : 0);
return date.toLocaleString();
}
+ function humanFileSize(bytes) {
+ if(Math.abs(bytes) < 1024) {
+ return bytes + ' B';
+ }
+ var units = ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
+ var u = -1;
+ do {
+ bytes /= 1024;
+ ++u;
+ } while(Math.abs(bytes) >= 1024 && u < units.length - 1);
+ return bytes.toFixed(1)+' '+units[u];
+ }
$("#refresh_postfix_log").on('click', function(e) {
e.preventDefault();
draw_postfix_logs();
@@ -83,6 +27,10 @@ jQuery(function($){
e.preventDefault();
draw_sogo_logs();
});
+ $("#refresh_rspamd_history").on('click', function(e) {
+ e.preventDefault();
+ draw_rspamd_history();
+ });
function draw_postfix_logs() {
ft_postfix_logs = FooTable.init('#postfix_log', {
"columns": [
@@ -307,10 +255,185 @@ jQuery(function($){
}
});
}
-
+ function draw_rspamd_history() {
+ ft_postfix_logs = FooTable.init('#rspamd_history', {
+ "columns": [{
+ "name": "message-id",
+ "title": "ID",
+ "breakpoints": "all",
+ "style": {
+ "minWidth": 130,
+ "overflow": "hidden",
+ "textOverflow": "ellipsis",
+ "wordBreak": "break-all",
+ "whiteSpace": "normal"
+ }
+ }, {
+ "name": "ip",
+ "title": "IP address",
+ "breakpoints": "all",
+ "style": {
+ "minWidth": 88
+ }
+ }, {
+ "name": "sender_mime",
+ "title": "From",
+ "breakpoints": "xs sm md",
+ "style": {
+ "minWidth": 100
+ }
+ }, {
+ "name": "rcpt_mime",
+ "title": "To",
+ "breakpoints": "xs sm md",
+ "style": {
+ "minWidth": 100
+ }
+ }, {
+ "name": "subject",
+ "title": "Subject",
+ "breakpoints": "all",
+ "style": {
+ "word-break": "break-all",
+ "minWidth": 150
+ }
+ }, {
+ "name": "action",
+ "title": "Action",
+ "style": {
+ "minwidth": 82
+ }
+ }, {
+ "name": "score",
+ "title": "Score",
+ "style": {
+ "maxWidth": 110
+ },
+ }, {
+ "name": "symbols",
+ "title": "Symbols",
+ "breakpoints": "all",
+ }, {
+ "name": "size",
+ "title": "Msg size",
+ "breakpoints": "all",
+ "style": {
+ "minwidth": 50,
+ },
+ "formatter": function(value) { return humanFileSize(value); }
+ }, {
+ "name": "scan_time",
+ "title": "Scan time",
+ "breakpoints": "all",
+ "style": {
+ "maxWidth": 72
+ },
+ }, {
+ "sorted": true,
+ "breakpoints": "all",
+ "direction": "DESC",
+ "name": "time",
+ "title": "Time",
+ }, {
+ "name": "user",
+ "title": "Authenticated user",
+ "breakpoints": "xs sm md",
+ "style": {
+ "minWidth": 100
+ }
+ }],
+ "rows": $.ajax({
+ dataType: 'json',
+ url: '/api/v1/get/logs/rspamd-history',
+ jsonp: false,
+ error: function () {
+ console.log('Cannot draw rspamd history table');
+ },
+ success: function (data) {
+ $.each(data, function (i, item) {
+ item.rcpt_mime = item.rcpt_mime.join(",​");
+ Object.keys(item.symbols).map(function(key) {
+ var sym = item.symbols[key];
+ if (sym.score <= 0) {
+ sym.score_formatted = '(<span class="text-success"><b>' + sym.score + '</b></span>)'
+ }
+ else {
+ sym.score_formatted = '(<span class="text-danger"><b>' + sym.score + '</b></span>)'
+ }
+ var str = '<strong>' + key + '</strong> ' + sym.score_formatted;
+ if (sym.options) {
+ str += ' [' + sym.options.join(",") + "]";
+ }
+ item.symbols[key].str = str;
+ });
+ item.symbols = Object.keys(item.symbols).
+ map(function(key) {
+ return item.symbols[key];
+ }).sort(function(e1, e2) {
+ return Math.abs(e1.score) < Math.abs(e2.score);
+ }).map(function(e) {
+ return e.str;
+ }).join("<br>\n");
+ item.time = {
+ "value": unix_time_format(item.unix_time),
+ "options": {
+ "sortValue": item.unix_time
+ }
+ };
+ var scan_time = item.time_real.toFixed(3) + ' / ' + item.time_virtual.toFixed(3);
+ item.scan_time = {
+ "options": {
+ "sortValue": item.time_real
+ },
+ "value": scan_time
+ };
+ if (item.action === 'clean' || item.action === 'no action') {
+ item.action = "<div class='label label-success'>" + item.action + "</div>";
+ } else if (item.action === 'rewrite subject' || item.action === 'add header' || item.action === 'probable spam') {
+ item.action = "<div class='label label-warning'>" + item.action + "</div>";
+ } else if (item.action === 'spam' || item.action === 'reject') {
+ item.action = "<div class='label label-danger'>" + item.action + "</div>";
+ } else {
+ item.action = "<div class='label label-info'>" + item.action + "</div>";
+ }
+ var score_content;
+ if (item.score < item.required_score) {
+ score_content = "[ <span class='text-success'>" + item.score.toFixed(2) + " / " + item.required_score + "</span> ]";
+ } else {
+ score_content = "[ <span class='text-danger'>" + item.score.toFixed(2) + " / " + item.required_score + "</span> ]";
+ }
+ item.score = {
+ "options": {
+ "sortValue": item.score
+ },
+ "value": score_content
+ };
+ if (item.user == null) {
+ item.user = "none";
+ }
+ });
+ }
+ }),
+ "empty": lang.empty,
+ "paging": {
+ "enabled": true,
+ "limit": 5,
+ "size": pagination_size
+ },
+ "filtering": {
+ "enabled": true,
+ "position": "left",
+ "placeholder": lang.filter_table
+ },
+ "sorting": {
+ "enabled": true
+ }
+ });
+ }
draw_postfix_logs();
draw_dovecot_logs();
draw_sogo_logs();
draw_domain_admins();
draw_fwd_hosts();
+ draw_rspamd_history();
});
\ No newline at end of file
diff --git a/data/web/js/api.js b/data/web/js/api.js
new file mode 100644
index 00000000..0343df43
--- /dev/null
+++ b/data/web/js/api.js
@@ -0,0 +1,154 @@
+$(document).ready(function() {
+ // Collect values of input fields with name "multi_select" an same data-id to js array multi_data[data-id]
+ var multi_data = [];
+ $(document).on('change', 'input[name=multi_select]:checkbox', function() {
+ if ($(this).is(':checked') && $(this).data('id')) {
+ var id = $(this).data('id');
+ if (typeof multi_data[id] == "undefined") {
+ multi_data[id] = [];
+ }
+ multi_data[id].push($(this).val());
+ }
+ else {
+ var id = $(this).data('id');
+ multi_data[id].splice($.inArray($(this).val(), multi_data[id]),1);
+ }
+ });
+
+ // Select checkbox by click on parent tr
+ $(document).on('click', 'tbody>tr', function(e) {
+ if (e.target.type == "checkbox") {
+ e.stopPropagation();
+ } else {
+ var checkbox = $(this).find(':checkbox');
+ checkbox.trigger('click');
+ }
+ });
+
+ // Select or deselect all checkboxes with same data-id
+ $(document).on('click', '#toggle_multi_select_all', function(e) {
+ e.preventDefault();
+ id = $(this).data("id");
+ multi_data[id] = [];
+ var all_checkboxes = $("input[data-id=" + id + "]:enabled");
+ all_checkboxes.prop("checked", !all_checkboxes.prop("checked")).change();
+ });
+
+ // General API edit actions
+ $(document).on('click', '#edit_selected', function(e) {
+ e.preventDefault();
+ var id = $(this).data('id');
+ var api_url = $(this).data('api-url');
+ var api_attr = $(this).data('api-attr');
+ // If clicked element #edit_selected is in a form with the same data-id as the button,
+ // we merge all input fields by {"name":"value"} into api-attr
+ if ($(this).closest("form").data('id') == id) {
+ var attr_to_merge = {};
+ $.each($(this).closest("form").serializeArray(), function(i, field) {
+ attr_to_merge[field.name] = field.value;
+ });
+ var api_attr = $.extend(api_attr, attr_to_merge)
+ }
+ // If clicked element #edit_selected has data-item attribute, it is added to "items"
+ if (typeof $(this).data('item') !== 'undefined') {
+ var id = $(this).data('id');
+ if (typeof multi_data[id] == "undefined") {
+ multi_data[id] = [];
+ }
+ multi_data[id].push($(this).data('item'));
+ }
+ if (typeof multi_data[id] == "undefined") return;
+ api_items = multi_data[id];
+ if (Object.keys(api_items).length !== 0) {
+ $.ajax({
+ type: "POST",
+ dataType: "json",
+ data: { "items": JSON.stringify(api_items), "attr": JSON.stringify(api_attr), "csrf_token": csrf_token },
+ url: '/api/v1/' + api_url,
+ jsonp: false,
+ complete: function (data) {
+ // var reponse = (JSON.parse(data.responseText));
+ // console.log(reponse.type);
+ // console.log(reponse.msg);
+ window.location = window.location.href.split("#")[0];
+ }
+ });
+ }
+ });
+
+ // General API add actions
+ $(document).on('click', '#add_item', function(e) {
+ e.preventDefault();
+ var id = $(this).data('id');
+ var api_url = $(this).data('api-url');
+ var api_attr = $(this).data('api-attr');
+ // If clicked button is in a form with the same data-id as the button,
+ // we merge all input fields by {"name":"value"} into api-attr
+ if ($(this).closest("form").data('id') == id) {
+ var attr_to_merge = {};
+ $.each($(this).closest("form").serializeArray(), function(i, field) {
+ attr_to_merge[field.name] = field.value;
+ });
+ var api_attr = $.extend(api_attr, attr_to_merge)
+ }
+ $.ajax({
+ type: "POST",
+ dataType: "json",
+ data: { "attr": JSON.stringify(api_attr), "csrf_token": csrf_token },
+ url: '/api/v1/' + api_url,
+ jsonp: false,
+ complete: function (data) {
+ // var reponse = (JSON.parse(data.responseText));
+ // console.log(reponse.type);
+ // console.log(reponse.msg);
+ window.location = window.location.href.split("#")[0];
+ }
+ });
+ });
+ // General API delete actions
+ $(document).on('click', '#delete_selected', function(e) {
+ e.preventDefault();
+ var id = $(this).data('id');
+ // If clicked element #delete_selected has data-item attribute, it is added to "items"
+ if (typeof $(this).data('item') !== 'undefined') {
+ var id = $(this).data('id');
+ if (typeof multi_data[id] == "undefined") {
+ multi_data[id] = [];
+ }
+ multi_data[id].splice($.inArray($(this).data('item'), multi_data[id]),1);
+ multi_data[id].push($(this).data('item'));
+ }
+ if (typeof $(this).data('text') !== 'undefined') {
+ $("#DeleteText").empty();
+ $("#DeleteText").text($(this).data('text'));
+ }
+ if (typeof multi_data[id] == "undefined" || multi_data[id] == "") return;
+ data_array = multi_data[id];
+ api_url = $(this).data('api-url');
+ $(document).on('show.bs.modal','#ConfirmDeleteModal', function () {
+ $("#ItemsToDelete").empty();
+ for (var i in data_array) {
+ $("#ItemsToDelete").append("<li>" + data_array[i] + "</li>");
+ }
+ })
+ $('#ConfirmDeleteModal').modal({
+ backdrop: 'static',
+ keyboard: false
+ })
+ .one('click', '#IsConfirmed', function(e) {
+ $.ajax({
+ type: "POST",
+ dataType: "json",
+ data: { "items": JSON.stringify(data_array), "csrf_token": csrf_token },
+ url: '/api/v1/' + api_url,
+ jsonp: false,
+ complete: function (data) {
+ window.location = window.location.href.split("#")[0];
+ }
+ });
+ })
+ .one('click', '#isCanceled', function(e) {
+ $('#ConfirmDeleteModal').modal('hide');
+ });;
+ });
+});
\ No newline at end of file
diff --git a/data/web/js/edit.js b/data/web/js/edit.js
new file mode 100644
index 00000000..4b3654b2
--- /dev/null
+++ b/data/web/js/edit.js
@@ -0,0 +1,83 @@
+jQuery(function($){
+ // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
+ function validateEmail(email) {
+ var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+ return re.test(email);
+ }
+ function draw_wl_policy_domain_table() {
+ ft_wl_policy_mailbox_table = FooTable.init('#wl_policy_domain_table', {
+ "columns": [
+ {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
+ {"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
+ {"sorted": true,"name":"value","title":lang.spamfilter_table_rule},
+ {"name":"object","title":"Scope"}
+ ],
+ "empty": lang.empty,
+ "rows": $.ajax({
+ dataType: 'json',
+ url: '/api/v1/get/policy_wl_domain/' + table_for_domain,
+ jsonp: false,
+ error: function () {
+ console.log('Cannot draw mailbox policy wl table');
+ },
+ success: function (data) {
+ $.each(data, function (i, item) {
+ if (!validateEmail(item.object)) {
+ item.chkbox = '<input type="checkbox" data-id="policy_wl_domain" name="multi_select" value="' + item.prefid + '" />';
+ }
+ else {
+ item.chkbox = '<input type="checkbox" disabled title="' + lang.spamfilter_table_domain_policy + '" />';
+ }
+ });
+ }
+ }),
+ "paging": {
+ "enabled": true,
+ "limit": 5,
+ "size": pagination_size
+ },
+ "sorting": {
+ "enabled": true
+ }
+ });
+ }
+ function draw_bl_policy_domain_table() {
+ ft_bl_policy_mailbox_table = FooTable.init('#bl_policy_domain_table', {
+ "columns": [
+ {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
+ {"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
+ {"sorted": true,"name":"value","title":lang.spamfilter_table_rule},
+ {"name":"object","title":"Scope"}
+ ],
+ "empty": lang.empty,
+ "rows": $.ajax({
+ dataType: 'json',
+ url: '/api/v1/get/policy_bl_domain/' + table_for_domain,
+ jsonp: false,
+ error: function () {
+ console.log('Cannot draw mailbox policy bl table');
+ },
+ success: function (data) {
+ $.each(data, function (i, item) {
+ if (!validateEmail(item.object)) {
+ item.chkbox = '<input type="checkbox" data-id="policy_bl_domain" name="multi_select" value="' + item.prefid + '" />';
+ }
+ else {
+ item.chkbox = '<input type="checkbox" disabled tooltip="' + lang.spamfilter_table_domain_policy + '" />';
+ }
+ });
+ }
+ }),
+ "paging": {
+ "enabled": true,
+ "limit": 5,
+ "size": pagination_size
+ },
+ "sorting": {
+ "enabled": true
+ }
+ });
+ }
+ draw_wl_policy_domain_table();
+ draw_bl_policy_domain_table();
+});
\ No newline at end of file
diff --git a/data/web/js/mailbox.js b/data/web/js/mailbox.js
index 100c9235..80d84339 100644
--- a/data/web/js/mailbox.js
+++ b/data/web/js/mailbox.js
@@ -1,95 +1,3 @@
-$(document).ready(function() {
- // Collect values of input fields with name multi_select with same data-id to js array multi_data[data-id]
- var multi_data = [];
- $(document).on('change', 'input[name=multi_select]:checkbox', function() {
- if ($(this).is(':checked') && $(this).data('id')) {
- var id = $(this).data('id');
- if (typeof multi_data[id] == "undefined") {
- multi_data[id] = [];
- }
- multi_data[id].push($(this).val());
- }
- else {
- var id = $(this).data('id');
- multi_data[id].splice($.inArray($(this).val(), multi_data[id]),1);
- }
- });
- // Select checkbox by click on parent tr
- $(document).on('click', 'tbody>tr', function(e) {
- if (e.target.type == "checkbox") {
- e.stopPropagation();
- } else {
- var checkbox = $(this).find(':checkbox');
- checkbox.trigger('click');
- }
- });
- // Select or deselect all checkboxes with same data-id
- $(document).on('click', '#toggle_multi_select_all', function(e) {
- e.preventDefault();
- id = $(this).data("id");
- multi_data[id] = [];
- var all_checkboxes = $("input[data-id=" + id + "]:enabled");
- all_checkboxes.prop("checked", !all_checkboxes.prop("checked")).change();
- });
- // General API edit actions
- $(document).on('click', '#edit_selected', function(e) {
- e.preventDefault();
- var id = $(this).data('id');
- if (typeof multi_data[id] == "undefined") return;
- data_array = multi_data[id];
- api_url = $(this).data('api-url');
- api_attr = $(this).data('api-attr');
- if (Object.keys(data_array).length !== 0) {
- $.ajax({
- type: "POST",
- dataType: "json",
- data: { "items": JSON.stringify(data_array), "attr": JSON.stringify(api_attr), "csrf_token": csrf_token },
- url: '/api/v1/' + api_url,
- jsonp: false,
- complete: function (data) {
- // var reponse = (JSON.parse(data.responseText));
- // console.log(reponse.type);
- // console.log(reponse.msg);
- location.assign(window.location);
- }
- });
- }
- });
- // General API delete actions
- $(document).on('click', '#delete_selected', function(e) {
- e.preventDefault();
- var id = $(this).data('id');
- if (typeof multi_data[id] == "undefined" || multi_data[id] == "") return;
- data_array = multi_data[id];
- api_url = $(this).data('api-url');
- $(document).on('show.bs.modal','#ConfirmDeleteModal', function () {
- $("#ItemsToDelete").empty();
- for (var i in data_array) {
- $("#ItemsToDelete").append("<li>" + data_array[i] + "</li>");
- }
- })
- $('#ConfirmDeleteModal').modal({
- backdrop: 'static',
- keyboard: false
- })
- .one('click', '#IsConfirmed', function(e) {
- $.ajax({
- type: "POST",
- dataType: "json",
- data: { "items": JSON.stringify(data_array), "csrf_token": csrf_token },
- url: '/api/v1/' + api_url,
- jsonp: false,
- complete: function (data) {
- location.assign(window.location);
- }
- });
- })
- .one('click', '#isCanceled', function(e) {
- $('#ConfirmDeleteModal').modal('hide');
- });;
- });
-});
-
jQuery(function($){
// Calculation human readable file sizes
function humanFileSize(bytes) {
diff --git a/data/web/js/user.js b/data/web/js/user.js
index 7959cc5a..8e94b85e 100644
--- a/data/web/js/user.js
+++ b/data/web/js/user.js
@@ -1,29 +1,4 @@
$(document).ready(function() {
- // Show and activate password fields after box was checked
- // Hidden by default
- if ( !$("#togglePwNew").is(':checked') ) {
- $(".passFields").hide();
- }
- $('#togglePwNew').click(function() {
- $("#user_new_pass").attr("disabled", !this.checked);
- $("#user_new_pass2").attr("disabled", !this.checked);
- var $this = $(this);
- if ($this.is(':checked')) {
- $(".passFields").slideDown();
- } else {
- $(".passFields").slideUp();
- }
- });
- // Show generate button after time selection
- $('#generate_tla').hide();
- $('#validity').change(function(){
- $('#generate_tla').show();
- });
-
- // Init Bootstrap Switch
- $.fn.bootstrapSwitch.defaults.onColor = 'success';
- $("#tls_out").bootstrapSwitch();
- $("#tls_in").bootstrapSwitch();
// Log modal
$('#logModal').on('show.bs.modal', function(e) {
@@ -31,96 +6,8 @@ $(document).ready(function() {
$(e.currentTarget).find('#logText').html('<pre style="background:none;font-size:11px;line-height:1.1;border:0px">' + logText + '</pre>');
});
- // Collect values of input fields with name multi_select with same data-id to js array multi_data[data-id]
- var multi_data = [];
- $(document).on('change', 'input[name=multi_select]:checkbox', function() {
- if ($(this).is(':checked') && $(this).data('id')) {
- var id = $(this).data('id');
- if (typeof multi_data[id] == "undefined") {
- multi_data[id] = [];
- }
- multi_data[id].push($(this).val());
- }
- else {
- var id = $(this).data('id');
- multi_data[id].splice($.inArray($(this).val(), multi_data[id]),1);
- }
- });
- // Select checkbox by click on parent tr
- $(document).on('click', 'tbody>tr', function(e) {
- if (e.target.type == "checkbox") {
- e.stopPropagation();
- } else {
- var checkbox = $(this).find(':checkbox');
- checkbox.trigger('click');
- }
- });
- // Select or deselect all checkboxes with same data-id
- $(document).on('click', '#toggle_multi_select_all', function(e) {
- e.preventDefault();
- id = $(this).data("id");
- multi_data[id] = [];
- var all_checkboxes = $("input[data-id=" + id + "]:enabled");
- all_checkboxes.prop("checked", !all_checkboxes.prop("checked")).change();
- });
- // General API edit actions
- $(document).on('click', '#edit_selected', function(e) {
- e.preventDefault();
- var id = $(this).data('id');
- if (typeof multi_data[id] == "undefined") return;
- data_array = multi_data[id];
- api_url = $(this).data('api-url');
- api_attr = $(this).data('api-attr');
- if (Object.keys(data_array).length !== 0) {
- $.ajax({
- type: "POST",
- dataType: "json",
- data: { "items": JSON.stringify(data_array), "attr": JSON.stringify(api_attr), "csrf_token": csrf_token },
- url: '/api/v1/' + api_url,
- jsonp: false,
- complete: function (data) {
- // var reponse = (JSON.parse(data.responseText));
- // console.log(reponse.type);
- // console.log(reponse.msg);
- location.assign(window.location);
- }
- });
- }
- });
- // General API delete actions
- $(document).on('click', '#delete_selected', function(e) {
- e.preventDefault();
- var id = $(this).data('id');
- if (typeof multi_data[id] == "undefined" || multi_data[id] == "") return;
- data_array = multi_data[id];
- api_url = $(this).data('api-url');
- $(document).on('show.bs.modal','#ConfirmDeleteModal', function () {
- $("#ItemsToDelete").empty();
- for (var i in data_array) {
- $("#ItemsToDelete").append("<li>" + data_array[i] + "</li>");
- }
- })
- $('#ConfirmDeleteModal').modal({
- backdrop: 'static',
- keyboard: false
- })
- .one('click', '#IsConfirmed', function(e) {
- $.ajax({
- type: "POST",
- dataType: "json",
- data: { "items": JSON.stringify(data_array), "csrf_token": csrf_token },
- url: '/api/v1/' + api_url,
- jsonp: false,
- complete: function (data) {
- location.reload(true);
- }
- });
- })
- .one('click', '#isCanceled', function(e) {
- $('#ConfirmDeleteModal').modal('hide');
- });;
- });
});
+
jQuery(function($){
// http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery
var entityMap = {
@@ -138,11 +25,52 @@ jQuery(function($){
return entityMap[s];
});
}
+ // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
+ function validateEmail(email) {
+ var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+ return re.test(email);
+ }
+ function unix_time_format(tm) {
+ var date = new Date(tm ? tm * 1000 : 0);
+ return date.toLocaleString();
+ }
+ function draw_tla_table() {
+ ft_tla_table = FooTable.init('#tla_table', {
+ "columns": [
+ {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
+ {"sorted": true,"name":"address","title":lang.alias},
+ {"name":"validity","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},"title":lang.alias_valid_until,"style":{"width":"170px"}},
+ ],
+ "empty": lang.empty,
+ "rows": $.ajax({
+ dataType: 'json',
+ url: '/api/v1/get/time_limited_aliases',
+ jsonp: false,
+ error: function () {
+ console.log('Cannot draw tla table');
+ },
+ success: function (data) {
+ $.each(data, function (i, item) {
+ item.chkbox = '<input type="checkbox" data-id="tla" name="multi_select" value="' + item.address + '" />';
+ });
+ }
+ }),
+ "paging": {
+ "enabled": true,
+ "limit": 5,
+ "size": pagination_size
+ },
+ "sorting": {
+ "enabled": true
+ }
+ });
+ }
function draw_sync_job_table() {
- ft_aliasdomain_table = FooTable.init('#sync_job_table', {
+ ft_syncjob_table = FooTable.init('#sync_job_table', {
"columns": [
- {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
- {"sorted": true,"name":"server_w_port","title":"Server"},
+ {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
+ {"sorted": true,"name":"id","title":"ID"},
+ {"name":"server_w_port","title":"Server"},
{"name":"enc1","title":lang.encryption},
{"name":"user1","title":lang.username},
{"name":"exclude","title":lang.excludes},
@@ -155,7 +83,7 @@ jQuery(function($){
"empty": lang.empty,
"rows": $.ajax({
dataType: 'json',
- url: '/api/v1/get/syncjob',
+ url: '/api/v1/get/syncjobs',
jsonp: false,
error: function () {
console.log('Cannot draw sync job table');
@@ -182,5 +110,82 @@ jQuery(function($){
}
});
}
+ function draw_wl_policy_mailbox_table() {
+ ft_wl_policy_mailbox_table = FooTable.init('#wl_policy_mailbox_table', {
+ "columns": [
+ {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
+ {"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
+ {"sorted": true,"name":"value","title":lang.spamfilter_table_rule},
+ {"name":"object","title":"Scope"}
+ ],
+ "empty": lang.empty,
+ "rows": $.ajax({
+ dataType: 'json',
+ url: '/api/v1/get/policy_wl_mailbox',
+ jsonp: false,
+ error: function () {
+ console.log('Cannot draw mailbox policy wl table');
+ },
+ success: function (data) {
+ $.each(data, function (i, item) {
+ if (validateEmail(item.object)) {
+ item.chkbox = '<input type="checkbox" data-id="policy_wl_mailbox" name="multi_select" value="' + item.prefid + '" />';
+ }
+ else {
+ item.chkbox = '<input type="checkbox" disabled title="' + lang.spamfilter_table_domain_policy + '" />';
+ }
+ });
+ }
+ }),
+ "paging": {
+ "enabled": true,
+ "limit": 5,
+ "size": pagination_size
+ },
+ "sorting": {
+ "enabled": true
+ }
+ });
+ }
+ function draw_bl_policy_mailbox_table() {
+ ft_bl_policy_mailbox_table = FooTable.init('#bl_policy_mailbox_table', {
+ "columns": [
+ {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
+ {"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
+ {"sorted": true,"name":"value","title":lang.spamfilter_table_rule},
+ {"name":"object","title":"Scope"}
+ ],
+ "empty": lang.empty,
+ "rows": $.ajax({
+ dataType: 'json',
+ url: '/api/v1/get/policy_bl_mailbox',
+ jsonp: false,
+ error: function () {
+ console.log('Cannot draw mailbox policy bl table');
+ },
+ success: function (data) {
+ $.each(data, function (i, item) {
+ if (validateEmail(item.object)) {
+ item.chkbox = '<input type="checkbox" data-id="policy_bl_mailbox" name="multi_select" value="' + item.prefid + '" />';
+ }
+ else {
+ item.chkbox = '<input type="checkbox" disabled tooltip="' + lang.spamfilter_table_domain_policy + '" />';
+ }
+ });
+ }
+ }),
+ "paging": {
+ "enabled": true,
+ "limit": 5,
+ "size": pagination_size
+ },
+ "sorting": {
+ "enabled": true
+ }
+ });
+ }
draw_sync_job_table();
+ draw_tla_table();
+ draw_wl_policy_mailbox_table();
+ draw_bl_policy_mailbox_table();
});
\ No newline at end of file
diff --git a/data/web/json_api.php b/data/web/json_api.php
index a2d08e39..5c9d729f 100644
--- a/data/web/json_api.php
+++ b/data/web/json_api.php
@@ -25,15 +25,52 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
$extra = (isset($query[3])) ? $query[3] : null;
switch ($action) {
+ case "add":
+ switch ($category) {
+ case "time_limited_alias":
+ if (isset($_POST['attr'])) {
+ $attr = (array)json_decode($_POST['attr'], true);
+ if (mailbox('add', 'time_limited_alias', $attr) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Cannot add item'
+ ));
+ }
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Cannot find attributes in post data'
+ ));
+ }
+ break;
+ }
+ break;
case "get":
switch ($category) {
case "domain":
switch ($object) {
case "all":
- $domains = mailbox_get_domains();
+ $domains = mailbox('get', 'domains');
if (!empty($domains)) {
foreach ($domains as $domain) {
- if ($details = mailbox_get_domain_details($domain)) {
+ if ($details = mailbox('get', 'domain_details', $domain)) {
$data[] = $details;
}
else {
@@ -53,7 +90,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
break;
default:
- $data = mailbox_get_domain_details($object);
+ $data = mailbox('get', 'domain_details', $object);
if (!isset($data) || empty($data)) {
echo '{}';
}
@@ -110,18 +147,27 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
echo '{}';
}
break;
+ case "rspamd-history":
+ $logs = get_logs('rspamd-history');
+ if (isset($logs) && !empty($logs)) {
+ echo json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
+ }
+ else {
+ echo '{}';
+ }
+ break;
}
break;
case "mailbox":
switch ($object) {
case "all":
- $domains = mailbox_get_domains();
+ $domains = mailbox('get', 'domains');
if (!empty($domains)) {
foreach ($domains as $domain) {
- $mailboxes = mailbox_get_mailboxes($domain);
+ $mailboxes = mailbox('get', 'mailboxes', $domain);
if (!empty($mailboxes)) {
foreach ($mailboxes as $mailbox) {
- if ($details = mailbox_get_mailbox_details($mailbox)) {
+ if ($details = mailbox('get', 'mailbox_details', $mailbox)) {
$data[] = $details;
}
else {
@@ -143,7 +189,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
break;
default:
- $data = mailbox_get_mailbox_details($object);
+ $data = mailbox('get', 'mailbox_details', $object);
if (!isset($data) || empty($data)) {
echo '{}';
}
@@ -153,10 +199,75 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
break;
}
break;
- case "syncjob":
+ case "syncjobs":
+ switch ($object) {
+ default:
+ $data = mailbox('get', 'syncjobs', $object);
+ if (!isset($data) || empty($data)) {
+ echo '{}';
+ }
+ else {
+ echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
+ }
+ break;
+ }
+ break;
+ case "policy_wl_mailbox":
+ switch ($object) {
+ default:
+ $data = policy('get', 'mailbox', $object)['whitelist'];
+ if (!isset($data) || empty($data)) {
+ echo '{}';
+ }
+ else {
+ echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
+ }
+ break;
+ }
+ break;
+ case "policy_bl_mailbox":
+ switch ($object) {
+ default:
+ $data = policy('get', 'mailbox', $object)['blacklist'];
+ if (!isset($data) || empty($data)) {
+ echo '{}';
+ }
+ else {
+ echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
+ }
+ break;
+ }
+ break;
+ case "policy_wl_domain":
+ switch ($object) {
+ default:
+ $data = policy('get', 'domain', $object)['whitelist'];
+ if (!isset($data) || empty($data)) {
+ echo '{}';
+ }
+ else {
+ echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
+ }
+ break;
+ }
+ break;
+ case "policy_bl_domain":
switch ($object) {
default:
- $data = get_syncjobs($object);
+ $data = policy('get', 'domain', $object)['blacklist'];
+ if (!isset($data) || empty($data)) {
+ echo '{}';
+ }
+ else {
+ echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
+ }
+ break;
+ }
+ break;
+ case "time_limited_aliases":
+ switch ($object) {
+ default:
+ $data = mailbox('get', 'time_limited_aliases', $object);
if (!isset($data) || empty($data)) {
echo '{}';
}
@@ -169,13 +280,13 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
case "resource":
switch ($object) {
case "all":
- $domains = mailbox_get_domains();
+ $domains = mailbox('get', 'domains');
if (!empty($domains)) {
foreach ($domains as $domain) {
- $resources = mailbox_get_resources($domain);
+ $resources = mailbox('get', 'resources', $domain);
if (!empty($resources)) {
foreach ($resources as $resource) {
- if ($details = mailbox_get_resource_details($resource)) {
+ if ($details = mailbox('get', 'resource_details', $resource)) {
$data[] = $details;
}
else {
@@ -196,7 +307,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
}
break;
default:
- $data = mailbox_get_resource_details($object);
+ $data = mailbox('get', 'resource_details', $object);
if (!isset($data) || empty($data)) {
echo '{}';
}
@@ -241,13 +352,13 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
case "alias-domain":
switch ($object) {
case "all":
- $domains = mailbox_get_domains();
+ $domains = mailbox('get', 'domains');
if (!empty($domains)) {
foreach ($domains as $domain) {
- $alias_domains = mailbox_get_alias_domains($domain);
+ $alias_domains = mailbox('get', 'alias_domains', $domain);
if (!empty($alias_domains)) {
foreach ($alias_domains as $alias_domain) {
- if ($details = mailbox_get_alias_domain_details($alias_domain)) {
+ if ($details = mailbox('get', 'alias_domain_details', $alias_domain)) {
$data[] = $details;
}
else {
@@ -268,7 +379,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
}
break;
default:
- $data = mailbox_get_alias_domains($object);
+ $data = mailbox('get', 'alias_domains', $object);
if (!isset($data) || empty($data)) {
echo '{}';
}
@@ -281,13 +392,13 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
case "alias":
switch ($object) {
case "all":
- $domains = array_merge(mailbox_get_domains(), mailbox_get_alias_domains());
+ $domains = array_merge(mailbox('get', 'domains'),mailbox('get', 'alias_domains'));
if (!empty($domains)) {
foreach ($domains as $domain) {
- $aliases = mailbox_get_aliases($domain);
+ $aliases = mailbox('get', 'aliases', $domain);
if (!empty($aliases)) {
foreach ($aliases as $alias) {
- if ($details = mailbox_get_alias_details($alias)) {
+ if ($details = mailbox('get', 'alias_details', $alias)) {
$data[] = $details;
}
else {
@@ -309,7 +420,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
break;
default:
- $data = mailbox_get_alias_details($object);
+ $data = mailbox('get', 'alias_details', $object);
if (!isset($data) || empty($data)) {
echo '{}';
}
@@ -389,7 +500,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
if (isset($_POST['items'])) {
$items = (array)json_decode($_POST['items'], true);
if (is_array($items)) {
- if (mailbox_delete_alias(array('address' => $items)) === false) {
+ if (mailbox('delete', 'alias', array('address' => $items)) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -426,6 +537,47 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
));
}
break;
+ case "syncjob":
+ if (isset($_POST['items'])) {
+ $items = (array)json_decode($_POST['items'], true);
+ if (is_array($items)) {
+ if (mailbox('delete', 'syncjob', array('id' => $items)) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Deletion of items/s failed'
+ ));
+ }
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Cannot find id array in post data'
+ ));
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Cannot find items in post data'
+ ));
+ }
+ break;
case "fwdhost":
if (isset($_POST['items'])) {
$items = (array)json_decode($_POST['items'], true);
@@ -512,7 +664,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
if (isset($_POST['items'])) {
$items = (array)json_decode($_POST['items'], true);
if (is_array($items)) {
- if (mailbox_delete_domain(array('domain' => $items)) === false) {
+ if (mailbox('delete', 'domain', array('domain' => $items)) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -553,7 +705,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
if (isset($_POST['items'])) {
$items = (array)json_decode($_POST['items'], true);
if (is_array($items)) {
- if (mailbox_delete_alias_domain(array('alias_domain' => $items)) === false) {
+ if (mailbox('delete', 'alias_domain', array('alias_domain' => $items)) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -594,7 +746,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
if (isset($_POST['items'])) {
$items = (array)json_decode($_POST['items'], true);
if (is_array($items)) {
- if (mailbox_delete_mailbox(array('username' => $items)) === false) {
+ if (mailbox('delete', 'mailbox', array('username' => $items)) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -635,7 +787,130 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
if (isset($_POST['items'])) {
$items = (array)json_decode($_POST['items'], true);
if (is_array($items)) {
- if (mailbox_delete_resource(array('name' => $items)) === false) {
+ if (mailbox('delete', 'resource', array('name' => $items)) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Task failed'
+ ));
+ }
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Cannot find name array in post data'
+ ));
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Cannot find items in post data'
+ ));
+ }
+ break;
+ case "policy_mailbox":
+ if (isset($_POST['items'])) {
+ $items = (array)json_decode($_POST['items'], true);
+ if (is_array($items)) {
+ if (policy('delete', 'mailbox', array('prefid' => $items)) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Task failed'
+ ));
+ }
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Cannot find name array in post data'
+ ));
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Cannot find items in post data'
+ ));
+ }
+ break;
+ case "time_limited_alias":
+ if (isset($_POST['items'])) {
+ $items = (array)json_decode($_POST['items'], true);
+ if (is_array($items)) {
+ if (mailbox('delete', 'time_limited_alias', array('address' => $items)) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Task failed'
+ ));
+ }
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Cannot find name array in post data'
+ ));
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Cannot find items in post data'
+ ));
+ }
+ break;
+ case "eas_cache":
+ if (isset($_POST['items'])) {
+ $items = (array)json_decode($_POST['items'], true);
+ if (is_array($items)) {
+ if (mailbox('delete', 'eas_cache', array('username' => $items)) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -682,7 +957,139 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
$attr = (array)json_decode($_POST['attr'], true);
$postarray = array_merge(array('address' => $items), $attr);
if (is_array($postarray['address'])) {
- if (mailbox_edit_alias($postarray) === false) {
+ if (mailbox('edit', 'alias', $postarray) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Edit failed'
+ ));
+ }
+ exit();
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ break;
+ case "delimiter_action":
+ if (isset($_POST['items']) && isset($_POST['attr'])) {
+ $items = (array)json_decode($_POST['items'], true);
+ $attr = (array)json_decode($_POST['attr'], true);
+ $postarray = array_merge(array('username' => $items), $attr);
+ if (is_array($postarray['username'])) {
+ if (mailbox('edit', 'delimiter_action', $postarray) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Edit failed'
+ ));
+ }
+ exit();
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ break;
+ case "tls_policy":
+ if (isset($_POST['items']) && isset($_POST['attr'])) {
+ $items = (array)json_decode($_POST['items'], true);
+ $attr = (array)json_decode($_POST['attr'], true);
+ $postarray = array_merge(array('username' => $items), $attr);
+ if (is_array($postarray['username'])) {
+ if (mailbox('edit', 'tls_policy', $postarray) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Edit failed'
+ ));
+ }
+ exit();
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ break;
+ case "time_limited_alias":
+ if (isset($_POST['items']) && isset($_POST['attr'])) {
+ $items = (array)json_decode($_POST['items'], true);
+ $attr = (array)json_decode($_POST['attr'], true);
+ $postarray = array_merge(array('address' => $items), $attr);
+ if (is_array($postarray['address'])) {
+ if (mailbox('edit', 'time_limited_alias', $postarray) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -726,7 +1133,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
$attr = (array)json_decode($_POST['attr'], true);
$postarray = array_merge(array('username' => $items), $attr);
if (is_array($postarray['username'])) {
- if (mailbox_edit_mailbox($postarray) === false) {
+ if (mailbox('edit', 'mailbox', $postarray) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -770,7 +1177,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
$attr = (array)json_decode($_POST['attr'], true);
$postarray = array_merge(array('id' => $items), $attr);
if (is_array($postarray['id'])) {
- if (edit_syncjob($postarray) === false) {
+ if (mailbox('edit', 'syncjob', $postarray) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -814,7 +1221,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
$attr = (array)json_decode($_POST['attr'], true);
$postarray = array_merge(array('name' => $items), $attr);
if (is_array($postarray['name'])) {
- if (mailbox_edit_resource($postarray) === false) {
+ if (mailbox('edit', 'resource', $postarray) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -858,7 +1265,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
$attr = (array)json_decode($_POST['attr'], true);
$postarray = array_merge(array('domain' => $items), $attr);
if (is_array($postarray['domain'])) {
- if (mailbox_edit_domain($postarray) === false) {
+ if (mailbox('edit', 'domain', $postarray) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -902,7 +1309,51 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
$attr = (array)json_decode($_POST['attr'], true);
$postarray = array_merge(array('alias_domain' => $items), $attr);
if (is_array($postarray['alias_domain'])) {
- if (mailbox_edit_alias_domain($postarray) === false) {
+ if (mailbox('edit', 'alias_domain', $postarray) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Edit failed'
+ ));
+ }
+ exit();
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ break;
+ case "spam_score":
+ if (isset($_POST['items']) && isset($_POST['attr'])) {
+ $items = (array)json_decode($_POST['items'], true);
+ $attr = (array)json_decode($_POST['attr'], true);
+ $postarray = array_merge(array('username' => $items), $attr);
+ if (is_array($postarray['username'])) {
+ if (mailbox('edit', 'spam_score', $postarray) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
diff --git a/data/web/lang/lang.de.php b/data/web/lang/lang.de.php
index b5d5470e..1aee2c5f 100644
--- a/data/web/lang/lang.de.php
+++ b/data/web/lang/lang.de.php
@@ -10,7 +10,7 @@ $lang['footer']['restart_now'] = 'Jetzt neustarten';
$lang['footer']['restart_sogo_info'] = 'Einige Änderungen an Domains benötigen einen Neustart SOGos. Hier können Sie SOGo neustarten.<br><br><b>Wichtig:</b> Ein korrekter Neustart SOGos kann eine Weile in Anspruch nehmen, bitte warten Sie, bis der Prozess vollständig beendet wurde.';
$lang['footer']['confirm_delete'] = 'Löschen bestätigen';
-$lang['footer']['delete_these_items'] = 'Sind Sie sicher, dass die folgenden Elemente entfernt werden sollen?';
+$lang['footer']['delete_these_items'] = 'Sind Sie sicher, dass die Änderungen an folgenden Elementen durchgeführt werden sollen?';
$lang['footer']['delete_now'] = 'Jetzt löschen';
$lang['footer']['cancel'] = 'Abbrechen';
@@ -28,6 +28,7 @@ $lang['danger']['domain_invalid'] = 'Domainname ist ungültig';
$lang['danger']['mailbox_quota_exceeds_domain_quota'] = 'Maximale Größe für Mailboxen überschreitet das Domain Speicherlimit';
$lang['danger']['object_is_not_numeric'] = 'Wert %s ist nicht numerisch';
$lang['success']['domain_added'] = 'Domain %s wurde angelegt';
+$lang['success']['items_deleted'] = "Objekt(e) %s wurde(n) erfolgreich entfernt";
$lang['danger']['alias_empty'] = 'Alias-Adresse darf nicht leer sein';
$lang['danger']['goto_empty'] = 'Ziel-Adresse darf nicht leer sein';
$lang['danger']['policy_list_from_exists'] = 'Ein Eintrag mit diesem Wert existiert bereits';
diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php
index 2763e0f9..5c2936db 100644
--- a/data/web/lang/lang.en.php
+++ b/data/web/lang/lang.en.php
@@ -10,7 +10,7 @@ $lang['footer']['restart_now'] = 'Restart now';
$lang['footer']['restart_sogo_info'] = 'Some tasks, e.g. adding a domain, require you to restart SOGo to catch changes made in the mailcow UI.<br><br><b>Important:</b> A graceful restart may take a while to complete, please wait for it to finish.';
$lang['footer']['confirm_delete'] = 'Confirm deletion';
-$lang['footer']['delete_these_items'] = 'Are you sure you want to delete the following items?';
+$lang['footer']['delete_these_items'] = 'Please confirm your changes to the following items:';
$lang['footer']['delete_now'] = 'Delete now';
$lang['footer']['cancel'] = 'Cancel';
@@ -28,6 +28,7 @@ $lang['danger']['domain_invalid'] = "Domain name is invalid";
$lang['danger']['mailbox_quota_exceeds_domain_quota'] = "Max. quota exceeds domain quota limit";
$lang['danger']['object_is_not_numeric'] = "Value %s is not numeric";
$lang['success']['domain_added'] = "Added domain %s";
+$lang['success']['items_deleted'] = "Item %s successfully deleted";
$lang['danger']['alias_empty'] = "Alias address must not be empty";
$lang['danger']['last_key'] = 'Last key cannot be deleted';
$lang['danger']['goto_empty'] = "Goto address must not be empty";
diff --git a/data/web/user.php b/data/web/user.php
index 7a3d6f87..4fa4abc8 100644
--- a/data/web/user.php
+++ b/data/web/user.php
@@ -27,7 +27,7 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'doma
<div class="col-sm-9 col-xs-7">
<p id="tfa_pretty"><?=$tfa_data['pretty'];?></p>
<div id="tfa_additional">
- <?php if($tfa_data['additional']):
+ <?php if (!empty($tfa_data['additional'])):
foreach ($tfa_data['additional'] as $key_info): ?>
<form style="display:inline;" method="post">
<input type="hidden" name="unset_tfa_key" value="<?=$key_info['id'];?>" />
@@ -63,8 +63,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
require_once("inc/header.inc.php");
$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
$username = $_SESSION['mailcow_cc_username'];
- $get_tls_policy = get_tls_policy($_SESSION['mailcow_cc_username']);
- $mailboxdata = mailbox_get_mailbox_details($username);
+ $mailboxdata = mailbox('get', 'mailbox_details', $username);
?>
<div class="container">
<h3><?=$lang['user']['user_settings'];?></h3>
@@ -124,31 +123,64 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
</div>
<hr>
<?php // Show tagging options ?>
- <form class="form-horizontal" role="form" method="post">
- <?php $get_tagging_options = get_delimiter_action();?>
+ <?php $get_tagging_options = mailbox('get', 'delimiter_action', $username);?>
<div class="row">
<div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['tag_handling'];?>:</div>
<div class="col-md-9 col-xs-7">
- <input type="hidden" name="edit_delimiter_action" value="1">
- <select name="tagged_mail_handler" class="selectpicker" onchange="this.form.submit()">
- <option value="subfolder" <?=($get_tagging_options == "subfolder") ? 'selected' : null; ?>><?=$lang['user']['tag_in_subfolder'];?></option>
- <option value="subject" <?=($get_tagging_options == "subject") ? 'selected' : null; ?>><?=$lang['user']['tag_in_subject'];?></option>
- </select>
+ <div class="btn-group">
+
+ <button type="button" class="btn btn-sm btn-default <?=($get_tagging_options == "subfolder") ? 'active' : null; ?>"
+ id="edit_selected"
+ data-item="<?= $username; ?>"
+ data-id="delimiter_action"
+ data-api-url='edit/delimiter_action'
+ data-api-attr='{"tagged_mail_handler":"subfolder"}'><?=$lang['user']['tag_in_subfolder'];?></button>
+
+ <button type="button" class="btn btn-sm btn-default <?=($get_tagging_options == "subject") ? 'active' : null; ?>"
+ id="edit_selected"
+ data-item="<?= $username; ?>"
+ data-id="delimiter_action"
+ data-api-url='edit/delimiter_action'
+ data-api-attr='{"tagged_mail_handler":"subject"}'><?=$lang['user']['tag_in_subject'];?></button>
+
+ </div>
<p class="help-block"><?=$lang['user']['tag_help_explain'];?></p>
<p class="help-block"><?=$lang['user']['tag_help_example'];?></p>
</div>
</div>
- </form>
+ <?php // Show TLS policy options ?>
+ <?php $get_tls_policy = mailbox('get', 'tls_policy', $username); ?>
+ <div class="row">
+ <div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['tls_policy'];?>:</div>
+ <div class="col-md-9 col-xs-7">
+ <div class="btn-group">
+
+ <button type="button" class="btn btn-sm btn-default <?=($get_tls_policy['tls_enforce_in'] == "1") ? "active" : null;?>"
+ id="edit_selected"
+ data-item="<?= $username; ?>"
+ data-id="tls_policy"
+ data-api-url='edit/tls_policy'
+ data-api-attr='{"tls_enforce_in":<?=($get_tls_policy['tls_enforce_in'] == "1") ? "0" : "1";?>}'><?=$lang['user']['tls_enforce_in'];?></button>
+
+ <button type="button" class="btn btn-sm btn-default <?=($get_tls_policy['tls_enforce_out'] == "1") ? "active" : null;?>"
+ id="edit_selected"
+ data-item="<?= $username; ?>"
+ data-id="tls_policy"
+ data-api-url='edit/tls_policy'
+ data-api-attr='{"tls_enforce_out":<?=($get_tls_policy['tls_enforce_out'] == "1") ? "0" : "1";?>}'><?=$lang['user']['tls_enforce_out'];?></button>
+
+ </div>
+ <p class="help-block"><?=$lang['user']['tls_policy_warning'];?></p>
+ </div>
+ </div>
<?php // Rest EAS devices ?>
- <form class="form-horizontal" role="form" method="post">
<div class="row">
<div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['eas_reset'];?>:</div>
<div class="col-md-9 col-xs-7">
- <button type="submit" name="mailbox_reset_eas" id="mailbox_reset_eas" value="1" class="btn btn-xs btn-default"><?=$lang['user']['eas_reset_now'];?></button>
+ <button class="btn btn-xs btn-default" id="delete_selected" data-text="<?=$lang['user']['eas_reset'];?>?" data-item="<?= $username; ?>" data-id="eas_cache" data-api-url='delete/eas_cache' href="#"><?=$lang['user']['eas_reset_now'];?></button>
<p class="help-block"><?=$lang['user']['eas_reset_help'];?></p>
</div>
</div>
- </form>
</div>
</div>
@@ -156,92 +188,50 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
<ul class="nav nav-pills nav-justified" role="tablist">
<li role="presentation" class="active"><a href="#SpamAliases" aria-controls="SpamAliases" role="tab" data-toggle="tab"><?=$lang['user']['spam_aliases'];?></a></li>
<li role="presentation"><a href="#Spamfilter" aria-controls="Spamfilter" role="tab" data-toggle="tab"><?=$lang['user']['spamfilter'];?></a></li>
- <li role="presentation"><a href="#TLSPolicy" aria-controls="TLSPolicy" role="tab" data-toggle="tab"><?=$lang['user']['tls_policy'];?></a></li>
<li role="presentation"><a href="#Syncjobs" aria-controls="Syncjobs" role="tab" data-toggle="tab"><?=$lang['user']['sync_jobs'];?></a></li>
</ul>
<hr>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="SpamAliases">
- <div class="row">
- <div class="col-xs-6">
- <p><b><?=$lang['user']['alias'];?></b></p>
- </div>
- <div class="col-xs-2">
- <p><b><?=$lang['user']['alias_valid_until'];?></b></p>
- </div>
- <div class="col-xs-2">
- <p><b><?=$lang['user']['action'];?></b></p>
- </div>
- </div>
- <?php
- $get_time_limited_aliases = get_time_limited_aliases($username);
- if (!empty($get_time_limited_aliases)):
- foreach ($get_time_limited_aliases as $row):
- ?>
- <div class="row">
- <div class="col-xs-6">
- <p><?=htmlspecialchars($row['address']);?></p>
- </div>
- <div class="col-xs-2">
- <p><?=htmlspecialchars(date($lang['user']['alias_full_date'], $row['validity']));?></p>
- </div>
- <div class="col-xs-1">
- <form class="form-inline" role="form" method="post">
- <a class="text-danger" href="#" onclick="$(this).closest('form').submit()"><span class="glyphicon glyphicon-remove"></span></a>
- <input type="hidden" name="set_time_limited_aliases" value="delete">
- <input type="hidden" name="item" value="<?=htmlspecialchars($row['address']);?>">
- </form>
+ <div class="row">
+ <div class="col-md-6 col-sm-12 col-xs-12">
+ <div class="table-responsive">
+ <table class="table table-striped" id="tla_table"></table>
+ </div>
</div>
- <div class="col-xs-1">
- <form class="form-inline" role="form" method="post">
- <a href="#" onclick="$(this).closest('form').submit()"><span class="glyphicon glyphicon-time"></span> + 1h</a>
- <input type="hidden" name="set_time_limited_aliases" value="extend">
- <input type="hidden" name="item" value="<?=htmlspecialchars($row['address']);?>">
- </form>
+ </div>
+ <div class="mass-actions-user">
+ <div class="btn-group">
+ <div class="btn-group">
+ <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="tla" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+ <a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
+ <ul class="dropdown-menu">
+ <li><a id="edit_selected" data-id="tla" data-api-url='edit/time_limited_alias' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-time"></span> + 1h</a></li>
+ <li role="separator" class="divider"></li>
+ <li><a id="delete_selected" data-id="tla" data-api-url='delete/time_limited_alias' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+ </ul>
+ </div>
+ <div class="btn-group">
+ <a class="btn btn-sm btn-success dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['user']['alias_create_random'];?> <span class="caret"></span></a>
+ <ul class="dropdown-menu">
+ <li><a id="add_item" data-api-url='add/time_limited_alias' data-api-attr='{"validity":"1"}' href="#">1 <?=$lang['user']['hour'];?></a></li>
+ <li><a id="add_item" data-api-url='add/time_limited_alias' data-api-attr='{"validity":"6"}' href="#">6 <?=$lang['user']['hours'];?></a></li>
+ <li><a id="add_item" data-api-url='add/time_limited_alias' data-api-attr='{"validity":"24"}' href="#">1 <?=$lang['user']['day'];?></a></li>
+ <li><a id="add_item" data-api-url='add/time_limited_alias' data-api-attr='{"validity":"168"}' href="#">1 <?=$lang['user']['week'];?></a></li>
+ <li><a id="add_item" data-api-url='add/time_limited_alias' data-api-attr='{"validity":"672"}' href="#">4 <?=$lang['user']['weeks'];?></a></li>
+ </ul>
+ </div>
</div>
</div>
- <?php
- endforeach;
- else:
- ?>
- <div class="col-xs-12">
- <center><i><?=$lang['user']['no_record'];?></i></center>
- </div>
- <?php
- endif;
- ?>
- <form class="form-horizontal" role="form" method="post">
- <div class="form-group">
- <div class="col-sm-9">
- <select id="validity" name="validity" title="<?=$lang['user']['alias_select_validity'];?>">
- <option value="1">1 <?=$lang['user']['hour'];?></option>
- <option value="6">6 <?=$lang['user']['hours'];?></option>
- <option value="24">1 <?=$lang['user']['day'];?></option>
- <option value="168">1 <?=$lang['user']['week'];?></option>
- <option value="672">4 <?=$lang['user']['weeks'];?></option>
- </select>
- <button type="submit" name="set_time_limited_aliases" id="generate_tla" value="generate" class="btn btn-success"><?=$lang['user']['alias_create_random'];?></button>
- </div>
- </div>
- <div class="form-group">
- <div class="col-sm-12">
- <button type="submit" name="set_time_limited_aliases" value="deleteall" class="btn-danger btn btn-sm">
- <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> <?=$lang['user']['alias_remove_all'];?>
- </button>
- <button type="submit" name="set_time_limited_aliases" value="extendall" class="btn-default btn btn-sm">
- <span class="glyphicon glyphicon-time" aria-hidden="true"></span> <?=$lang['user']['alias_extend_all'];?>
- </button>
- </div>
- </div>
- </form>
</div>
+
<div role="tabpanel" class="tab-pane" id="Spamfilter">
<h4><?=$lang['user']['spamfilter_behavior'];?></h4>
- <form class="form-horizontal" role="form" method="post">
+ <form class="form-horizontal" role="form" data-id="spam_score" method="post">
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
- <input name="score" id="score" type="text"
+ <input name="spam_score" id="spam_score" type="text"
data-provide="slider"
data-slider-min="1"
data-slider-max="30"
@@ -249,7 +239,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
data-slider-range="true"
data-slider-tooltip='always'
data-slider-id="slider1"
- data-slider-value="[<?=get_spam_score($username);?>]"
+ data-slider-value="[<?=mailbox('get', 'spam_score', $username);?>]"
data-slider-step="1" />
<br /><br />
<ul>
@@ -263,149 +253,67 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
- <button type="submit" id="edit_spam_score" name="edit_spam_score" class="btn btn-success"><?=$lang['user']['save_changes'];?></button>
+ <button type="button" class="btn btn-sm btn-success" id="edit_selected"
+ data-item="<?= $username; ?>"
+ data-id="spam_score"
+ data-api-url='edit/spam_score'
+ data-api-attr='{}'><?=$lang['user']['save_changes'];?></button>
</div>
</div>
</form>
<hr>
<div class="row">
<div class="col-sm-6">
- <h4><span class="glyphicon glyphicon-thumbs-up" aria-hidden="true"></span> <?=$lang['user']['spamfilter_wl'];?></h4>
- <p><?=$lang['user']['spamfilter_wl_desc'];?></p>
- <div class="row">
- <div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_rule'];?></b></div>
- <div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_action'];?></b></div>
- </div>
- <?php
- $get_policy_list = get_policy_list($username);
- if (empty($get_policy_list['whitelist'])):
- ?>
- <div class="row">
- <div class="col-sm-12"><i><?=$lang['user']['spamfilter_table_empty'];?></i></div>
- </div>
- <?php
- else:
- foreach($get_policy_list['whitelist'] as $wl):
- ?>
- <div class="row striped">
- <form class="form-inline" method="post">
- <div class="col-xs-6"><code><?=$wl['value'];?></code></div>
- <div class="col-xs-6">
- <input type="hidden" name="delete_prefid" value="<?=$wl['prefid'];?>">
- <?php
- if (filter_var($wl['object'], FILTER_VALIDATE_EMAIL)):
- ?>
- <input type="hidden" name="delete_policy_list_item">
- <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a>
- <?php
- else:
- ?>
- <span style="cursor:not-allowed"><?=$lang['user']['spamfilter_table_domain_policy'];?></span>
- <?php
- endif;
- ?>
- </div>
- </form>
+ <h4><?=$lang['user']['spamfilter_wl'];?></h4>
+ <p><?=$lang['user']['spamfilter_wl_desc'];?></p>
+ <div class="table-responsive">
+ <table class="table table-striped table-condensed" id="wl_policy_mailbox_table"></table>
+ </div>
+ <div class="mass-actions-user">
+ <div class="btn-group">
+ <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="policy_wl_mailbox" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+ <a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_wl_mailbox" data-api-url='delete/policy_mailbox' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+ </ul>
</div>
- <?php
- endforeach;
- endif;
- ?>
- <hr style="margin:5px 0px 7px 0px">
- <div class="row">
- <form class="form-inline" method="post">
- <div class="col-xs-6">
- <input type="text" class="form-control input-sm" name="object_from" id="object_from" placeholder="*@example.org" required>
- <input type="hidden" name="object_list" value="wl">
- </div>
- <div class="col-xs-6">
- <button type="submit" id="add_policy_list_item" name="add_policy_list_item" class="btn btn-xs btn-default"><?=$lang['user']['spamfilter_table_add'];?></button>
- </div>
- </form>
- </div>
- </div>
+ </div>
+ <form class="form-inline" method="post">
+ <div class="input-group">
+ <input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
+ <input type="hidden" name="username" value="<?= $username ;?>">
+ <input type="hidden" name="object_list" value="wl">
+ <span class="input-group-btn">
+ <button type="submit" id="add_policy_list_item" name="add_policy_list_item" class="btn btn-default"><?=$lang['user']['spamfilter_table_add'];?></button>
+ </span>
+ </div>
+ </form>
+ </div>
<div class="col-sm-6">
- <h4><span class="glyphicon glyphicon-thumbs-down" aria-hidden="true"></span> <?=$lang['user']['spamfilter_bl'];?></h4>
- <p><?=$lang['user']['spamfilter_bl_desc'];?></p>
- <div class="row">
- <div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_rule'];?></b></div>
- <div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_action'];?></b></div>
- </div>
- <?php
- if (empty($get_policy_list['blacklist'])):
- ?>
- <div class="row">
- <div class="col-sm-12"><i><?=$lang['user']['spamfilter_table_empty'];?></i></div>
- </div>
- <?php
- else:
- foreach($get_policy_list['blacklist'] as $bl):
- ?>
- <div class="row striped">
- <form class="form-inline" method="post">
- <div class="col-xs-6"><code><?=$bl['value'];?></code></div>
- <div class="col-xs-6">
- <?php
- if (filter_var($bl['object'], FILTER_VALIDATE_EMAIL)):
- ?>
- <input type="hidden" name="delete_prefid" value="<?=$bl['prefid'];?>">
- <input type="hidden" name="delete_policy_list_item">
- <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a>
- <?php
- else:
- ?>
- <span style="cursor:not-allowed"><?=$lang['user']['spamfilter_table_domain_policy'];?></span>
- <?php
- endif;
- ?>
- </div>
- </form>
+ <h4><?=$lang['user']['spamfilter_bl'];?></h4>
+ <p><?=$lang['user']['spamfilter_bl_desc'];?></p>
+ <div class="table-responsive">
+ <table class="table table-striped table-condensed" id="bl_policy_mailbox_table"></table>
+ </div>
+ <div class="mass-actions-user">
+ <div class="btn-group">
+ <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="policy_bl_mailbox" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+ <a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_bl_mailbox" data-api-url='delete/policy_mailbox' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+ </ul>
</div>
- <?php
- endforeach;
- endif;
- ?>
- <hr style="margin:5px 0px 7px 0px">
- <div class="row">
- <form class="form-inline" method="post">
- <div class="col-xs-6">
- <input type="text" class="form-control input-sm" name="object_from" id="object_from" placeholder="*@example.org" required>
- <input type="hidden" name="object_list" value="bl">
- </div>
- <div class="col-xs-6">
- <button type="submit" id="add_policy_list_item" name="add_policy_list_item" class="btn btn-xs btn-default"><?=$lang['user']['spamfilter_table_add'];?></button>
- </div>
- </form>
- </div>
- </div>
- </div>
- </div>
- <div role="tabpanel" class="tab-pane" id="TLSPolicy">
- <form class="form-horizontal" role="form" method="post">
- <input type="hidden" value="0" name="tls_in">
- <input type="hidden" value="0" name="tls_out">
- <p class="help-block"><?=$lang['user']['tls_policy_warning'];?></p>
- <div class="form-group">
- <div class="col-sm-6">
- <div class="checkbox">
- <h4><span class="glyphicon glyphicon-download" aria-hidden="true"></span> <?=$lang['user']['tls_enforce_in'];?></h4>
- <input type="checkbox" value="1" id="tls_in" name="tls_in" <?=($get_tls_policy['tls_enforce_in'] == "1") ? "checked" : null;?> data-on-text="<?=$lang['user']['on'];?>" data-off-text="<?=$lang['user']['off'];?>">
- </div>
- </div>
- <div class="col-sm-6">
- <div class="checkbox">
- <h4><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> <?=$lang['user']['tls_enforce_out'];?></h4>
- <input type="checkbox" value="1" id="tls_out" name="tls_out" <?=($get_tls_policy['tls_enforce_out'] == "1") ? "checked" : null;?> data-on-text="<?=$lang['user']['on'];?>" data-off-text="<?=$lang['user']['off'];?>">
- </div>
- </div>
- </div>
- <div class="form-group">
- <div class="col-sm-12">
- <button type="submit" id="edit_tls_policy" name="edit_tls_policy" class="btn btn-success"><?=$lang['user']['save_changes'];?></button>
- </div>
- </div>
- </form>
- </div>
+ </div>
+ <form class="form-inline" method="post">
+ <div class="input-group">
+ <input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
+ <input type="hidden" name="username" value="<?= $username ;?>">
+ <input type="hidden" name="object_list" value="bl">
+ <span class="input-group-btn">
+ <button type="submit" id="add_policy_list_item" name="add_policy_list_item" class="btn btn-default"><?=$lang['user']['spamfilter_table_add'];?></button>
+ </span>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+
<div role="tabpanel" class="tab-pane" id="Syncjobs">
<div class="table-responsive">
<table class="table table-striped" id="sync_job_table"></table>