Page MenuHomeWMGMC Issues

No OneTemporary

diff --git a/build-nginx.sh b/build-nginx.sh
index 7e6b3cfb..694c9c2b 100755
--- a/build-nginx.sh
+++ b/build-nginx.sh
@@ -1,40 +1,40 @@
#!/bin/bash
. mailcow.conf
./build-network.sh
NAME="nginx-mailcow"
echo "Stopping and removing containers with name tag ${NAME}..."
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
if [[ ! -z "$(docker images -q nginx:${NGINXVERS})" ]]; then
read -r -p "Found image locally. Delete local image and repull? [y/N] " response
response=${response,,} # tolower
if [[ $response =~ ^(yes|y)$ ]]; then
docker rmi nginx:${NGINXVERS}
fi
fi
sed -i "s#database_name.*#database_name = \"${DBNAME}\";#" data/web/inc/vars.inc.php
sed -i "s#database_user.*#database_user = \"${DBUSER}\";#" data/web/inc/vars.inc.php
sed -i "s#database_pass.*#database_pass = \"${DBPASS}\";#" data/web/inc/vars.inc.php
-sed -i "s#database_user.*#database_user = \"${DBUSER}\";#" data/conf/nginx/vars.inc.php
docker run \
-p 443:443 \
--name ${NAME} \
-v ${PWD}/data/web:/web:ro \
+ -v ${PWD}/data/conf/rspamd/dynmaps:/dynmaps:ro \
-v ${PWD}/data/assets/ssl/:/etc/ssl/mail/:ro \
-v ${PWD}/data/conf/nginx/:/etc/nginx/conf.d/:ro \
--network=${DOCKER_NETWORK} \
--network-alias nginx \
-h nginx \
-d nginx:${NGINXVERS}
echo "Installaing SOGo web resource files..."
docker exec -it ${NAME} /bin/bash -c 'apt-key adv --keyserver keys.gnupg.net --recv-key 0x810273C4 && apt-get update && apt-get -y --force-yes install apt-transport-https'
docker exec -it ${NAME} /bin/bash -c 'echo "deb http://packages.inverse.ca/SOGo/nightly/3/debian/ jessie jessie" > /etc/apt/sources.list.d/sogo.list && apt-get update && apt-get -y --force-yes install sogo'
diff --git a/build-php-fpm.sh b/build-php-fpm.sh
index f4a12ac0..c8ac9376 100755
--- a/build-php-fpm.sh
+++ b/build-php-fpm.sh
@@ -1,32 +1,33 @@
#!/bin/bash
. mailcow.conf
./build-network.sh
NAME="php-fpm-mailcow"
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
if [[ ! -z "$(docker images -q php:${PHPVERS})" ]]; then
read -r -p "Found image locally. Delete local image and repull? [y/N] " response
response=${response,,}
if [[ $response =~ ^(yes|y)$ ]]; then
docker rmi php:${PHPVERS}
fi
fi
docker run \
-v ${PWD}/data/web:/web:ro \
+ -v ${PWD}/data/conf/rspamd/dynmaps:/dynmaps:ro \
-v ${PWD}/data/dkim/:/shared/dkim/ \
-d --network=${DOCKER_NETWORK} \
--name ${NAME} --network-alias phpfpm -h phpfpm php:${PHPVERS}
echo "Installing intl and mysql pdo extension..."
docker exec ${NAME} /bin/bash -c "apt-get update && apt-get install -y zlib1g-dev libicu-dev g++ libidn11-dev dovecot-core"
docker exec ${NAME} docker-php-ext-configure intl pdo pdo_mysql
docker exec ${NAME} docker-php-ext-install intl pdo pdo_mysql
echo "Restarting container..."
docker restart ${NAME}
diff --git a/data/conf/nginx/dynmaps.conf b/data/conf/nginx/dynmaps.conf
new file mode 100644
index 00000000..8394870a
--- /dev/null
+++ b/data/conf/nginx/dynmaps.conf
@@ -0,0 +1,18 @@
+server {
+ listen 8081;
+ index index.php index.html;
+ server_name _;
+ error_log /var/log/nginx/error.log;
+ access_log /var/log/nginx/access.log;
+ root /dynmaps;
+
+ location ~ \.php$ {
+ try_files $uri =404;
+ fastcgi_split_path_info ^(.+\.php)(/.+)$;
+ fastcgi_pass phpfpm:9000;
+ fastcgi_index index.php;
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param PATH_INFO $fastcgi_path_info;
+ }
+}
diff --git a/data/conf/rspamd/dynmaps/settings.php b/data/conf/rspamd/dynmaps/settings.php
new file mode 100644
index 00000000..419c4b8d
--- /dev/null
+++ b/data/conf/rspamd/dynmaps/settings.php
@@ -0,0 +1,206 @@
+<?php
+ini_set('error_reporting', 0);
+/*
+The match section performs AND operation on different matches: for example, if you have from and rcpt in the same rule,
+then the rule matches only when from AND rcpt match. For similar matches, the OR rule applies: if you have multiple rcpt matches,
+then any of these will trigger the rule. If a rule is triggered then no more rules are matched.
+*/
+header('Content-Type: text/plain');
+require_once "vars.inc.php";
+$dsn = $database_type . ':host=' . $database_host . ';dbname=' . $database_name;
+$opt = [
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
+ PDO::ATTR_EMULATE_PREPARES => false,
+];
+$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
+?>
+settings {
+<?php
+$stmt = $pdo->query("SELECT DISTINCT `object` FROM `filterconf` WHERE `option` = 'highspamlevel' OR `option` = 'lowspamlevel'");
+$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+while ($row = array_shift($rows)) {
+ $username_sane = preg_replace("/[^a-zA-Z0-9]+/", "", $row['object']);
+?>
+ score_<?=$username_sane;?> {
+ priority = low;
+<?php
+ $stmt = $pdo->prepare("SELECT `option`, `value` FROM `filterconf`
+ WHERE (`option` = 'highspamlevel' OR `option` = 'lowspamlevel')
+ AND `object`= :object");
+ $stmt->execute(array(':object' => $row['object']));
+ $spamscore = $stmt->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP);
+
+ $stmt = $pdo->prepare("SELECT GROUP_CONCAT(REPLACE(`value`, '*', '.*') SEPARATOR '|') AS `value` FROM `filterconf`
+ WHERE `object`= :object
+ AND (`option` = 'blacklist_from' OR `option` = 'whitelist_from')");
+ $stmt->execute(array(':object' => $row['object']));
+ $grouped_lists = $stmt->fetchAll(PDO::FETCH_COLUMN);
+ $value_sane = preg_replace("/\.\./", ".", (preg_replace("/\*/", ".*", $grouped_lists[0])));
+?>
+ from = "/^((?!<?=$value_sane;?>).)*$/";
+ rcpt = "<?=$row['object'];?>";
+<?php
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` = :object_goto AND `address` NOT LIKE '@%' AND `address` != :object_address");
+ $stmt->execute(array(':object_goto' => $row['object'], ':object_address' => $row['object']));
+ $rows_aliases_1 = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row_aliases_1 = array_shift($rows_aliases_1)) {
+?>
+ rcpt = "<?=$row_aliases_1['address'];?>";
+<?php
+ }
+ $stmt = $pdo->prepare("SELECT CONCAT(`local_part`, '@', `alias_domain`.`alias_domain`) AS `aliases` FROM `mailbox`
+ LEFT OUTER JOIN `alias_domain` on `mailbox`.`domain` = `alias_domain`.`target_domain`
+ WHERE `mailbox`.`username` = :object");
+ $stmt->execute(array(':object' => $row['object']));
+ $rows_aliases_2 = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row_aliases_2 = array_shift($rows_aliases_2)) {
+?>
+ rcpt = "<?=$row_aliases_2['aliases'];?>";
+<?php
+ }
+?>
+ apply "default" {
+ actions {
+ reject = <?=$spamscore['highspamlevel'][0];?>;
+ greylist = <?=$spamscore['lowspamlevel'][0] - 1;?>;
+ "add header" = <?=$spamscore['lowspamlevel'][0];?>;
+ }
+ }
+<?php
+}
+
+/*
+// Start whitelist
+*/
+
+$stmt = $pdo->query("SELECT DISTINCT `object` FROM `filterconf` WHERE `option` = 'whitelist_from'");
+$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+while ($row = array_shift($rows)) {
+ $username_sane = preg_replace("/[^a-zA-Z0-9]+/", "", $row['object']);
+?>
+ whitelist_<?=$username_sane;?> {
+ priority = high;
+<?php
+ $stmt = $pdo->prepare("SELECT GROUP_CONCAT(REPLACE(`value`, '*', '.*') SEPARATOR '|') AS `value` FROM `filterconf`
+ WHERE `object`= :object
+ AND `option` = 'whitelist_from'");
+ $stmt->execute(array(':object' => $row['object']));
+ $grouped_lists = $stmt->fetchAll(PDO::FETCH_COLUMN);
+ $value_sane = preg_replace("/\.\./", ".", (preg_replace("/\*/", ".*", $grouped_lists[0])));
+?>
+ from = "/(<?=$value_sane;?>)/";
+<?php
+ if (!filter_var(trim($row['object']), FILTER_VALIDATE_EMAIL)) {
+?>
+ rcpt = "/.*@<?=$username_userpref['username'];?>/";
+<?php
+ $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain`
+ WHERE `target_domain` = :object");
+ $stmt->execute(array(':object' => $row['object']));
+ $rows_domain_aliases = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row_domain_aliases = array_shift($rows_domain_aliases)) {
+?>
+ rcpt = "<?=$row_domain_aliases['alias_domain'];?>";
+<?php
+ }
+ }
+ else {
+?>
+ rcpt = "<?=$row['object'];?>";
+<?php
+ }
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` = :object_goto AND `address` NOT LIKE '@%' AND `address` != :object_address");
+ $stmt->execute(array(':object_goto' => $row['object'], ':object_address' => $row['object']));
+ $rows_aliases_wl_1 = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row_aliases_wl_1 = array_shift($rows_aliases_wl_1)) {
+?>
+ rcpt = "<?=$row_aliases_wl_1['address'];?>";
+<?php
+ }
+ $stmt = $pdo->prepare("SELECT CONCAT(`local_part`, '@', `alias_domain`.`alias_domain`) AS `aliases` FROM `mailbox`
+ LEFT OUTER JOIN `alias_domain` on `mailbox`.`domain` = `alias_domain`.`target_domain`
+ WHERE `mailbox`.`username` = :object");
+ $stmt->execute(array(':object' => $row['object']));
+ $rows_aliases_wl_2 = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row_aliases_wl_2 = array_shift($rows_aliases_wl_2)) {
+?>
+ rcpt = "<?=$row_aliases_wl_2['aliases'];?>";
+<?php
+ }
+?>
+ apply "default" {
+ MAILCOW_MOO = -999.0;
+ }
+ }
+<?php
+}
+
+/*
+// Start blacklist
+*/
+
+$stmt = $pdo->query("SELECT DISTINCT `object` FROM `filterconf` WHERE `option` = 'blacklist_from'");
+$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+while ($row = array_shift($rows)) {
+ $username_sane = preg_replace("/[^a-zA-Z0-9]+/", "", $row['object']);
+?>
+ blacklist_<?=$username_sane;?> {
+ priority = medium;
+<?php
+ $stmt = $pdo->prepare("SELECT GROUP_CONCAT(REPLACE(`value`, '*', '.*') SEPARATOR '|') AS `value` FROM `filterconf`
+ WHERE `object`= :object
+ AND `option` = 'blacklist_from'");
+ $stmt->execute(array(':object' => $row['object']));
+ $grouped_lists = $stmt->fetchAll(PDO::FETCH_COLUMN);
+ $value_sane = preg_replace("/\.\./", ".", (preg_replace("/\*/", ".*", $grouped_lists[0])));
+?>
+ from = "/(<?=$value_sane;?>)/";
+<?php
+ if (!filter_var(trim($row['object']), FILTER_VALIDATE_EMAIL)) {
+?>
+ rcpt = "/.*@<?=$username_userpref['username'];?>/";
+<?php
+ $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain`
+ WHERE `target_domain` = :object");
+ $stmt->execute(array(':object' => $row['object']));
+ $rows_domain_aliases = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row_domain_aliases = array_shift($rows_domain_aliases)) {
+?>
+ rcpt = "<?=$row_domain_aliases['alias_domain'];?>";
+<?php
+ }
+ }
+ else {
+?>
+ rcpt = "<?=$row['object'];?>";
+<?php
+ }
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` = :object_goto AND `address` NOT LIKE '@%' AND `address` != :object_address");
+ $stmt->execute(array(':object_goto' => $row['object'], ':object_address' => $row['object']));
+ $rows_aliases_wl_1 = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row_aliases_wl_1 = array_shift($rows_aliases_wl_1)) {
+?>
+ rcpt = "<?=$row_aliases_wl_1['address'];?>";
+<?php
+ }
+ $stmt = $pdo->prepare("SELECT CONCAT(`local_part`, '@', `alias_domain`.`alias_domain`) AS `aliases` FROM `mailbox`
+ LEFT OUTER JOIN `alias_domain` on `mailbox`.`domain` = `alias_domain`.`target_domain`
+ WHERE `mailbox`.`username` = :object");
+ $stmt->execute(array(':object' => $row['object']));
+ $rows_aliases_wl_2 = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row_aliases_wl_2 = array_shift($rows_aliases_wl_2)) {
+?>
+ rcpt = "<?=$row_aliases_wl_2['aliases'];?>";
+<?php
+ }
+?>
+ apply "default" {
+ MAILCOW_MOO = 999.0;
+ }
+ }
+<?php
+}
+?>
+}
diff --git a/data/conf/rspamd/dynmaps/vars.inc.php b/data/conf/rspamd/dynmaps/vars.inc.php
new file mode 120000
index 00000000..f59ab89b
--- /dev/null
+++ b/data/conf/rspamd/dynmaps/vars.inc.php
@@ -0,0 +1 @@
+../../../web/inc/vars.inc.php
\ No newline at end of file
diff --git a/data/conf/rspamd/lua/rspamd.local.lua b/data/conf/rspamd/lua/rspamd.local.lua
index 727876b7..97c6af3d 100644
--- a/data/conf/rspamd/lua/rspamd.local.lua
+++ b/data/conf/rspamd/lua/rspamd.local.lua
@@ -1,9 +1,14 @@
rspamd_config.MAILCOW_AUTH = {
callback = function(task)
local uname = task:get_user()
if uname then
return 1
end
end
}
+rspamd_config.MAILCOW_MOO = function (task)
+ return true
+end
+
+rspamd_config:add_map('http://nginx:8081/settings.php', "settings map", process_map)
diff --git a/data/web/admin.php b/data/web/admin.php
index d960d222..30b773c1 100644
--- a/data/web/admin.php
+++ b/data/web/admin.php
@@ -1,272 +1,272 @@
<?php
require_once("inc/prerequisites.inc.php");
if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admin") {
require_once("inc/header.inc.php");
$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
?>
<div class="container">
<h4><span class="glyphicon glyphicon-user" aria-hidden="true"></span> <?=$lang['admin']['access'];?></h4>
<div class="panel-group" id="accordion_access">
<div class="panel panel-danger">
<div class="panel-heading"><?=$lang['admin']['admin_details'];?></div>
<div class="panel-body">
<form class="form-horizontal" autocapitalize="none" autocorrect="off" role="form" method="post">
<?php
try {
$stmt = $pdo->prepare("SELECT `username` FROM `admin`
WHERE `superadmin`='1' and active='1'");
$stmt->execute();
$AdminData = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
?>
<input type="hidden" name="admin_user_now" value="<?=htmlspecialchars($AdminData['username']);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="admin_user"><?=$lang['admin']['admin'];?>:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="admin_user" id="admin_user" value="<?=htmlspecialchars($AdminData['username']);?>" required>
&rdsh; <kbd>a-z A-Z - _ .</kbd>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="admin_pass"><?=$lang['admin']['password'];?>:</label>
<div class="col-sm-10">
<input type="password" class="form-control" name="admin_pass" id="admin_pass" placeholder="<?=$lang['admin']['unchanged_if_empty'];?>">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="admin_pass2"><?=$lang['admin']['password_repeat'];?>:</label>
<div class="col-sm-10">
<input type="password" class="form-control" name="admin_pass2" id="admin_pass2">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_set_admin" class="btn btn-default"><?=$lang['admin']['save'];?></button>
</div>
</div>
</form>
</div>
</div>
<div class="panel panel-default">
<div style="cursor:pointer;" class="panel-heading" data-toggle="collapse" data-parent="#accordion_access" data-target="#collapseDomAdmins">
<span class="accordion-toggle"><?=$lang['admin']['domain_admins'];?></span>
</div>
<div id="collapseDomAdmins" class="panel-collapse collapse">
<div class="panel-body">
<form method="post">
<div class="table-responsive">
<table class="table table-striped sortable-theme-bootstrap" data-sortable id="domainadminstable">
<thead>
<tr>
<th class="sort-table" style="min-width: 100px;"><?=$lang['admin']['username'];?></th>
<th class="sort-table" style="min-width: 166px;"><?=$lang['admin']['admin_domains'];?></th>
<th class="sort-table" style="min-width: 76px;"><?=$lang['admin']['active'];?></th>
<th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['admin']['action'];?></th>
</tr>
</thead>
<tbody>
<?php
try {
$stmt = $pdo->query("SELECT DISTINCT
`username`,
CASE WHEN `active`='1' THEN '".$lang['admin']['yes']."' ELSE '".$lang['admin']['no']."' END AS `active`
FROM `domain_admins`
WHERE `username` IN (
SELECT `username` FROM `admin`
WHERE `superadmin`!='1'
)");
$rows_username = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
if(!empty($rows_username)):
while ($row_user_state = array_shift($rows_username)):
?>
<tr id="data">
<td><?=htmlspecialchars(strtolower($row_user_state['username']));?></td>
<td>
<?php
try {
$stmt = $pdo->prepare("SELECT `domain` FROM `domain_admins` WHERE `username` = :username");
$stmt->execute(array('username' => $row_user_state['username']));
$rows_domain = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
while ($row_domain = array_shift($rows_domain)) {
echo htmlspecialchars($row_domain['domain']).'<br />';
}
?>
</td>
<td><?=$row_user_state['active'];?></td>
<td style="text-align: right;">
<div class="btn-group">
<a href="edit.php?domainadmin=<?=$row_user_state['username'];?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['admin']['edit'];?></a>
<a href="delete.php?domainadmin=<?=$row_user_state['username'];?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['admin']['remove'];?></a>
</div>
</td>
</td>
</tr>
<?php
endwhile;
else:
?>
<tr id="no-data"><td colspan="4" style="text-align: center; font-style: italic;"><?=$lang['admin']['no_record'];?></td></tr>
<?php
endif;
?>
</tbody>
</table>
</div>
</form>
<small>
<legend><?=$lang['admin']['add_domain_admin'];?></legend>
<form class="form-horizontal" role="form" method="post">
<div class="form-group">
<label class="control-label col-sm-2" for="username"><?=$lang['admin']['username'];?>:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="username" id="username" required>
&rdsh; <kbd>a-z A-Z - _ .</kbd>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="name"><?=$lang['admin']['admin_domains'];?>:</label>
<div class="col-sm-10">
<select title="<?=$lang['admin']['search_domain_da'];?>" style="width:100%" name="domain[]" size="5" multiple>
<?php
try {
$stmt = $pdo->query("SELECT domain FROM domain");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
while ($row = array_shift($rows)) {
echo "<option>".htmlspecialchars($row['domain'])."</option>";
}
?>
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="password"><?=$lang['admin']['password'];?>:</label>
<div class="col-sm-10">
<input type="password" class="form-control" name="password" id="password" placeholder="">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="password2"><?=$lang['admin']['password_repeat'];?>:</label>
<div class="col-sm-10">
<input type="password" class="form-control" name="password2" id="password2" placeholder="">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="active" checked> <?=$lang['admin']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_add_domain_admin" class="btn btn-default"><?=$lang['admin']['add'];?></button>
</div>
</div>
</form>
</small>
</div>
</div>
</div>
</div>
<h4><span class="glyphicon glyphicon-wrench" aria-hidden="true"></span> <?=$lang['admin']['configuration'];?></h4>
<div class="panel panel-default">
<div class="panel-heading"><?=$lang['admin']['dkim_keys'];?></div>
<div id="collapseDKIM" class="panel-collapse">
<div class="panel-body">
<?php
$dnstxt_folder = scandir($GLOBALS["MC_DKIM_TXTS"]);
- $dnstxt_files = array_diff($dnstxt_folder, array('.', '..'));
+ $dnstxt_files = array_diff($dnstxt_folder, array('.', '..', '.dkim_pub_keys'));
foreach($dnstxt_files as $file) {
$str = file_get_contents($GLOBALS["MC_DKIM_TXTS"]."/".$file);
$str = preg_replace('/\r|\t|\n/', '', $str);
preg_match('/\(.*\)/im', $str, $matches);
$domain = explode("_", $file)[1];
$selector = explode("_", $file)[0];
if(isset($matches[0])) {
$str = str_replace(array(' ', '"', '(', ')'), '', $matches[0]);
}
?>
<div class="row">
<div class="col-xs-2">
<p>Domain: <strong><?=htmlspecialchars($domain);?></strong> (<?=htmlspecialchars($selector);?>._domainkey)</p>
</div>
<div class="col-xs-9">
<pre>v=DKIM1;k=rsa;t=s;s=email;p=<?=$str;?></pre>
</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-remove-circle"></span></a>
<input type="hidden" name="delete_dkim_record" value="<?=htmlspecialchars($file);?>">
<input type="hidden" name="dkim[domain]" value="<?=$domain;?>">
<input type="hidden" name="dkim[selector]" value="<?=$selector;?>">
</form>
</div>
</div>
<?php
}
?>
<legend><?=$lang['admin']['dkim_add_key'];?></legend>
<form class="form-inline" role="form" method="post">
<div class="form-group">
<label for="dkim_domain">Domain</label>
<input class="form-control" id="dkim_domain" name="dkim[domain]" placeholder="example.org" required>
</div>
<div class="form-group">
<label for="dkim_selector">Selector</label>
<input class="form-control" id="dkim_selector" name="dkim[selector]" value="default" required>
</div>
<div class="form-group">
<select class="form-control" id="dkim_key_size" name="dkim[key_size]" title="<?=$lang['admin']['dkim_key_length'];?>" required>
<option>1024</option>
<option>2048</option>
</select>
</div>
<button type="submit" name="add_dkim_record" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> <?=$lang['admin']['add'];?></button>
</form>
</div>
</div>
</div>
</div> <!-- /container -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js" integrity="sha384-YWP9O4NjmcGo4oEJFXvvYSEzuHIvey+LbXkBNJ1Kd0yfugEZN9NCQNpRYBVC1RvA" crossorigin="anonymous"></script>
<script src="js/sorttable.js"></script>
<script src="js/admin.js"></script>
<?php
require_once("inc/footer.inc.php");
} else {
header('Location: /');
exit();
}
?>
diff --git a/data/web/edit.php b/data/web/edit.php
index a5629c0d..38a58bfc 100644
--- a/data/web/edit.php
+++ b/data/web/edit.php
@@ -1,544 +1,544 @@
<?php
require_once("inc/prerequisites.inc.php");
$AuthUsers = array("admin", "domainadmin");
if (!isset($_SESSION['mailcow_cc_role']) OR !in_array($_SESSION['mailcow_cc_role'], $AuthUsers)) {
header('Location: /');
exit();
}
require_once("inc/header.inc.php");
?>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><?=$lang['edit']['title'];?></h3>
</div>
<div class="panel-body">
<?php
if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin")) {
if (isset($_GET["alias"]) &&
!empty($_GET["alias"])) {
$alias = $_GET["alias"];
$domain = substr(strrchr($alias, "@"), 1);
try {
$stmt = $pdo->prepare("SELECT * FROM `alias`
WHERE `address`= :address
AND `goto` != :goto
AND (
`domain` IN (
SELECT `domain` FROM `domain_admins`
WHERE `active`='1'
AND `username`= :username
)
OR 'admin'= :admin
)");
$stmt->execute(array(
':address' => $alias,
':goto' => $alias,
':username' => $_SESSION['mailcow_cc_username'],
':admin' => $_SESSION['mailcow_cc_role']
));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
if ($result !== false) {
?>
<h4><?=$lang['edit']['alias'];?></h4>
<br />
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<input type="hidden" name="address" value="<?=htmlspecialchars($alias);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="goto"><?=$lang['edit']['target_address'];?></label>
<div class="col-sm-10">
<textarea class="form-control" autocapitalize="none" autocorrect="off" rows="10" id="goto" name="goto"><?=htmlspecialchars($result['goto']) ?></textarea>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="active" <?php if (isset($result['active']) && $result['active']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_mailbox_action" value="editalias" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
<?php
}
else {
?>
<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
<?php
}
}
elseif (isset($_GET['domainadmin']) &&
ctype_alnum(str_replace(array('_', '.', '-'), '', $_GET["domainadmin"])) &&
!empty($_GET["domainadmin"]) &&
$_GET["domainadmin"] != 'admin' &&
$_SESSION['mailcow_cc_role'] == "admin") {
$domain_admin = $_GET["domainadmin"];
try {
$stmt = $pdo->prepare("SELECT * FROM `domain_admins` WHERE `username`= :domain_admin");
$stmt->execute(array(
':domain_admin' => $domain_admin
));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
if ($result !== false) {
?>
<h4><?=$lang['edit']['domain_admin'];?></h4>
<br />
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<input type="hidden" name="username" value="<?=htmlspecialchars($domain_admin);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="domain"><?=$lang['edit']['domains'];?></label>
<div class="col-sm-10">
<select id="domain" name="domain[]" multiple>
<?php
try {
$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);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
while ($row_selected = array_shift($rows)):
?>
<option selected><?=htmlspecialchars($row_selected['domain']);?></option>
<?php
endwhile;
try {
$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);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
while ($row_unselected = array_shift($rows)):
?>
<option><?=htmlspecialchars($row_unselected['domain']);?></option>
<?php
endwhile;
?>
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="password"><?=$lang['edit']['password'];?></label>
<div class="col-sm-10">
<input type="password" class="form-control" name="password" id="password" placeholder="">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="password2"><?=$lang['edit']['password_repeat'];?></label>
<div class="col-sm-10">
<input type="password" class="form-control" name="password2" id="password2">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="active" <?php if (isset($result['active']) && $result['active']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_edit_domain_admin" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
<?php
}
else {
?>
<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
<?php
}
}
elseif (isset($_GET['domain']) &&
is_valid_domain_name($_GET["domain"]) &&
!empty($_GET["domain"])) {
$domain = $_GET["domain"];
try {
$stmt = $pdo->prepare("SELECT * FROM `domain` WHERE `domain`='".$domain."'
AND (
`domain` IN (
SELECT `domain` from `domain_admins`
WHERE `active`='1'
AND `username` = :username
)
OR 'admin'= :admin
)");
$stmt->execute(array(
':username' => $_SESSION['mailcow_cc_username'],
':admin' => $_SESSION['mailcow_cc_role']
));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
if ($result !== false) {
?>
<h4><?=$lang['edit']['domain'];?></h4>
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<input type="hidden" name="domain" value="<?=htmlspecialchars($domain);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="description"><?=$lang['edit']['description'];?></label>
<div class="col-sm-10">
<input type="text" class="form-control" name="description" id="description" value="<?=htmlspecialchars($result['description']);?>">
</div>
</div>
<?php
if ($_SESSION['mailcow_cc_role'] == "admin") {
?>
<div class="form-group">
<label class="control-label col-sm-2" for="aliases"><?=$lang['edit']['max_aliases'];?></label>
<div class="col-sm-10">
<input type="number" class="form-control" name="aliases" id="aliases" value="<?=intval($result['aliases']);?>">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="mailboxes"><?=$lang['edit']['max_mailboxes'];?></label>
<div class="col-sm-10">
<input type="number" class="form-control" name="mailboxes" id="mailboxes" value="<?=intval($result['mailboxes']);?>">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="maxquota"><?=$lang['edit']['max_quota'];?></label>
<div class="col-sm-10">
<input type="number" class="form-control" name="maxquota" id="maxquota" value="<?=intval($result['maxquota']);?>">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="quota"><?=$lang['edit']['domain_quota'];?></label>
<div class="col-sm-10">
<input type="number" class="form-control" name="quota" id="quota" value="<?=intval($result['quota']);?>">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2"><?=$lang['edit']['backup_mx_options'];?></label>
<div class="col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="backupmx" <?php if (isset($result['backupmx']) && $result['backupmx']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['relay_domain'];?></label>
<br />
<label><input type="checkbox" name="relay_all_recipients" <?php if (isset($result['relay_all_recipients']) && $result['relay_all_recipients']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['relay_all'];?></label>
<p><?=$lang['edit']['relay_all_info'];?></p>
</div>
</div>
</div>
<?php
}
?>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="active" <?php if (isset($result['active']) && $result['active']=="1") { echo "checked "; }; if ($_SESSION['mailcow_cc_role']=="domainadmin") { echo "disabled"; }; ?>> <?=$lang['edit']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_mailbox_action" value="editdomain" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
<?php
- $dnstxt_folder = scandir($GLOBALS["MC_DKIM_TXTS"]);
- $dnstxt_files = array_diff($dnstxt_folder, array('.', '..'));
+ $dnstxt_folder = scandir($GLOBALS["MC_DKIM_TXTS"]);
+ $dnstxt_files = array_diff($dnstxt_folder, array('.', '..', '.dkim_pub_keys'));
foreach($dnstxt_files as $file) {
if (explode("_", $file)[1] == $domain) {
$str = file_get_contents($GLOBALS["MC_DKIM_TXTS"]."/".$file);
$str = preg_replace('/\r|\t|\n/', '', $str);
preg_match('/\(.*\)/im', $str, $matches);
if(isset($matches[0])) {
$str = str_replace(array(' ', '"', '(', ')'), '', $matches[0]);
}
?>
<div class="row">
<div class="col-xs-2">
<p class="text-right"><?=$lang['edit']['dkim_signature'];?></p>
</div>
<div class="col-xs-10">
<div class="col-md-2"><b><?=$lang['edit']['dkim_txt_name'];?></b></div>
<div class="col-md-10">
<pre><?=htmlspecialchars(explode("_", $file)[0]);?>._domainkey</pre>
</div>
<div class="col-md-2"><b><?=$lang['edit']['dkim_txt_value'];?></b></div>
<div class="col-md-10">
<pre>v=DKIM1;k=rsa;t=s;s=email;p=<?=htmlspecialchars($str);?></pre>
<?=$lang['edit']['dkim_record_info'];?>
</div>
</div>
</div>
<?php
}
}
}
else {
?>
<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
<?php
}
}
elseif (isset($_GET['aliasdomain']) &&
is_valid_domain_name($_GET["aliasdomain"]) &&
!empty($_GET["aliasdomain"])) {
$alias_domain = $_GET["aliasdomain"];
try {
$stmt = $pdo->prepare("SELECT * FROM `alias_domain`
WHERE `alias_domain`= :alias_domain
AND (
`target_domain` IN (
SELECT `domain` FROM `domain_admins`
WHERE `active`='1'
AND `username`= :username
)
OR 'admin'= :admin
)");
$stmt->execute(array(
':alias_domain' => $alias_domain,
':username' => $_SESSION['mailcow_cc_username'],
':admin' => $_SESSION['mailcow_cc_role']
));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
if ($result !== false) {
?>
<h4><?=$lang['edit']['edit_alias_domain'];?></h4>
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<input type="hidden" name="alias_domain_now" value="<?=htmlspecialchars($alias_domain);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="alias_domain"><?=$lang['edit']['alias_domain'];?></label>
<div class="col-sm-10">
<input type="text" class="form-control" name="alias_domain" id="alias_domain" value="<?=htmlspecialchars($result['alias_domain']);?>">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="active" <?= (isset($result['active']) && $result['active']=="1") ? "checked" : null ?>> <?=$lang['edit']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_mailbox_action" value="editaliasdomain" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
<?php
$dnstxt_folder = scandir($GLOBALS["MC_DKIM_TXTS"]);
$dnstxt_files = array_diff($dnstxt_folder, array('.', '..'));
foreach($dnstxt_files as $file) {
if (explode("_", $file)[1] == $domain) {
$str = file_get_contents($GLOBALS["MC_DKIM_TXTS"]."/".$file);
$str = preg_replace('/\r|\t|\n/', '', $str);
preg_match('/\(.*\)/im', $str, $matches);
if(isset($matches[0])) {
$str = str_replace(array(' ', '"', '(', ')'), '', $matches[0]);
}
?>
<div class="row">
<div class="col-xs-2">
<p class="text-right"><?=$lang['edit']['dkim_signature'];?></p>
</div>
<div class="col-xs-10">
<div class="col-md-2"><b><?=$lang['edit']['dkim_txt_name'];?></b></div>
<div class="col-md-10">
<pre><?=htmlspecialchars(explode("_", $file)[0]);?>._domainkey</pre>
</div>
<div class="col-md-2"><b><?=$lang['edit']['dkim_txt_value'];?></b></div>
<div class="col-md-10">
<pre><?=htmlspecialchars($str);?></pre>
<?=$lang['edit']['dkim_record_info'];?>
</div>
</div>
</div>
<?php
}
}
}
else {
?>
<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
<?php
}
}
elseif (isset($_GET['mailbox']) && filter_var($_GET["mailbox"], FILTER_VALIDATE_EMAIL) && !empty($_GET["mailbox"])) {
$mailbox = $_GET["mailbox"];
try {
$stmt = $pdo->prepare("SELECT `username`, `domain`, `name`, `quota`, `active` FROM `mailbox` WHERE `username` = :username1");
$stmt->execute(array(
':username1' => $mailbox,
));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
if ($result !== false && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $result['domain'])) {
$left_m = remaining_specs($result['domain'], $_GET['mailbox'])['left_m'];
?>
<h4><?=$lang['edit']['mailbox'];?></h4>
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<input type="hidden" name="username" value="<?=htmlspecialchars($result['username']);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="name"><?=$lang['edit']['full_name'];?>:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="name" id="name" value="<?=htmlspecialchars($result['name'], ENT_QUOTES, 'UTF-8');?>">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="quota"><?=$lang['edit']['quota_mb'];?>:
<br /><span id="quotaBadge" class="badge">max. <?=intval($left_m)?> MiB</span>
</label>
<div class="col-sm-10">
<input type="number" name="quota" id="quota" id="destroyable" style="width:100%" min="1" max="<?=intval($left_m);?>" value="<?=intval($result['quota']) / 1048576;?>" class="form-control">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="sender_acl"><?=$lang['edit']['sender_acl'];?>:</label>
<div class="col-sm-10">
<select style="width:100%" id="sender_acl" name="sender_acl[]" size="10" multiple>
<?php
$rows = get_sender_acl_handles($mailbox, "preselected");
while ($row_goto_from_alias = array_shift($rows)):
?>
<option disabled selected><?=htmlspecialchars($row_goto_from_alias['address']);?></option>
<?php
endwhile;
// All manual selected
$rows = get_sender_acl_handles($mailbox, "selected");
while ($row_selected_sender_acl = array_shift($rows)):
if (!filter_var($row_selected_sender_acl['send_as'], FILTER_VALIDATE_EMAIL)):
?>
<option data-divider="true"></option>
<option value="<?=htmlspecialchars($row_selected_sender_acl['send_as']);?>" selected><?=htmlspecialchars(sprintf($lang['edit']['dont_check_sender_acl'], str_replace('@', '', $row_selected_sender_acl['send_as'])));?></option>
<option data-divider="true"></option>
<?php
else:
?>
<option selected><?=htmlspecialchars($row_selected_sender_acl['send_as']);?></option>
<?php
endif;
endwhile;
// Unselected domains
$rows = get_sender_acl_handles($mailbox, "unselected-domains");
while ($row_unselected_sender_acl = array_shift($rows)):
?>
<option data-divider="true"></option>
<option value="@<?=htmlspecialchars($row_unselected_sender_acl['domain']);?>"><?=htmlspecialchars(sprintf($lang['edit']['dont_check_sender_acl'], $row_unselected_sender_acl['domain']));?></option>
<option data-divider="true"></option>
<?php
endwhile;
// Unselected addresses
$rows = get_sender_acl_handles($mailbox, "unselected-addresses");
while ($row_unselected_sender_acl = array_shift($rows)):
?>
<option><?=htmlspecialchars($row_unselected_sender_acl['address']);?></option>
<?php
endwhile;
?>
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="password"><?=$lang['edit']['password'];?></label>
<div class="col-sm-10">
<input type="password" class="form-control" name="password" id="password" placeholder="<?=$lang['edit']['unchanged_if_empty'];?>">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="password2"><?=$lang['edit']['password_repeat'];?></label>
<div class="col-sm-10">
<input type="password" class="form-control" name="password2" id="password2">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="active" <?=($result['active']=="1") ? "checked" : "";?>> <?=$lang['edit']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_mailbox_action" value="editmailbox" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
<?php
}
else {
?>
<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
<?php
}
}
else {
?>
<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
<?php
}
}
else {
?>
<div class="alert alert-danger" role="alert"><?=$lang['danger']['access_denied'];?></div>
<?php
}
?>
</div>
</div>
</div>
</div>
<a href="<?=$_SESSION['return_to'];?>">&#8592; <?=$lang['edit']['previous'];?></a>
</div> <!-- /container -->
<?php
require_once("inc/footer.inc.php");
?>
diff --git a/data/web/inc/header.inc.php b/data/web/inc/header.inc.php
index 3d5635bf..ca6f7eb6 100644
--- a/data/web/inc/header.inc.php
+++ b/data/web/inc/header.inc.php
@@ -1,207 +1,214 @@
<!DOCTYPE html>
<html lang="<?= $_SESSION['mailcow_locale'] ?>">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>mailcow UI - <?php echo gethostname() ?></title>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js" integrity="sha384-XxcvoeNF5V0ZfksTnV+bejnCsJjOOIzN6UVwF85WBsAnU3zeYh5bloN+L4WLgeNE" crossorigin="anonymous"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/<?=strtolower(trim($DEFAULT_THEME));?>/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.9.4/css/bootstrap-select.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/7.0.2/css/bootstrap-slider.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/css/bootstrap3/bootstrap-switch.min.css">
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Source+Sans+Pro:400,600,700&subset=latin,latin-ext">
<link rel="stylesheet" href="/inc/languages.min.css">
<link rel="shortcut icon" href="/favicon.png" type="image/png">
<link rel="icon" href="/favicon.png" type="image/png">
<style>
#maxmsgsize { min-width: 80px; }
ul[id*="sortable"] { word-wrap: break-word; list-style-type: none; float: left; padding: 0 15px 0 0; width: 48%; cursor:move}
ul[id$="sortable-active"] li {cursor:move; }
ul[id$="sortable-inactive"] li {cursor:move }
.list-heading { cursor:default !important}
.ui-state-disabled { cursor:no-drop; color:#ccc; }
.ui-state-highlight {background: #F5F5F5 !important; height: 41px !important; cursor:move }
#slider1 .slider-selection {
background: #FFD700;
}
#slider1 .slider-track-high {
background: #FF4500;
}
#slider1 .slider-track-low {
background: #66CD00;
}
table[data-sortable] {
border-collapse: collapse;
border-spacing: 0;
}
table[data-sortable] th {
vertical-align: bottom;
font-weight: bold;
}
table[data-sortable] th, table[data-sortable] td {
text-align: left;
padding: 10px;
}
table[data-sortable] th:not([data-sortable="false"]) {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-touch-callout: none;
cursor: pointer;
}
table[data-sortable] th:after {
content: "";
visibility: hidden;
display: inline-block;
vertical-align: inherit;
height: 0;
width: 0;
border-width: 5px;
border-style: solid;
border-color: transparent;
margin-right: 1px;
margin-left: 10px;
float: right;
}
table[data-sortable] th[data-sortable="false"]:after {
display: none;
}
table[data-sortable] th[data-sorted="true"]:after {
visibility: visible;
}
table[data-sortable] th[data-sorted-direction="descending"]:after {
border-top-color: inherit;
margin-top: 8px;
}
table[data-sortable] th[data-sorted-direction="ascending"]:after {
border-bottom-color: inherit;
margin-top: 3px;
}
table[data-sortable].sortable-theme-bootstrap thead th {
border-bottom: 2px solid #e0e0e0;
}
table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"] {
color: #3a87ad;
background: #d9edf7;
border-bottom-color: #bce8f1;
}
table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"][data-sorted-direction="descending"]:after {
border-top-color: #3a87ad;
}
table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"][data-sorted-direction="ascending"]:after {
border-bottom-color: #3a87ad;
}
table[data-sortable].sortable-theme-bootstrap.sortable-theme-bootstrap-striped tbody > tr:nth-child(odd) > td {
background-color: #f9f9f9;
}
.btn {
text-transform: none;
}
#data td, #no-data td {
vertical-align: middle;
}
.sort-table:hover {
border-bottom-color: #00B7DC !important;
}
+.striped:nth-child(odd) {
+ background-color: #fff;
+}
+.striped:nth-child(even) {
+ background-color: #fafafa;
+ border:1px solid white;
+}
</style>
<?php
if (preg_match("/mailbox.php/i", $_SERVER['REQUEST_URI'])):
?>
<style>
.panel-heading div {
margin-top: -18px;
font-size: 15px;
}
.panel-heading div span {
margin-left:5px;
}
.panel-body {
display: none;
}
.clickable {
cursor: pointer;
}
.progress {
margin-bottom: 0px;
}
</style>
<?php
endif;
?>
</head>
<body style="padding-top:70px">
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/"><img height="32" alt="mailcow-logo" style="margin-top:-5px;" src="/img/cow_mailcow.svg" /></a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<?php
if (isset($_SESSION['mailcow_locale'])) {
?>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><span class="lang-sm lang-lbl" lang="<?=$_SESSION['mailcow_locale'];?>"></span><span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li <?=($_SESSION['mailcow_locale'] == 'de') ? 'class="active"' : ''?>> <a href="?<?= http_build_query(array_merge($_GET, array("lang" => "de"))) ?>"><span class="lang-xs lang-lbl-full" lang="de"></span></a></li>
<li <?=($_SESSION['mailcow_locale'] == 'en') ? 'class="active"' : ''?>> <a href="?<?= http_build_query(array_merge($_GET, array("lang" => "en"))) ?>"><span class="lang-xs lang-lbl-full" lang="en"></span></a></li>
<li <?=($_SESSION['mailcow_locale'] == 'nl') ? 'class="active"' : ''?>> <a href="?<?= http_build_query(array_merge($_GET, array("lang" => "nl"))) ?>"><span class="lang-xs lang-lbl-full" lang="nl"></span></a></li>
<li <?=($_SESSION['mailcow_locale'] == 'pt') ? 'class="active"' : ''?>> <a href="?<?= http_build_query(array_merge($_GET, array("lang" => "pt"))) ?>"><span class="lang-xs lang-lbl-full" lang="pt"></span></a></li>
</ul>
</li>
<?php
}
if (isset($_SESSION['mailcow_cc_role'])) {
?>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><?=$lang['header']['mailcow_settings'];?><span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<?php
if (isset($_SESSION['mailcow_cc_role'])) {
if ($_SESSION['mailcow_cc_role'] == "admin") {
?>
<li <?=(preg_match("/admin/i", $_SERVER['REQUEST_URI'])) ? 'class="active"' : ''?>><a href="/admin.php"><?=$lang['header']['administration'];?></a></li>
<?php
}
if ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin") {
?>
<li <?=(preg_match("/mailbox/i", $_SERVER['REQUEST_URI'])) ? 'class="active"' : ''?>><a href="/mailbox.php"><?=$lang['header']['mailboxes'];?></a></li>
<?php
}
if ($_SESSION['mailcow_cc_role'] == "user") {
?>
<li <?=(preg_match("/user/i", $_SERVER['REQUEST_URI'])) ? 'class="active"' : ''?>><a href="/user.php"><?=$lang['header']['user_settings'];?></a></li>
<?php
}
}
?>
</ul>
</li>
<?php
}
if (isset($_SESSION['mailcow_cc_username'])):
?>
<li><a style="border-left:1px solid #E7E7E7" href="#" onclick="logout.submit()"><?=sprintf($lang['header']['logged_in_as_logout'], $_SESSION['mailcow_cc_username']);?></a></li>
<?php
endif;
?>
</ul>
</div><!--/.nav-collapse -->
</div><!--/.container-fluid -->
</nav>
<form action="/" method="post" id="logout"><input type="hidden" name="logout"></form>
diff --git a/data/web/inc/otepad.php b/data/web/inc/otepad.php
new file mode 100644
index 00000000..e0067e31
--- /dev/null
+++ b/data/web/inc/otepad.php
@@ -0,0 +1,2656 @@
+<?php
+function hash_password($password) {
+ $salt_str = bin2hex(openssl_random_pseudo_bytes(8));
+ if ($GLOBALS['HASHING'] == "SHA512-CRYPT") {
+ return "{SHA512-CRYPT}".crypt($password, '$6$'.$salt_str.'$');
+ }
+ else {
+ return "{SSHA256}".base64_encode(hash('sha256', $password.$salt_str, true).$salt_str);
+ }
+}
+function hasDomainAccess($username, $role, $domain) {
+ global $pdo;
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
+ return false;
+ }
+
+ if (!is_valid_domain_name($domain)) {
+ return false;
+ }
+
+ try {
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain_admins`
+ WHERE (
+ `active`='1'
+ AND `username` = :username
+ AND `domain` = :domain
+ )
+ OR 'admin' = :role");
+ $stmt->execute(array(':username' => $username, ':domain' => $domain, ':role' => $role));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ } catch(PDOException $e) {
+ error_log($e);
+ return false;
+ }
+ if ($num_results != 0 && !empty($num_results)) {
+ return true;
+ }
+ return false;
+}
+function doveadm_authenticate($hash, $algorithm, $password) {
+ $descr = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
+ $pipes = array();
+ $process = proc_open("/usr/bin/doveadm pw -s ".$algorithm." -t '".$hash."'", $descr, $pipes);
+ if (is_resource($process)) {
+ fputs($pipes[0], $password);
+ fclose($pipes[0]);
+ while ($f = fgets($pipes[1])) {
+ if (preg_match('/(verified)/', $f)) {
+ proc_close($process);
+ return true;
+ }
+ return false;
+ }
+ fclose($pipes[1]);
+ while ($f = fgets($pipes[2])) {
+ proc_close($process);
+ return false;
+ }
+ fclose($pipes[2]);
+ proc_close($process);
+ }
+ return false;
+}
+function check_login($user, $pass) {
+ global $pdo;
+ if (!filter_var($user, FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $user))) {
+ return false;
+ }
+ if (!strpos(shell_exec("file --mime-encoding /usr/bin/doveadm"), "binary")) {
+ return false;
+ }
+ $user = strtolower(trim($user));
+ $stmt = $pdo->prepare("SELECT `password` FROM `admin`
+ WHERE `superadmin` = '1'
+ AND `username` = :user");
+ $stmt->execute(array(':user' => $user));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($rows as $row) {
+ if (doveadm_authenticate($row['password'], $GLOBALS['HASHING'], $pass) !== false) {
+ unset($_SESSION['ldelay']);
+ return "admin";
+ }
+ }
+ $stmt = $pdo->prepare("SELECT `password` FROM `admin`
+ WHERE `superadmin` = '0'
+ AND `active`='1'
+ AND `username` = :user");
+ $stmt->execute(array(':user' => $user));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($rows as $row) {
+ if (doveadm_authenticate($row['password'], $GLOBALS['HASHING'], $pass) !== false) {
+ unset($_SESSION['ldelay']);
+ return "domainadmin";
+ }
+ }
+ $stmt = $pdo->prepare("SELECT `password` FROM `mailbox`
+ WHERE `active`='1'
+ AND `username` = :user");
+ $stmt->execute(array(':user' => $user));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($rows as $row) {
+ if (doveadm_authenticate($row['password'], $GLOBALS['HASHING'], $pass) !== false) {
+ unset($_SESSION['ldelay']);
+ return "user";
+ }
+ }
+ if (!isset($_SESSION['ldelay'])) {
+ $_SESSION['ldelay'] = "0";
+ }
+ elseif (!isset($_SESSION['mailcow_cc_username'])) {
+ $_SESSION['ldelay'] = $_SESSION['ldelay']+0.5;
+ }
+ sleep($_SESSION['ldelay']);
+}
+function formatBytes($size, $precision = 2) {
+ if(!is_numeric($size)) {
+ return "0";
+ }
+ $base = log($size, 1024);
+ $suffixes = array(' Byte', ' KiB', ' MiB', ' GiB', ' TiB');
+ if ($size == "0") {
+ return "0";
+ }
+ return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
+}
+function dkim_table($action, $item) {
+ global $lang;
+ switch ($action) {
+ case "delete":
+ $domain = preg_replace('/[^A-Za-z0-9._\-]/', '_', $item['dkim']['domain']);
+ $selector = preg_replace('/[^A-Za-z0-9._\-]/', '_', $item['dkim']['selector']);
+ if (!ctype_alnum($selector) || !is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
+ );
+ break;
+ }
+ exec('rm ' . escapeshellarg($GLOBALS['MC_DKIM_TXTS'] . '/' . $selector . '_' . $domain), $out, $return);
+ if ($return != "0") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['dkim_remove_failed'])
+ );
+ break;
+ }
+ exec('rm ' . escapeshellarg($GLOBALS['MC_DKIM_KEYS'] . '/' . $domain . '.' . $selector), $out, $return);
+ if ($return != "0") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['dkim_remove_failed'])
+ );
+ break;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['dkim_removed'])
+ );
+ break;
+ case "add":
+ $domain = preg_replace('/[^A-Za-z0-9._\-]/', '_', $item['dkim']['domain']);
+ $selector = preg_replace('/[^A-Za-z0-9._\-]/', '_', $item['dkim']['selector']);
+ $key_length = $item['dkim']['key_size'];
+ if (!ctype_alnum($selector) || !is_valid_domain_name($domain) || !is_numeric($key_length)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
+ );
+ break;
+ }
+
+ if (file_exists($GLOBALS['MC_DKIM_TXTS'] . '/' . $selector . '_' . $domain) ||
+ file_exists($GLOBALS['MC_DKIM_KEYS'] . '/' . $domain . '.' . $selector)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
+ );
+ break;
+ }
+
+ // Should be done native in PHP soon
+ $privKey = shell_exec("openssl genrsa -out /tmp/dkim-private.pem " . escapeshellarg($key_length) . " -outform PEM && cat /tmp/dkim-private.pem");
+ $pubKey = shell_exec('openssl rsa -in /tmp/dkim-private.pem -pubout -outform PEM 2>/dev/null | sed -e "1d" -e "\$d" | tr -d "\n"');
+ shell_exec('rm /tmp/dkim-private.pem');
+
+ file_put_contents($GLOBALS['MC_DKIM_TXTS'] . '/' . $selector . '_' . $domain, $pubKey);
+ file_put_contents($GLOBALS['MC_DKIM_KEYS'] . '/' . $domain . '.' . $selector, $privKey);
+
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['dkim_added'])
+ );
+ break;
+ }
+}
+function mailbox_add_domain($postarray) {
+ global $pdo;
+ 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;
+ }
+
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+ isset($postarray['relay_all_recipients']) ? $relay_all_recipients = '1' : $relay_all_recipients = '0';
+ isset($postarray['backupmx']) ? $backupmx = '1' : $backupmx = '0';
+ isset($postarray['relay_all_recipients']) ? $backupmx = '1' : true;
+
+ 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));
+ }
+ 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`, `created`, `modified`, `active`, `relay_all_recipients`)
+ VALUES (:domain, :description, :aliases, :mailboxes, :maxquota, :quota, 'virtual', :backupmx, :created, :modified, :active, :relay_all_recipients)");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ':description' => $description,
+ ':aliases' => $aliases,
+ ':mailboxes' => $mailboxes,
+ ':maxquota' => $maxquota,
+ ':quota' => $quota,
+ ':backupmx' => $backupmx,
+ ':active' => $active,
+ ':created' => date('Y-m-d H:i:s'),
+ ':modified' => date('Y-m-d H:i:s'),
+ ':relay_all_recipients' => $relay_all_recipients
+ ));
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_added'], htmlspecialchars($domain))
+ );
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+}
+function mailbox_add_alias($postarray) {
+ global $lang;
+ global $pdo;
+ $addresses = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['address']));
+ $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+ 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;
+ }
+
+ $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
+ $local_part = strstr($address, '@', true);
+ $address = $local_part.'@'.$domain;
+
+ 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;
+ }
+
+ try {
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias`
+ WHERE `address`= :address");
+ $stmt->execute(array(':address' => $address));
+ $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']['is_alias_or_mailbox'], htmlspecialchars($address))
+ );
+ return false;
+ }
+
+ try {
+ $stmt = $pdo->prepare("SELECT `address` FROM `spamalias`
+ WHERE `address`= :address");
+ $stmt->execute(array(':address' => $address));
+ $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']['is_spam_alias'], htmlspecialchars($address))
+ );
+ 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;
+
+ 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`, `created`, `modified`, `active`)
+ VALUES (:address, :goto, :domain, :created, :modified, :active)");
+
+ if (!filter_var($address, FILTER_VALIDATE_EMAIL) === true) {
+ $stmt->execute(array(
+ ':address' => '@'.$domain,
+ ':goto' => $goto,
+ ':domain' => $domain,
+ ':created' => date('Y-m-d H:i:s'),
+ ':modified' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ }
+ else {
+ $stmt->execute(array(
+ ':address' => $address,
+ ':goto' => $goto,
+ ':domain' => $domain,
+ ':created' => date('Y-m-d H:i:s'),
+ ':modified' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['alias_added'])
+ );
+ }
+ catch (PDOException $e) {
+ $_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) {
+ global $lang;
+ global $pdo;
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+
+ if (!is_valid_domain_name($postarray['alias_domain'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
+ );
+ return false;
+ }
+
+ if (!is_valid_domain_name($postarray['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'], $postarray['target_domain'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+
+ if ($postarray['alias_domain'] == $postarray['target_domain']) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['aliasd_targetd_identical'])
+ );
+ return false;
+ }
+
+ $alias_domain = strtolower(trim($postarray['alias_domain']));
+ $target_domain = strtolower(trim($postarray['target_domain']));
+
+ 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));
+ }
+ 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']['targetd_not_found'])
+ );
+ return false;
+ }
+
+ try {
+ $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));
+ }
+ 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']['aliasd_exists'])
+ );
+ return false;
+ }
+
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `alias_domain` (`alias_domain`, `target_domain`, `created`, `modified`, `active`)
+ VALUES (:alias_domain, :target_domain, :created, :modified, :active)");
+ $stmt->execute(array(
+ ':alias_domain' => $alias_domain,
+ ':target_domain' => $target_domain,
+ ':created' => date('Y-m-d H:i:s'),
+ ':modified' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['aliasd_added'], htmlspecialchars($alias_domain))
+ );
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+
+}
+function mailbox_edit_alias_domain($postarray) {
+ global $lang;
+ global $pdo;
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+ $alias_domain = idn_to_ascii($postarray['alias_domain']);
+ $alias_domain = strtolower(trim($alias_domain));
+ $alias_domain_now = strtolower(trim($postarray['alias_domain_now']));
+ 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($alias_domain_now)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['alias_domain_invalid'])
+ );
+ return false;
+ }
+
+ try {
+ $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
+ WHERE `alias_domain`= :alias_domain_now");
+ $stmt->execute(array(':alias_domain_now' => $alias_domain_now));
+ $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("SELECT `target_domain` FROM `alias_domain`
+ WHERE `target_domain`= :alias_domain");
+ $stmt->execute(array(':alias_domain' => $alias_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) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['aliasd_targetd_identical'])
+ );
+ return false;
+ }
+
+ try {
+ $stmt = $pdo->prepare("UPDATE `alias_domain` SET `alias_domain` = :alias_domain, `active` = :active WHERE `alias_domain` = :alias_domain_now");
+ $stmt->execute(array(
+ ':alias_domain' => $alias_domain,
+ ':alias_domain_now' => $alias_domain_now,
+ ':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($alias_domain))
+ );
+}
+function mailbox_add_mailbox($postarray) {
+ global $pdo;
+ global $lang;
+ $username = strtolower(trim($postarray['local_part'])).'@'.strtolower(trim($postarray['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;
+ }
+ $domain = strtolower(trim($postarray['domain']));
+ $password = $postarray['password'];
+ $password2 = $postarray['password2'];
+ $local_part = strtolower(trim($postarray['local_part']));
+ $name = $postarray['name'];
+ $quota_m = $postarray['quota'];
+
+ if (empty($name)) {
+ $name = $local_part;
+ }
+
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+
+ $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;
+ }
+
+ try {
+ $stmt = $pdo->prepare("SELECT `mailboxes`, `maxquota`, `quota` 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;
+ }
+
+ try {
+ $stmt = $pdo->prepare("SELECT
+ COUNT(*) as count,
+ COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota`
+ FROM `mailbox`
+ WHERE `domain` = :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $MailboxData = $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;
+ }
+
+ try {
+ $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));
+ }
+ 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($username))
+ );
+ return false;
+ }
+
+ try {
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE address= :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;
+ }
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['is_alias'], htmlspecialchars($username))
+ );
+ return false;
+ }
+
+ try {
+ $stmt = $pdo->prepare("SELECT `address` FROM `spamalias` WHERE `address`= :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;
+ }
+ if ($num_results != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($username))
+ );
+ 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 ($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;
+ }
+
+ try {
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain` 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) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => $lang['danger']['domain_not_found']
+ );
+ 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`, `created`, `modified`, `active`)
+ VALUES (:username, :password_hashed, :name, :maildir, :quota_b, :local_part, :domain, :created, :modified, :active)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':password_hashed' => $password_hashed,
+ ':name' => $name,
+ ':maildir' => $maildir,
+ ':quota_b' => $quota_b,
+ ':local_part' => $local_part,
+ ':domain' => $domain,
+ ':created' => date('Y-m-d H:i:s'),
+ ':modified' => date('Y-m-d H:i:s'),
+ ':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`, `created`, `modified`, `active`)
+ VALUES (:username1, :username2, :domain, :created, :modified, :active)");
+ $stmt->execute(array(
+ ':username1' => $username,
+ ':username2' => $username,
+ ':domain' => $domain,
+ ':created' => date('Y-m-d H:i:s'),
+ ':modified' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_added'], htmlspecialchars($username))
+ );
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+}
+function mailbox_edit_alias($postarray) {
+ global $lang;
+ global $pdo;
+ $address = $postarray['address'];
+ $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 (empty($postarray['goto'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['goto_empty'])
+ );
+ 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);
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+ 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 {
+ $stmt = $pdo->prepare("UPDATE `alias` SET `goto` = :goto, `active`= :active WHERE `address` = :address");
+ $stmt->execute(array(
+ ':goto' => $goto,
+ ':active' => $active,
+ ':address' => $address
+ ));
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['alias_modified'], htmlspecialchars($address))
+ );
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+}
+function mailbox_edit_domain($postarray) {
+ global $lang;
+ global $pdo;
+ $domain = $postarray['domain'];
+ $description = $postarray['description'];
+
+ $aliases = filter_var($postarray['aliases'], FILTER_SANITIZE_NUMBER_FLOAT);
+ $mailboxes = filter_var($postarray['mailboxes'], FILTER_SANITIZE_NUMBER_FLOAT);
+ $maxquota = filter_var($postarray['maxquota'], FILTER_SANITIZE_NUMBER_FLOAT);
+ $quota = filter_var($postarray['quota'], FILTER_SANITIZE_NUMBER_FLOAT);
+
+ isset($postarray['relay_all_recipients']) ? $relay_all_recipients = '1' : $relay_all_recipients = '0';
+ isset($postarray['backupmx']) ? $backupmx = '1' : $backupmx = '0';
+ isset($postarray['relay_all_recipients']) ? $backupmx = '1' : true;
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+
+ try {
+ $stmt = $pdo->prepare("SELECT
+ COUNT(*) AS count,
+ MAX(COALESCE(ROUND(`quota`/1048576), 0)) AS `maxquota`,
+ COALESCE(ROUND(SUM(`quota`)/1048576), 0) AS `quota`
+ FROM `mailbox`
+ WHERE domain= :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+
+
+ try {
+ $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 (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+
+ if ($maxquota > $quota) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
+ );
+ return false;
+ }
+
+ if ($MailboxData['maxquota'] > $maxquota) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['max_quota_in_use'], $MailboxData['maxquota'])
+ );
+ return false;
+ }
+
+ if ($MailboxData['quota'] > $quota) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_quota_m_in_use'], $MailboxData['quota'])
+ );
+ 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;
+ }
+
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("UPDATE `domain` SET
+ `modified`= :modified,
+ `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,
+ ':modified' => date('Y-m-d H:i:s'),
+ ':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 edit_domain_admin($postarray) {
+ global $lang;
+ global $pdo;
+ $username = $postarray['username'];
+ $password = $postarray['password'];
+ $password2 = $postarray['password2'];
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+
+ 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 (!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,
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+
+ 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 ($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 `modified` = :modified, `active` = :active, `password` = :password_hashed WHERE `username` = :username");
+ $stmt->execute(array(
+ ':password_hashed' => $password_hashed,
+ ':username' => $username,
+ ':modified' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ else {
+ try {
+ $stmt = $pdo->prepare("UPDATE `admin` SET `modified` = :modified, `active` = :active WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':modified' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ }
+ 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 mailbox_edit_mailbox($postarray) {
+ global $lang;
+ global $pdo;
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+ if (!filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ $quota_m = $postarray['quota'];
+ $quota_b = $quota_m*1048576;
+ $username = $postarray['username'];
+ $name = $postarray['name'];
+ $password = $postarray['password'];
+ $password2 = $postarray['password2'];
+
+ try {
+ $stmt = $pdo->prepare("SELECT `domain`
+ FROM `mailbox`
+ WHERE username = :username");
+ $stmt->execute(array(':username' => $username));
+ $MailboxData1 = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $stmt = $pdo->prepare("SELECT
+ COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota_m_now`
+ FROM `mailbox`
+ WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ $MailboxData2 = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $stmt = $pdo->prepare("SELECT
+ COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota_m_in_use`
+ FROM `mailbox`
+ WHERE `domain` = :domain");
+ $stmt->execute(array(':domain' => $MailboxData1['domain']));
+ $MailboxData3 = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $stmt = $pdo->prepare("SELECT `quota`, `maxquota`
+ FROM `domain`
+ WHERE `domain` = :domain");
+ $stmt->execute(array(':domain' => $MailboxData1['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'], $MailboxData1['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 (($MailboxData3['quota_m_in_use'] - $MailboxData2['quota_m_now'] + $quota_m) > $DomainData['quota']) {
+ $quota_left_m = ($DomainData['quota'] - $MailboxData3['quota_m_in_use'] + $MailboxData2['quota_m_now']);
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], $quota_left_m)
+ );
+ return false;
+ }
+
+ 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 (isset($postarray['sender_acl']) && is_array($postarray['sender_acl'])) {
+ foreach ($postarray['sender_acl'] as $sender_acl) {
+ if (!filter_var($sender_acl, FILTER_VALIDATE_EMAIL) &&
+ !is_valid_domain_name(str_replace('@', '', $sender_acl))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
+ );
+ return false;
+ }
+ }
+ foreach ($postarray['sender_acl'] as $sender_acl) {
+ 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;
+ }
+ }
+ }
+ if (!empty($password) && !empty($password2)) {
+ 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
+ `modified` = :modified,
+ `active` = :active
+ WHERE `address` = :address");
+ $stmt->execute(array(
+ ':address' => $username,
+ ':modified' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ $stmt = $pdo->prepare("UPDATE `mailbox` SET
+ `modified` = :modified,
+ `active` = :active,
+ `password` = :password_hashed,
+ `name`= :name,
+ `quota` = :quota_b
+ WHERE `username` = :username");
+ $stmt->execute(array(
+ ':modified' => date('Y-m-d H:i:s'),
+ ':password_hashed' => $password_hashed,
+ ':active' => $active,
+ ':name' => $name,
+ ':quota_b' => $quota_b,
+ ':username' => $username
+ ));
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
+ );
+ return true;
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ try {
+ $stmt = $pdo->prepare("UPDATE `alias` SET
+ `modified` = :modified,
+ `active` = :active
+ WHERE `address` = :address");
+ $stmt->execute(array(
+ ':address' => $username,
+ ':modified' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ $stmt = $pdo->prepare("UPDATE `mailbox` SET
+ `modified` = :modified,
+ `active` = :active,
+ `name`= :name,
+ `quota` = :quota_b
+ WHERE `username` = :username");
+ $stmt->execute(array(
+ ':active' => $active,
+ ':modified' => date('Y-m-d H:i:s'),
+ ':name' => $name,
+ ':quota_b' => $quota_b,
+ ':username' => $username
+ ));
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
+ );
+ return true;
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+}
+function mailbox_delete_domain($postarray) {
+ global $lang;
+ global $pdo;
+ $domain = $postarray['domain'];
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ $domain = 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;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_removed'], htmlspecialchars($domain))
+ );
+ return true;
+}
+function mailbox_delete_alias($postarray) {
+ global $lang;
+ global $pdo;
+ $address = $postarray['address'];
+ $local_part = strstr($address, '@', true);
+ $domain = substr(strrchr($address, "@"), 1);
+ 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($address))
+ );
+
+}
+function mailbox_delete_alias_domain($postarray) {
+ global $lang;
+ global $pdo;
+ if (!is_valid_domain_name($postarray['alias_domain'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ $alias_domain = $postarray['alias_domain'];
+ 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,
+ ));
+ }
+ 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($alias_domain))
+ );
+}
+function mailbox_delete_mailbox($postarray) {
+ global $lang;
+ global $pdo;
+ $domain = substr(strrchr($postarray['username'], "@"), 1);
+ $username = $postarray['username'];
+ if (!filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
+ $_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;
+ }
+
+ 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 `filterconf` WHERE `object` = :username");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ $stmt = $pdo->prepare("SELECT `address`, `goto` FROM `alias`
+ WHERE `goto` LIKE :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($username))
+ );
+}
+function set_admin_account($postarray) {
+ global $lang;
+ global $pdo;
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ $name = $postarray['admin_user'];
+ $name_now = $postarray['admin_user_now'];
+
+ if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $name)) || empty ($name)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $name_now)) || empty ($name_now)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ if (!empty($postarray['admin_pass']) && !empty($postarray['admin_pass2'])) {
+ if ($postarray['admin_pass'] != $postarray['admin_pass2']) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_mismatch'])
+ );
+ return false;
+ }
+ $password_hashed = hash_password($postarray['admin_pass']);
+ try {
+ $stmt = $pdo->prepare("UPDATE `admin` SET
+ `modified` = :modified,
+ `password` = :password_hashed,
+ `username` = :name
+ WHERE `username` = :username");
+ $stmt->execute(array(
+ ':password_hashed' => $password_hashed,
+ ':modified' => date('Y-m-d H:i:s'),
+ ':name' => $name,
+ ':username' => $name_now
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ else {
+ try {
+ $stmt = $pdo->prepare("UPDATE `admin` SET
+ `modified` = :modified,
+ `username` = :name
+ WHERE `username` = :name_now");
+ $stmt->execute(array(
+ ':name' => $name,
+ ':modified' => date('Y-m-d H:i:s'),
+ ':name_now' => $name_now
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ try {
+ $stmt = $pdo->prepare("UPDATE `domain_admins` SET
+ `domain` = :domain,
+ `username` = :name
+ WHERE `username` = :name_now");
+ $stmt->execute(array(
+ ':domain' => 'ALL',
+ ':name' => $name,
+ ':name_now' => $name_now
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['admin_modified'])
+ );
+}
+function set_time_limited_aliases($postarray) {
+ global $lang;
+ global $pdo;
+ $username = $_SESSION['mailcow_cc_username'];
+ $domain = substr($username, strpos($username, '@'));
+ if (($_SESSION['mailcow_cc_role'] != "user" &&
+ $_SESSION['mailcow_cc_role'] != "domainadmin") ||
+ empty($username) ||
+ empty($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ switch ($postarray["trigger_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 "delete":
+ 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 "extend":
+ 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;
+ }
+}
+function set_user_account($postarray) {
+ global $lang;
+ global $pdo;
+ $username = $_SESSION['mailcow_cc_username'];
+ $password_old = $postarray['user_old_pass'];
+ isset($postarray['togglePwNew']) ? $pwnew_active = '1' : $pwnew_active = '0';
+
+ if (isset($pwnew_active) && $pwnew_active == "1") {
+ $password_new = $postarray['user_new_pass'];
+ $password_new2 = $postarray['user_new_pass2'];
+ }
+
+ if (!check_login($username, $password_old) == "user") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+
+ if ($_SESSION['mailcow_cc_role'] != "user" &&
+ $_SESSION['mailcow_cc_role'] != "domainadmin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+
+ if (isset($password_new) && isset($password_new2)) {
+ 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 (strlen($password_new) < "6" ||
+ !preg_match('/[A-Za-z]/', $password_new) ||
+ !preg_match('/[0-9]/', $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 `mailbox` SET `modified` = :modified, `password` = :password_hashed WHERE `username` = :username");
+ $stmt->execute(array(
+ ':password_hashed' => $password_hashed,
+ ':modified' => date('Y-m-d H:i:s'),
+ ':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 add_domain_admin($postarray) {
+ global $lang;
+ global $pdo;
+ $username = strtolower(trim($postarray['username']));
+ $password = $postarray['password'];
+ $password2 = $postarray['password2'];
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+ 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 ($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) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
+ VALUES (:username, :password_hashed, '0', :created, :modified, :active)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':password_hashed' => $password_hashed,
+ ':created' => date('Y-m-d H:i:s'),
+ ':modified' => date('Y-m-d H:i:s'),
+ ':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_spam_score($username) {
+ global $pdo;
+ $default = "5, 15";
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ return $default;
+ }
+ 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
+ );
+ return false;
+ }
+ if ($num_results == 0 || 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;
+ }
+ }
+}
+function set_whitelist($postarray) {
+ global $lang;
+ global $pdo;
+ $username = $_SESSION['mailcow_cc_username'];
+ $whitelist_from = trim(strtolower($postarray['whitelist_from']));
+ $whitelist_from = preg_replace("/\.\*/", "*", $whitelist_from);
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ if (!ctype_alnum(str_replace(array('@', '.', '-', '*'), '', $whitelist_from))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['whitelist_from_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `object` FROM `filterconf`
+ WHERE `option` = 'whitelist_from'
+ AND `object` = :username
+ AND `value` = :whitelist_from");
+ $stmt->execute(array(':username' => $username, ':whitelist_from' => $whitelist_from));
+ $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']['whitelist_exists'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option` ,`value`)
+ VALUES (:username, 'whitelist_from', :whitelist_from)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':whitelist_from' => $whitelist_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'], $username)
+ );
+}
+function delete_whitelist($postarray) {
+ global $lang;
+ global $pdo;
+ $username = $_SESSION['mailcow_cc_username'];
+ $prefid = $postarray['wlid'];
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ if (!is_numeric($prefid)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['whitelist_from_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username AND `prefid` = :prefid");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':prefid' => $prefid
+ ));
+ }
+ 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 set_blacklist($postarray) {
+ global $lang;
+ global $pdo;
+ $username = $_SESSION['mailcow_cc_username'];
+ $blacklist_from = trim(strtolower($postarray['blacklist_from']));
+ $blacklist_from = preg_replace("/\.\*/", "*", $blacklist_from);
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ if (!ctype_alnum(str_replace(array('@', '.', '-', '*'), '', $blacklist_from))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['blacklist_from_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `object` FROM `filterconf`
+ WHERE `option` = 'blacklist_from'
+ AND `object` = :username
+ AND `value` = :blacklist_from");
+ $stmt->execute(array(':username' => $username, ':blacklist_from' => $blacklist_from));
+ $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']['blacklist_exists'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option` ,`value`)
+ VALUES (:username, 'blacklist_from', :blacklist_from)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':blacklist_from' => $blacklist_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'], $username)
+ );
+}
+function delete_blacklist($postarray) {
+ global $lang;
+ global $pdo;
+ $username = $_SESSION['mailcow_cc_username'];
+ $prefid = $postarray['blid'];
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ if (!is_numeric($prefid)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['blacklist_from_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username AND `prefid` = :prefid");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':prefid' => $prefid
+ ));
+ }
+ 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 set_spam_score($postarray) {
+ global $lang;
+ global $pdo;
+ $username = $_SESSION['mailcow_cc_username'];
+ $lowspamlevel = explode(',', $postarray['score'])[0];
+ $highspamlevel = explode(',', $postarray['score'])[1];
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ 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) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], $username)
+ );
+}
+function set_tls_policy($postarray) {
+ global $lang;
+ global $pdo;
+ isset($postarray['tls_in']) ? $tls_in = '1' : $tls_in = '0';
+ isset($postarray['tls_out']) ? $tls_out = '1' : $tls_out = '0';
+ $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) {
+ global $lang;
+ global $pdo;
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `tls_enforce_out`, `tls_enforce_in` FROM `mailbox` WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ $TLSData = $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $TLSData;
+}
+function remaining_specs($domain, $object = null, $js = null) {
+ // left_m without object given = MiB left in domain
+ // left_m with object given = Max. MiB we can assign to given object
+ // limit_m = Domain limit in MiB
+ // left_c = Mailboxes we can create depending on domain quota
+ global $pdo;
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ 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 `in_use_m` FROM `mailbox` WHERE `domain` = :domain AND `username` != :object");
+ $stmt->execute(array(':domain' => $domain, ':object' => $object));
+ $MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $quota_left_m = $DomainData['quota'] - $MailboxDataDomain['in_use_m'];
+ $mboxs_left = $DomainData['mailboxes'] - $MailboxDataDomain['count'];
+
+ if ($quota_left_m > $DomainData['maxquota']) {
+ $quota_left_m = $DomainData['maxquota'];
+ }
+
+ }
+ catch (PDOException $e) {
+ return false;
+ }
+ if (is_numeric($quota_left_m)) {
+ $spec['left_m'] = $quota_left_m;
+ $spec['limit_m'] = $DomainData['maxquota'];
+ }
+ if (is_numeric($mboxs_left)) {
+ $spec['left_c'] = $mboxs_left;
+ }
+ if (!empty($js)) {
+ echo $quota_left_m;
+ exit;
+ }
+ return $spec;
+}
+function get_sender_acl_handles($mailbox, $which) {
+ global $pdo;
+ if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
+ return false;
+ }
+ switch ($which) {
+ case "preselected":
+ try {
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` = :goto AND `address` NOT LIKE '@%'");
+ $stmt->execute(array(':goto' => $mailbox));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ return $rows;
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ break;
+ case "selected":
+ try {
+ $stmt = $pdo->prepare("SELECT `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as");
+ $stmt->execute(array(':logged_in_as' => $mailbox));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ return $rows;
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ break;
+ case "unselected-domains":
+ try {
+ if ($_SESSION['mailcow_cc_role'] == "admin" ) {
+ $stmt = $pdo->prepare("SELECT DISTINCT `domain` FROM `domain`
+ WHERE `domain` NOT IN (
+ SELECT REPLACE(`send_as`, '@', '') FROM `sender_acl`
+ WHERE `logged_in_as` = :logged_in_as)
+ AND `domain` NOT IN (
+ SELECT REPLACE(`address`, '@', '') FROM `alias`
+ WHERE `goto` = :goto)");
+ $stmt->execute(array(
+ ':logged_in_as' => $mailbox,
+ ':goto' => $mailbox,
+ ));
+ }
+ else {
+ $stmt = $pdo->prepare("SELECT DISTINCT `domain` FROM `domain_admins`
+ WHERE `username` = :username
+ AND `domain` != 'ALL'
+ AND `domain` NOT IN (
+ SELECT REPLACE(`send_as`, '@', '') FROM `sender_acl`
+ WHERE `logged_in_as` = :logged_in_as)");
+ $stmt->execute(array(
+ ':logged_in_as' => $mailbox,
+ ':username' => $_SESSION['mailcow_cc_username']
+ ));
+ }
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ return $rows;
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ break;
+ case "unselected-addresses":
+ try {
+ if ($_SESSION['mailcow_cc_role'] == "admin" ) {
+ $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)");
+ $stmt->execute(array(
+ ':logged_in_as' => $mailbox,
+ ':goto' => $mailbox
+ ));
+ }
+ else {
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias`
+ WHERE `goto` != :goto
+ AND `domain` IN (
+ SELECT `domain` FROM `domain_admins`
+ WHERE `username` = :username)
+ AND `address` NOT IN (
+ SELECT `send_as` FROM `sender_acl`
+ WHERE `logged_in_as` = :logged_in_as)");
+ $stmt->execute(array(
+ ':logged_in_as' => $mailbox,
+ ':goto' => $mailbox,
+ ':username' => $_SESSION['mailcow_cc_username']
+ ));
+ }
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ return $rows;
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ break;
+ }
+ 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));
+}
+?>

File Metadata

Mime Type
text/x-diff
Expires
9月 12 Fri, 3:04 AM (20 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5763
默认替代文本
(132 KB)

Event Timeline