Merge branch 'dev' into patch-1
commit
06274e1a2d
|
@ -1,8 +1,8 @@
|
||||||
FROM debian:latest
|
FROM debian:stretch-slim
|
||||||
MAINTAINER https://m-ko.de Markus Kosmal <code@cnfg.io>
|
MAINTAINER https://m-ko.de Markus Kosmal <code@cnfg.io>
|
||||||
|
|
||||||
# Debian Base to use
|
# Debian Base to use
|
||||||
ENV DEBIAN_VERSION jessie
|
ENV DEBIAN_VERSION stretch
|
||||||
|
|
||||||
# initial install of av daemon
|
# initial install of av daemon
|
||||||
RUN echo "deb http://http.debian.net/debian/ $DEBIAN_VERSION main contrib non-free" > /etc/apt/sources.list && \
|
RUN echo "deb http://http.debian.net/debian/ $DEBIAN_VERSION main contrib non-free" > /etc/apt/sources.list && \
|
||||||
|
@ -13,15 +13,14 @@ RUN echo "deb http://http.debian.net/debian/ $DEBIAN_VERSION main contrib non-fr
|
||||||
clamav-daemon \
|
clamav-daemon \
|
||||||
clamav-freshclam \
|
clamav-freshclam \
|
||||||
libclamunrar7 \
|
libclamunrar7 \
|
||||||
wget && \
|
curl && \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# initial update of av databases
|
# initial update of av databases
|
||||||
RUN wget -O /var/lib/clamav/main.cvd http://db.local.clamav.net/main.cvd && \
|
COPY dl_files.sh /dl_files.sh
|
||||||
wget -O /var/lib/clamav/daily.cvd http://db.local.clamav.net/daily.cvd && \
|
RUN chmod +x /dl_files.sh
|
||||||
wget -O /var/lib/clamav/bytecode.cvd http://db.local.clamav.net/bytecode.cvd && \
|
RUN /dl_files.sh
|
||||||
chown clamav:clamav /var/lib/clamav/*.cvd
|
|
||||||
|
|
||||||
# permission juggling
|
# permission juggling
|
||||||
RUN mkdir /var/run/clamav && \
|
RUN mkdir /var/run/clamav && \
|
||||||
|
@ -33,9 +32,6 @@ RUN sed -i 's/^Foreground .*$/Foreground true/g' /etc/clamav/clamd.conf && \
|
||||||
echo "TCPSocket 3310" >> /etc/clamav/clamd.conf && \
|
echo "TCPSocket 3310" >> /etc/clamav/clamd.conf && \
|
||||||
sed -i 's/^Foreground .*$/Foreground true/g' /etc/clamav/freshclam.conf
|
sed -i 's/^Foreground .*$/Foreground true/g' /etc/clamav/freshclam.conf
|
||||||
|
|
||||||
# volume provision
|
|
||||||
VOLUME ["/var/lib/clamav"]
|
|
||||||
|
|
||||||
# port provision
|
# port provision
|
||||||
EXPOSE 3310
|
EXPOSE 3310
|
||||||
|
|
||||||
|
|
|
@ -1,35 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# bootstrap clam av service and clam av database updater shell script
|
trap "kill 0" SIGINT
|
||||||
# presented by mko (Markus Kosmal<code@cnfg.io>)
|
|
||||||
set -m
|
|
||||||
|
|
||||||
# start clam service itself and the updater in background as daemon
|
|
||||||
freshclam -d &
|
freshclam -d &
|
||||||
clamd &
|
clamd &
|
||||||
|
|
||||||
# recognize PIDs
|
sleep inf
|
||||||
pidlist=`jobs -p`
|
|
||||||
|
|
||||||
# initialize latest result var
|
|
||||||
latest_exit=0
|
|
||||||
|
|
||||||
# define shutdown helper
|
|
||||||
function shutdown() {
|
|
||||||
trap "" SUBS
|
|
||||||
|
|
||||||
for single in $pidlist; do
|
|
||||||
if ! kill -0 $pidlist 2>/dev/null; then
|
|
||||||
wait $pidlist
|
|
||||||
exitcode=$?
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
kill $pidlist 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# run shutdown
|
|
||||||
trap terminate SUBS
|
|
||||||
wait
|
|
||||||
|
|
||||||
# return received result
|
|
||||||
exit $latest_exit
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
declare -a DB_MIRRORS=(
|
||||||
|
"switch.clamav.net"
|
||||||
|
"clamavdb.heanet.ie"
|
||||||
|
"clamav.iol.cz"
|
||||||
|
"clamav.univ-nantes.fr"
|
||||||
|
"clamav.easynet.fr"
|
||||||
|
"clamav.begi.net"
|
||||||
|
)
|
||||||
|
declare -a DB_MIRRORS=( $(shuf -e "${DB_MIRRORS[@]}") )
|
||||||
|
|
||||||
|
DB_FILES=(
|
||||||
|
"bytecode.cvd"
|
||||||
|
"daily.cvd"
|
||||||
|
"main.cvd"
|
||||||
|
)
|
||||||
|
|
||||||
|
for i in "${DB_MIRRORS[@]}"; do
|
||||||
|
for j in "${DB_FILES[@]}"; do
|
||||||
|
[[ -f "/var/lib/clamav/${j}" && -s "/var/lib/clamav/${j}" ]] && continue;
|
||||||
|
if [[ $(curl -o /dev/null --connect-timeout 1 \
|
||||||
|
--max-time 1 \
|
||||||
|
--silent \
|
||||||
|
--head \
|
||||||
|
--write-out "%{http_code}\n" "${i}/${j}") == 200 ]]; then
|
||||||
|
curl "${i}/${j}" -o "/var/lib/clamav/${j}" -#
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
chown clamav:clamav /var/lib/clamav/*.cvd
|
|
@ -23,6 +23,7 @@ RUN apt-get install -y --no-install-recommends supervisor \
|
||||||
gnupg \
|
gnupg \
|
||||||
python-gpgme \
|
python-gpgme \
|
||||||
sudo \
|
sudo \
|
||||||
|
curl \
|
||||||
dirmngr
|
dirmngr
|
||||||
|
|
||||||
RUN addgroup --system --gid 600 zeyple
|
RUN addgroup --system --gid 600 zeyple
|
||||||
|
@ -34,6 +35,7 @@ COPY zeyple.py /usr/local/bin/zeyple.py
|
||||||
COPY zeyple.conf /etc/zeyple.conf
|
COPY zeyple.conf /etc/zeyple.conf
|
||||||
COPY supervisord.conf /etc/supervisor/supervisord.conf
|
COPY supervisord.conf /etc/supervisor/supervisord.conf
|
||||||
COPY postfix.sh /opt/postfix.sh
|
COPY postfix.sh /opt/postfix.sh
|
||||||
|
COPY whitelist_forwardinghosts.sh /usr/local/bin/whitelist_forwardinghosts.sh
|
||||||
|
|
||||||
EXPOSE 588
|
EXPOSE 588
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
while read QUERY; do
|
||||||
|
QUERY=($QUERY)
|
||||||
|
if [ "${QUERY[0]}" != "get" ]; then
|
||||||
|
echo "500 dunno"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
result=$(curl -s http://nginx:8081/forwardinghosts.php?host=${QUERY[1]})
|
||||||
|
logger -t whitelist_forwardinghosts -p mail.info "Look up ${QUERY[1]} on whitelist, result $result"
|
||||||
|
echo ${result}
|
||||||
|
done
|
|
@ -24,7 +24,7 @@ milter_default_action = accept
|
||||||
milter_protocol = 6
|
milter_protocol = 6
|
||||||
minimal_backoff_time = 300s
|
minimal_backoff_time = 300s
|
||||||
plaintext_reject_code = 550
|
plaintext_reject_code = 550
|
||||||
postscreen_access_list = permit_mynetworks, cidr:/opt/postfix/conf/postscreen_access.cidr
|
postscreen_access_list = permit_mynetworks, cidr:/opt/postfix/conf/postscreen_access.cidr, tcp:127.0.0.1:10027
|
||||||
postscreen_bare_newline_enable = no
|
postscreen_bare_newline_enable = no
|
||||||
postscreen_blacklist_action = drop
|
postscreen_blacklist_action = drop
|
||||||
postscreen_cache_cleanup_interval = 24h
|
postscreen_cache_cleanup_interval = 24h
|
||||||
|
|
|
@ -55,3 +55,5 @@ zeyple unix - n n - - pipe
|
||||||
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
||||||
-o mynetworks=127.0.0.0/8
|
-o mynetworks=127.0.0.0/8
|
||||||
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
|
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
|
||||||
|
|
||||||
|
127.0.0.1:10027 inet n n n - 0 spawn user=nobody argv=/usr/local/bin/whitelist_forwardinghosts.sh
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
header('Content-Type: text/plain');
|
||||||
|
require_once "vars.inc.php";
|
||||||
|
|
||||||
|
ini_set('error_reporting', 0);
|
||||||
|
|
||||||
|
function in_net($addr, $net)
|
||||||
|
{
|
||||||
|
$net = explode('/', $net);
|
||||||
|
if (count($net) > 1)
|
||||||
|
$mask = $net[1];
|
||||||
|
$net = inet_pton($net[0]);
|
||||||
|
$addr = inet_pton($addr);
|
||||||
|
|
||||||
|
$length = strlen($net); // 4 for IPv4, 16 for IPv6
|
||||||
|
if (strlen($net) != strlen($addr))
|
||||||
|
return FALSE;
|
||||||
|
if (!isset($mask))
|
||||||
|
$mask = $length * 8;
|
||||||
|
|
||||||
|
$addr_bin = '';
|
||||||
|
$net_bin = '';
|
||||||
|
for ($i = 0; $i < $length; ++$i)
|
||||||
|
{
|
||||||
|
$addr_bin .= str_pad(decbin(ord(substr($addr, $i, $i+1))), 8, '0', STR_PAD_LEFT);
|
||||||
|
$net_bin .= str_pad(decbin(ord(substr($net, $i, $i+1))), 8, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return substr($addr_bin, 0, $mask) == substr($net_bin, 0, $mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
$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,
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
|
||||||
|
$stmt = $pdo->query("SELECT host FROM `forwarding_hosts`");
|
||||||
|
$networks = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
foreach ($networks as $network)
|
||||||
|
{
|
||||||
|
if (in_net($_GET['host'], $network))
|
||||||
|
{
|
||||||
|
echo '200 permit';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '200 dunno';
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
echo '200 dunno';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
|
@ -32,6 +32,35 @@ catch (PDOException $e) {
|
||||||
?>
|
?>
|
||||||
settings {
|
settings {
|
||||||
<?php
|
<?php
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->query("SELECT `host` FROM `forwarding_hosts`");
|
||||||
|
$rows = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
$rows = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rows)
|
||||||
|
{
|
||||||
|
?>
|
||||||
|
whitelist_forwarding_hosts {
|
||||||
|
priority = high;
|
||||||
|
<?php
|
||||||
|
foreach ($rows as $host) {
|
||||||
|
echo "\t\t" . 'ip = "' . $host . '";' . "\n";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
apply "default" {
|
||||||
|
actions {
|
||||||
|
reject = 999.9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
symbols [
|
||||||
|
"WHITELIST_FORWARDING_HOST"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
<?php
|
||||||
|
}
|
||||||
$stmt = $pdo->query("SELECT DISTINCT `object` FROM `filterconf` WHERE `option` = 'highspamlevel' OR `option` = 'lowspamlevel'");
|
$stmt = $pdo->query("SELECT DISTINCT `object` FROM `filterconf` WHERE `option` = 'highspamlevel' OR `option` = 'lowspamlevel'");
|
||||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
@ -207,8 +236,11 @@ while ($row = array_shift($rows)) {
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
apply "default" {
|
apply "default" {
|
||||||
MAILCOW_MOO = -999.0;
|
MAILCOW_WHITE = -999.0;
|
||||||
}
|
}
|
||||||
|
symbols [
|
||||||
|
"MAILCOW_WHITE"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
@ -302,10 +334,13 @@ while ($row = array_shift($rows)) {
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
apply "default" {
|
apply "default" {
|
||||||
MAILCOW_MOO = 999.0;
|
MAILCOW_BLACK = 999.0;
|
||||||
}
|
}
|
||||||
|
symbols [
|
||||||
|
"MAILCOW_BLACK"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
clamav {
|
||||||
|
attachments_only = false;
|
||||||
|
max_size = 20000000;
|
||||||
|
symbol = "CLAM_VIRUS";
|
||||||
|
type = "clamav";
|
||||||
|
log_clean = true;
|
||||||
|
servers = "clamd:3310";
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
rules {
|
||||||
|
DKIM_FAIL {
|
||||||
|
action = "add header";
|
||||||
|
expression = "R_DKIM_REJECT & !MAILLIST & !MAILCOW_WHITE & !MAILCOW_BLACK";
|
||||||
|
require_action = ["no action", "greylist"];
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,10 +7,6 @@ rspamd_config.MAILCOW_AUTH = {
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
rspamd_config.MAILCOW_MOO = function (task)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
modify_subject_map = rspamd_config:add_map({
|
modify_subject_map = rspamd_config:add_map({
|
||||||
url = 'http://172.22.1.251:8081/tags.php',
|
url = 'http://172.22.1.251:8081/tags.php',
|
||||||
type = 'map',
|
type = 'map',
|
||||||
|
|
|
@ -353,7 +353,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] ==
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-offset-2 col-sm-10">
|
<div class="col-sm-offset-2 col-sm-10">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label><input type="checkbox" name="delete1" checked> <?=$lang['add']['delete1'];?></label>
|
<label><input type="checkbox" name="delete1"> <?=$lang['add']['delete1'];?></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -183,9 +183,11 @@ $tfa_data = get_tfa();
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h4><span class="glyphicon glyphicon-wrench" aria-hidden="true"></span> <?=$lang['admin']['configuration'];?></h4>
|
<h4><span class="glyphicon glyphicon-wrench" aria-hidden="true"></span> <?=$lang['admin']['configuration'];?></h4>
|
||||||
|
|
||||||
|
<div class="panel-group" id="accordion_access">
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><?=$lang['admin']['dkim_keys'];?></div>
|
<div class="panel-heading"><?=$lang['admin']['dkim_keys'];?></div>
|
||||||
<div id="collapseDKIM" class="panel-collapse">
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<p style="margin-bottom:40px"><?=$lang['admin']['dkim_key_hint'];?></p>
|
<p style="margin-bottom:40px"><?=$lang['admin']['dkim_key_hint'];?></p>
|
||||||
<?php
|
<?php
|
||||||
|
@ -297,7 +299,72 @@ $tfa_data = get_tfa();
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><?=$lang['admin']['forwarding_hosts'];?></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<p style="margin-bottom:40px"><?=$lang['admin']['forwarding_hosts_hint'];?></p>
|
||||||
|
<form method="post">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped" id="forwardinghoststable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="min-width: 100px;"><?=$lang['edit']['host'];?></th>
|
||||||
|
<th style="min-width: 100px;"><?=$lang['edit']['source'];?></th>
|
||||||
|
<th style="text-align: right; min-width: 200px;"><?=$lang['admin']['action'];?></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
$forwarding_hosts = get_forwarding_hosts();
|
||||||
|
if ($forwarding_hosts) {
|
||||||
|
foreach ($forwarding_hosts as $host) {
|
||||||
|
$source = $host->source;
|
||||||
|
$host = $host->host;
|
||||||
|
?>
|
||||||
|
<tr id="data">
|
||||||
|
<td><?=htmlspecialchars(strtolower($host));?></td>
|
||||||
|
<td><?=htmlspecialchars(strtolower($source));?></td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
<div class="btn-group">
|
||||||
|
<a href="delete.php?forwardinghost=<?=$host;?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['admin']['remove'];?></a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
?>
|
||||||
|
<tr id="no-data"><td colspan="4" style="text-align: center; font-style: italic;"><?=$lang['admin']['no_record'];?></td></tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<legend><?=$lang['admin']['add_forwarding_host'];?></legend>
|
||||||
|
<p class="help-block"><?=$lang['admin']['forwarding_hosts_add_hint'];?></p>
|
||||||
|
<form class="form-horizontal" role="form" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-sm-2" for="hostname"><?=$lang['edit']['host'];?>:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" name="hostname" id="hostname" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-2 col-sm-10">
|
||||||
|
<button type="submit" name="add_forwarding_host" class="btn btn-default"><?=$lang['admin']['add'];?></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
</div> <!-- /container -->
|
</div> <!-- /container -->
|
||||||
<script type='text/javascript'>
|
<script type='text/javascript'>
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -105,6 +105,23 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
|
||||||
</form>
|
</form>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
// DELETE FORWARDING HOST
|
||||||
|
elseif (isset($_GET["forwardinghost"]) &&
|
||||||
|
!empty($_GET["forwardinghost"]) &&
|
||||||
|
$_SESSION['mailcow_cc_role'] == "admin") {
|
||||||
|
$host = $_GET["forwardinghost"];
|
||||||
|
?>
|
||||||
|
<div class="alert alert-warning" role="alert"><?=sprintf($lang['delete']['remove_forwardinghost_warning'], htmlspecialchars($_GET["forwardinghost"]));?></div>
|
||||||
|
<form class="form-horizontal" role="form" method="post" action="/admin.php">
|
||||||
|
<input type="hidden" name="forwardinghost" value="<?=htmlspecialchars($host);?>">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-1 col-sm-10">
|
||||||
|
<button type="submit" name="delete_forwarding_host" class="btn btn-default btn-sm"><?=$lang['delete']['remove_button'];?></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
// DELETE MAILBOX
|
// DELETE MAILBOX
|
||||||
elseif (isset($_GET["mailbox"]) &&
|
elseif (isset($_GET["mailbox"]) &&
|
||||||
filter_var($_GET["mailbox"], FILTER_VALIDATE_EMAIL) &&
|
filter_var($_GET["mailbox"], FILTER_VALIDATE_EMAIL) &&
|
||||||
|
|
|
@ -62,69 +62,6 @@ function hasMailboxObjectAccess($username, $role, $object) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
function init_db_schema() {
|
|
||||||
// This will be much better in future releases...
|
|
||||||
global $pdo;
|
|
||||||
try {
|
|
||||||
$stmt = $pdo->prepare("SELECT NULL FROM `admin`, `imapsync`, `tfa`");
|
|
||||||
$stmt->execute();
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
$lines = file('/web/inc/init.sql');
|
|
||||||
$data = '';
|
|
||||||
foreach ($lines as $line) {
|
|
||||||
if (substr($line, 0, 2) == '--' || $line == '') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$data .= $line;
|
|
||||||
if (substr(trim($line), -1, 1) == ';') {
|
|
||||||
$pdo->query($data);
|
|
||||||
$data = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create index if not exists
|
|
||||||
$stmt = $pdo->query("SHOW INDEX FROM sogo_acl WHERE KEY_NAME = 'sogo_acl_c_folder_id_idx'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("CREATE INDEX sogo_acl_c_folder_id_idx ON sogo_acl(c_folder_id)");
|
|
||||||
}
|
|
||||||
$stmt = $pdo->query("SHOW INDEX FROM sogo_acl WHERE KEY_NAME = 'sogo_acl_c_uid_idx'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("CREATE INDEX sogo_acl_c_uid_idx ON sogo_acl(c_uid)");
|
|
||||||
}
|
|
||||||
$_SESSION['return'] = array(
|
|
||||||
'type' => 'success',
|
|
||||||
'msg' => 'Database initialization completed.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Add newly added columns
|
|
||||||
$stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'kind'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("ALTER TABLE `mailbox` ADD `kind` VARCHAR(100) NOT NULL DEFAULT ''");
|
|
||||||
}
|
|
||||||
$stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'multiple_bookings'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("ALTER TABLE `mailbox` ADD `multiple_bookings` tinyint(1) NOT NULL DEFAULT '0'");
|
|
||||||
}
|
|
||||||
$stmt = $pdo->query("SHOW COLUMNS FROM `imapsync` LIKE 'delete1'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("ALTER TABLE `imapsync` ADD `delete1` tinyint(1) NOT NULL DEFAULT '0'");
|
|
||||||
}
|
|
||||||
$stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'wants_tagged_subject'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("ALTER TABLE `mailbox` ADD `wants_tagged_subject` tinyint(1) NOT NULL DEFAULT '0'");
|
|
||||||
}
|
|
||||||
$stmt = $pdo->query("SHOW COLUMNS FROM `tfa` LIKE 'key_id'");
|
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
||||||
if ($num_results == 0) {
|
|
||||||
$pdo->query("ALTER TABLE `tfa` ADD `key_id` VARCHAR(255) DEFAULT 'unidentified'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function verify_ssha256($hash, $password) {
|
function verify_ssha256($hash, $password) {
|
||||||
// Remove tag if any
|
// Remove tag if any
|
||||||
$hash = ltrim($hash, '{SSHA256}');
|
$hash = ltrim($hash, '{SSHA256}');
|
||||||
|
@ -287,13 +224,11 @@ function edit_admin_account($postarray) {
|
||||||
$password_hashed = hash_password($password);
|
$password_hashed = hash_password($password);
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `admin` SET
|
$stmt = $pdo->prepare("UPDATE `admin` SET
|
||||||
`modified` = :modified,
|
|
||||||
`password` = :password_hashed,
|
`password` = :password_hashed,
|
||||||
`username` = :username1
|
`username` = :username1
|
||||||
WHERE `username` = :username2");
|
WHERE `username` = :username2");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':username1' => $username,
|
':username1' => $username,
|
||||||
':username2' => $username_now
|
':username2' => $username_now
|
||||||
));
|
));
|
||||||
|
@ -309,12 +244,10 @@ function edit_admin_account($postarray) {
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `admin` SET
|
$stmt = $pdo->prepare("UPDATE `admin` SET
|
||||||
`modified` = :modified,
|
|
||||||
`username` = :username1
|
`username` = :username1
|
||||||
WHERE `username` = :username2");
|
WHERE `username` = :username2");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':username1' => $username,
|
':username1' => $username,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':username2' => $username_now
|
':username2' => $username_now
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -608,10 +541,9 @@ function edit_user_account($postarray) {
|
||||||
}
|
}
|
||||||
$password_hashed = hash_password($password_new);
|
$password_hashed = hash_password($password_new);
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `mailbox` SET `modified` = :modified, `password` = :password_hashed WHERE `username` = :username");
|
$stmt = $pdo->prepare("UPDATE `mailbox` SET `password` = :password_hashed WHERE `username` = :username");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':username' => $username
|
':username' => $username
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -1633,13 +1565,11 @@ function add_domain_admin($postarray) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `active`)
|
||||||
VALUES (:username, :password_hashed, '0', :created, :modified, :active)");
|
VALUES (:username, :password_hashed, '0', :active)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':username' => $username,
|
':username' => $username,
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2228,12 +2158,11 @@ function edit_domain_admin($postarray) {
|
||||||
}
|
}
|
||||||
$password_hashed = hash_password($password);
|
$password_hashed = hash_password($password);
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `modified` = :modified, `active` = :active, `password` = :password_hashed WHERE `username` = :username2");
|
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `active` = :active, `password` = :password_hashed WHERE `username` = :username2");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':username1' => $username,
|
':username1' => $username,
|
||||||
':username2' => $username_now,
|
':username2' => $username_now,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
if (isset($postarray['disable_tfa'])) {
|
if (isset($postarray['disable_tfa'])) {
|
||||||
|
@ -2255,11 +2184,10 @@ function edit_domain_admin($postarray) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `modified` = :modified, `active` = :active WHERE `username` = :username2");
|
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username1, `active` = :active WHERE `username` = :username2");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':username1' => $username,
|
':username1' => $username,
|
||||||
':username2' => $username_now,
|
':username2' => $username_now,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
if (isset($postarray['disable_tfa'])) {
|
if (isset($postarray['disable_tfa'])) {
|
||||||
|
@ -2321,10 +2249,9 @@ function edit_domain_admin($postarray) {
|
||||||
}
|
}
|
||||||
$password_hashed = hash_password($password_new);
|
$password_hashed = hash_password($password_new);
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `admin` SET `modified` = :modified, `password` = :password_hashed WHERE `username` = :username");
|
$stmt = $pdo->prepare("UPDATE `admin` SET `password` = :password_hashed WHERE `username` = :username");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':username' => $username
|
':username' => $username
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2356,7 +2283,7 @@ function get_admin_details() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("SELECT `username`, `modified`, `created` FROM `admin`WHERE `superadmin`='1' AND active='1'");
|
$stmt = $pdo->prepare("SELECT `username`, `modified`, `created` FROM `admin` WHERE `superadmin`='1' AND active='1'");
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
|
@ -2601,8 +2528,8 @@ function mailbox_add_domain($postarray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `transport`, `backupmx`, `created`, `modified`, `active`, `relay_all_recipients`)
|
$stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `transport`, `backupmx`, `active`, `relay_all_recipients`)
|
||||||
VALUES (:domain, :description, :aliases, :mailboxes, :maxquota, :quota, 'virtual', :backupmx, :created, :modified, :active, :relay_all_recipients)");
|
VALUES (:domain, :description, :aliases, :mailboxes, :maxquota, :quota, 'virtual', :backupmx, :active, :relay_all_recipients)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':description' => $description,
|
':description' => $description,
|
||||||
|
@ -2612,8 +2539,6 @@ function mailbox_add_domain($postarray) {
|
||||||
':quota' => $quota,
|
':quota' => $quota,
|
||||||
':backupmx' => $backupmx,
|
':backupmx' => $backupmx,
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':relay_all_recipients' => $relay_all_recipients
|
':relay_all_recipients' => $relay_all_recipients
|
||||||
));
|
));
|
||||||
$_SESSION['return'] = array(
|
$_SESSION['return'] = array(
|
||||||
|
@ -2789,16 +2714,14 @@ function mailbox_add_alias($postarray) {
|
||||||
$goto = implode(",", $gotos);
|
$goto = implode(",", $gotos);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `created`, `modified`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `active`)
|
||||||
VALUES (:address, :goto, :domain, :created, :modified, :active)");
|
VALUES (:address, :goto, :domain, :active)");
|
||||||
|
|
||||||
if (!filter_var($address, FILTER_VALIDATE_EMAIL) === true) {
|
if (!filter_var($address, FILTER_VALIDATE_EMAIL) === true) {
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':address' => '@'.$domain,
|
':address' => '@'.$domain,
|
||||||
':goto' => $goto,
|
':goto' => $goto,
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2807,8 +2730,6 @@ function mailbox_add_alias($postarray) {
|
||||||
':address' => $address,
|
':address' => $address,
|
||||||
':goto' => $goto,
|
':goto' => $goto,
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2909,13 +2830,11 @@ function mailbox_add_alias_domain($postarray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `alias_domain` (`alias_domain`, `target_domain`, `created`, `modified`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `alias_domain` (`alias_domain`, `target_domain`, `active`)
|
||||||
VALUES (:alias_domain, :target_domain, :created, :modified, :active)");
|
VALUES (:alias_domain, :target_domain, :active)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':alias_domain' => $alias_domain,
|
':alias_domain' => $alias_domain,
|
||||||
':target_domain' => $target_domain,
|
':target_domain' => $target_domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
$_SESSION['return'] = array(
|
$_SESSION['return'] = array(
|
||||||
|
@ -3118,8 +3037,8 @@ function mailbox_add_mailbox($postarray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `created`, `modified`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `active`)
|
||||||
VALUES (:username, :password_hashed, :name, :maildir, :quota_b, :local_part, :domain, :created, :modified, :active)");
|
VALUES (:username, :password_hashed, :name, :maildir, :quota_b, :local_part, :domain, :active)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':username' => $username,
|
':username' => $username,
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
|
@ -3128,8 +3047,6 @@ function mailbox_add_mailbox($postarray) {
|
||||||
':quota_b' => $quota_b,
|
':quota_b' => $quota_b,
|
||||||
':local_part' => $local_part,
|
':local_part' => $local_part,
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -3137,14 +3054,12 @@ function mailbox_add_mailbox($postarray) {
|
||||||
VALUES (:username, '0', '0')");
|
VALUES (:username, '0', '0')");
|
||||||
$stmt->execute(array(':username' => $username));
|
$stmt->execute(array(':username' => $username));
|
||||||
|
|
||||||
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `created`, `modified`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `active`)
|
||||||
VALUES (:username1, :username2, :domain, :created, :modified, :active)");
|
VALUES (:username1, :username2, :domain, :active)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':username1' => $username,
|
':username1' => $username,
|
||||||
':username2' => $username,
|
':username2' => $username,
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -3274,15 +3189,13 @@ function mailbox_add_resource($postarray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `created`, `modified`, `active`, `multiple_bookings`, `kind`)
|
$stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `active`, `multiple_bookings`, `kind`)
|
||||||
VALUES (:name, 'RESOURCE', :description, 'RESOURCE', 0, :local_part, :domain, :created, :modified, :active, :multiple_bookings, :kind)");
|
VALUES (:name, 'RESOURCE', :description, 'RESOURCE', 0, :local_part, :domain, :active, :multiple_bookings, :kind)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':name' => $name,
|
':name' => $name,
|
||||||
':description' => $description,
|
':description' => $description,
|
||||||
':local_part' => $local_part,
|
':local_part' => $local_part,
|
||||||
':domain' => $domain,
|
':domain' => $domain,
|
||||||
':created' => date('Y-m-d H:i:s'),
|
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':kind' => $kind,
|
':kind' => $kind,
|
||||||
':multiple_bookings' => $multiple_bookings
|
':multiple_bookings' => $multiple_bookings
|
||||||
|
@ -3373,12 +3286,10 @@ function mailbox_edit_alias_domain($postarray) {
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `alias_domain` SET
|
$stmt = $pdo->prepare("UPDATE `alias_domain` SET
|
||||||
`alias_domain` = :alias_domain,
|
`alias_domain` = :alias_domain,
|
||||||
`active` = :active,
|
`active` = :active
|
||||||
`modified` = :modified
|
|
||||||
WHERE `alias_domain` = :alias_domain_now");
|
WHERE `alias_domain` = :alias_domain_now");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':alias_domain' => $alias_domain,
|
':alias_domain' => $alias_domain,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':alias_domain_now' => $alias_domain_now,
|
':alias_domain_now' => $alias_domain_now,
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
|
@ -3454,14 +3365,12 @@ function mailbox_edit_alias($postarray) {
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `alias` SET
|
$stmt = $pdo->prepare("UPDATE `alias` SET
|
||||||
`goto` = :goto,
|
`goto` = :goto,
|
||||||
`active`= :active,
|
`active`= :active
|
||||||
`modified` = :modified
|
|
||||||
WHERE `address` = :address");
|
WHERE `address` = :address");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':goto' => $goto,
|
':goto' => $goto,
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':address' => $address,
|
':address' => $address
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
));
|
));
|
||||||
$_SESSION['return'] = array(
|
$_SESSION['return'] = array(
|
||||||
'type' => 'success',
|
'type' => 'success',
|
||||||
|
@ -3506,11 +3415,9 @@ function mailbox_edit_domain($postarray) {
|
||||||
isset($postarray['active']) ? $active = '1' : $active = '0';
|
isset($postarray['active']) ? $active = '1' : $active = '0';
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `domain` SET
|
$stmt = $pdo->prepare("UPDATE `domain` SET
|
||||||
`modified`= :modified,
|
|
||||||
`description` = :description
|
`description` = :description
|
||||||
WHERE `domain` = :domain");
|
WHERE `domain` = :domain");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':description' => $description,
|
':description' => $description,
|
||||||
':domain' => $domain
|
':domain' => $domain
|
||||||
));
|
));
|
||||||
|
@ -3614,7 +3521,6 @@ function mailbox_edit_domain($postarray) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `domain` SET
|
$stmt = $pdo->prepare("UPDATE `domain` SET
|
||||||
`modified`= :modified,
|
|
||||||
`relay_all_recipients` = :relay_all_recipients,
|
`relay_all_recipients` = :relay_all_recipients,
|
||||||
`backupmx` = :backupmx,
|
`backupmx` = :backupmx,
|
||||||
`active` = :active,
|
`active` = :active,
|
||||||
|
@ -3632,7 +3538,6 @@ function mailbox_edit_domain($postarray) {
|
||||||
':maxquota' => $maxquota,
|
':maxquota' => $maxquota,
|
||||||
':mailboxes' => $mailboxes,
|
':mailboxes' => $mailboxes,
|
||||||
':aliases' => $aliases,
|
':aliases' => $aliases,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':description' => $description,
|
':description' => $description,
|
||||||
':domain' => $domain
|
':domain' => $domain
|
||||||
));
|
));
|
||||||
|
@ -3844,23 +3749,19 @@ function mailbox_edit_mailbox($postarray) {
|
||||||
$password_hashed = hash_password($password);
|
$password_hashed = hash_password($password);
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `alias` SET
|
$stmt = $pdo->prepare("UPDATE `alias` SET
|
||||||
`modified` = :modified,
|
|
||||||
`active` = :active
|
`active` = :active
|
||||||
WHERE `address` = :address");
|
WHERE `address` = :address");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':address' => $username,
|
':address' => $username,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
||||||
`modified` = :modified,
|
|
||||||
`active` = :active,
|
`active` = :active,
|
||||||
`password` = :password_hashed,
|
`password` = :password_hashed,
|
||||||
`name`= :name,
|
`name`= :name,
|
||||||
`quota` = :quota_b
|
`quota` = :quota_b
|
||||||
WHERE `username` = :username");
|
WHERE `username` = :username");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':name' => $name,
|
':name' => $name,
|
||||||
|
@ -3883,23 +3784,19 @@ function mailbox_edit_mailbox($postarray) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `alias` SET
|
$stmt = $pdo->prepare("UPDATE `alias` SET
|
||||||
`modified` = :modified,
|
|
||||||
`active` = :active
|
`active` = :active
|
||||||
WHERE `address` = :address");
|
WHERE `address` = :address");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':address' => $username,
|
':address' => $username,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':active' => $active
|
':active' => $active
|
||||||
));
|
));
|
||||||
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
||||||
`modified` = :modified,
|
|
||||||
`active` = :active,
|
`active` = :active,
|
||||||
`name`= :name,
|
`name`= :name,
|
||||||
`quota` = :quota_b
|
`quota` = :quota_b
|
||||||
WHERE `username` = :username");
|
WHERE `username` = :username");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':name' => $name,
|
':name' => $name,
|
||||||
':quota_b' => $quota_b,
|
':quota_b' => $quota_b,
|
||||||
':username' => $username
|
':username' => $username
|
||||||
|
@ -3962,7 +3859,6 @@ function mailbox_edit_resource($postarray) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
$stmt = $pdo->prepare("UPDATE `mailbox` SET
|
||||||
`modified` = :modified,
|
|
||||||
`active` = :active,
|
`active` = :active,
|
||||||
`name`= :description,
|
`name`= :description,
|
||||||
`kind`= :kind,
|
`kind`= :kind,
|
||||||
|
@ -3970,7 +3866,6 @@ function mailbox_edit_resource($postarray) {
|
||||||
WHERE `username` = :name");
|
WHERE `username` = :name");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':description' => $description,
|
':description' => $description,
|
||||||
':multiple_bookings' => $multiple_bookings,
|
':multiple_bookings' => $multiple_bookings,
|
||||||
':kind' => $kind,
|
':kind' => $kind,
|
||||||
|
@ -4796,12 +4691,10 @@ function mailbox_delete_mailbox($postarray) {
|
||||||
}
|
}
|
||||||
$gotos_rebuild = implode(',', $goto_exploded);
|
$gotos_rebuild = implode(',', $goto_exploded);
|
||||||
$stmt = $pdo->prepare("UPDATE `alias` SET
|
$stmt = $pdo->prepare("UPDATE `alias` SET
|
||||||
`goto` = :goto,
|
`goto` = :goto
|
||||||
`modified` = :modified,
|
|
||||||
WHERE `address` = :address");
|
WHERE `address` = :address");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':goto' => $gotos_rebuild,
|
':goto' => $gotos_rebuild,
|
||||||
':modified' => date('Y-m-d H:i:s'),
|
|
||||||
':address' => $gotos['address']
|
':address' => $gotos['address']
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -5039,4 +4932,93 @@ function get_u2f_registrations($username) {
|
||||||
$sel->execute(array($username));
|
$sel->execute(array($username));
|
||||||
return $sel->fetchAll(PDO::FETCH_OBJ);
|
return $sel->fetchAll(PDO::FETCH_OBJ);
|
||||||
}
|
}
|
||||||
|
function get_forwarding_hosts() {
|
||||||
|
global $pdo;
|
||||||
|
$sel = $pdo->prepare("SELECT host, source FROM `forwarding_hosts`");
|
||||||
|
$sel->execute();
|
||||||
|
return $sel->fetchAll(PDO::FETCH_OBJ);
|
||||||
|
}
|
||||||
|
function add_forwarding_host($postarray) {
|
||||||
|
require_once 'spf.inc.php';
|
||||||
|
global $pdo;
|
||||||
|
global $lang;
|
||||||
|
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => sprintf($lang['danger']['access_denied'])
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$source = $postarray['hostname'];
|
||||||
|
$host = $postarray['hostname'];
|
||||||
|
$hosts = array();
|
||||||
|
if (preg_match('/^[0-9a-fA-F:\/]+$/', $host)) { // IPv6 address
|
||||||
|
$hosts = array($host);
|
||||||
|
}
|
||||||
|
elseif (preg_match('/^[0-9\.\/]+$/', $host)) { // IPv4 address
|
||||||
|
$hosts = array($host);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$hosts = get_outgoing_hosts_best_guess($host);
|
||||||
|
}
|
||||||
|
if (!$hosts)
|
||||||
|
{
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => 'Invalid host specified: '. htmlspecialchars($host)
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
foreach ($hosts as $host) {
|
||||||
|
if ($source == $host)
|
||||||
|
$source = '';
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->prepare("INSERT IGNORE INTO `forwarding_hosts` (`host`, `source`) VALUES (:host, :source)");
|
||||||
|
$stmt->execute(array(
|
||||||
|
':host' => $host,
|
||||||
|
':source' => $source,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => 'MySQL: '.$e
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'msg' => sprintf($lang['success']['forwarding_host_added'], htmlspecialchars(implode(', ', $hosts)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function delete_forwarding_host($postarray) {
|
||||||
|
global $pdo;
|
||||||
|
global $lang;
|
||||||
|
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => sprintf($lang['danger']['access_denied'])
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$host = $postarray['forwardinghost'];
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM `forwarding_hosts` WHERE `host` = :host");
|
||||||
|
$stmt->execute(array(
|
||||||
|
':host' => $host,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => 'MySQL: '.$e
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'msg' => sprintf($lang['success']['forwarding_host_removed'], htmlspecialchars($host))
|
||||||
|
);
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,281 +0,0 @@
|
||||||
CREATE TABLE IF NOT EXISTS `admin` (
|
|
||||||
`username` VARCHAR(255) NOT NULL,
|
|
||||||
`password` VARCHAR(255) NOT NULL,
|
|
||||||
`superadmin` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
PRIMARY KEY (`username`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `alias` (
|
|
||||||
`address` VARCHAR(255) NOT NULL,
|
|
||||||
`goto` TEXT NOT NULL,
|
|
||||||
`domain` VARCHAR(255) NOT NULL,
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
PRIMARY KEY (`address`),
|
|
||||||
KEY `domain` (`domain`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `sender_acl` (
|
|
||||||
`logged_in_as` VARCHAR(255) NOT NULL,
|
|
||||||
`send_as` VARCHAR(255) NOT NULL
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `spamalias` (
|
|
||||||
`address` VARCHAR(255) NOT NULL,
|
|
||||||
`goto` TEXT NOT NULL,
|
|
||||||
`validity` INT(11) NOT NULL,
|
|
||||||
PRIMARY KEY (`address`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `alias_domain` (
|
|
||||||
`alias_domain` VARCHAR(255) NOT NULL,
|
|
||||||
`target_domain` VARCHAR(255) NOT NULL,
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
PRIMARY KEY (`alias_domain`),
|
|
||||||
KEY `active` (`active`),
|
|
||||||
KEY `target_domain` (`target_domain`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `domain` (
|
|
||||||
`domain` VARCHAR(255) NOT NULL,
|
|
||||||
`description` VARCHAR(255),
|
|
||||||
`aliases` INT(10) NOT NULL DEFAULT '0',
|
|
||||||
`mailboxes` INT(10) NOT NULL DEFAULT '0',
|
|
||||||
`maxquota` BIGINT(20) NOT NULL DEFAULT '0',
|
|
||||||
`quota` BIGINT(20) NOT NULL DEFAULT '0',
|
|
||||||
`transport` VARCHAR(255) NOT NULL,
|
|
||||||
`backupmx` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`relay_all_recipients` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
PRIMARY KEY (`domain`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `domain_admins` (
|
|
||||||
`username` VARCHAR(255) NOT NULL,
|
|
||||||
`domain` VARCHAR(255) NOT NULL,
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
KEY `username` (`username`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `mailbox` (
|
|
||||||
`username` VARCHAR(255) NOT NULL,
|
|
||||||
`password` VARCHAR(255) NOT NULL,
|
|
||||||
`name` VARCHAR(255),
|
|
||||||
`maildir` VARCHAR(255) NOT NULL,
|
|
||||||
`quota` BIGINT(20) NOT NULL DEFAULT '0',
|
|
||||||
`local_part` VARCHAR(255) NOT NULL,
|
|
||||||
`domain` VARCHAR(255) NOT NULL,
|
|
||||||
`created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
|
|
||||||
`tls_enforce_in` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`tls_enforce_out` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`kind` VARCHAR(100) NOT NULL DEFAULT '',
|
|
||||||
`multiple_bookings` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`wants_tagged_subject` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
PRIMARY KEY (`username`),
|
|
||||||
KEY `domain` (`domain`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `quota2` (
|
|
||||||
`username` VARCHAR(100) NOT NULL,
|
|
||||||
`bytes` BIGINT(20) NOT NULL DEFAULT '0',
|
|
||||||
`messages` INT(11) NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`username`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `filterconf` (
|
|
||||||
`object` VARCHAR(100) NOT NULL DEFAULT '',
|
|
||||||
`option` VARCHAR(50) NOT NULL DEFAULT '',
|
|
||||||
`value` VARCHAR(100) NOT NULL DEFAULT '',
|
|
||||||
`prefid` INT(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
PRIMARY KEY (`prefid`),
|
|
||||||
KEY `object` (`object`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `imapsync` (
|
|
||||||
`id` INT NOT NULL AUTO_INCREMENT,
|
|
||||||
`user2` VARCHAR(255) NOT NULL,
|
|
||||||
`host1` VARCHAR(255) NOT NULL,
|
|
||||||
`authmech1` ENUM('PLAIN','LOGIN','CRAM-MD5') DEFAULT 'PLAIN',
|
|
||||||
`regextrans2` VARCHAR(255) DEFAULT '',
|
|
||||||
`authmd51` TINYINT(1) NOT NULL DEFAULT 0,
|
|
||||||
`domain2` VARCHAR(255) NOT NULL DEFAULT '',
|
|
||||||
`subfolder2` VARCHAR(255) NOT NULL DEFAULT '',
|
|
||||||
`user1` VARCHAR(255) NOT NULL,
|
|
||||||
`password1` VARCHAR(255) NOT NULL,
|
|
||||||
`exclude` VARCHAR(500) NOT NULL DEFAULT '',
|
|
||||||
`maxage` SMALLINT NOT NULL DEFAULT '0',
|
|
||||||
`mins_interval` VARCHAR(50) NOT NULL,
|
|
||||||
`port1` SMALLINT NOT NULL,
|
|
||||||
`enc1` ENUM('TLS','SSL','PLAIN') DEFAULT 'TLS',
|
|
||||||
`delete2duplicates` TINYINT(1) NOT NULL DEFAULT '1',
|
|
||||||
`returned_text` TEXT,
|
|
||||||
`last_run` TIMESTAMP NULL DEFAULT NULL,
|
|
||||||
`created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `tfa` (
|
|
||||||
`id` INT NOT NULL AUTO_INCREMENT,
|
|
||||||
`username` VARCHAR(255) NOT NULL,
|
|
||||||
`authmech` ENUM('yubi_otp', 'u2f', 'hotp', 'totp'),
|
|
||||||
`secret` VARCHAR(255) DEFAULT NULL,
|
|
||||||
`keyHandle` VARCHAR(255) DEFAULT NULL,
|
|
||||||
`publicKey` VARCHAR(255) DEFAULT NULL,
|
|
||||||
`counter` INT NOT NULL DEFAULT '0',
|
|
||||||
`certificate` TEXT,
|
|
||||||
`active` TINYINT(1) NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
DROP VIEW IF EXISTS grouped_mail_aliases;
|
|
||||||
DROP VIEW IF EXISTS grouped_sender_acl;
|
|
||||||
DROP VIEW IF EXISTS grouped_domain_alias_address;
|
|
||||||
|
|
||||||
CREATE VIEW grouped_mail_aliases (username, aliases) AS
|
|
||||||
SELECT goto, IFNULL(GROUP_CONCAT(address SEPARATOR ' '), '') AS address FROM alias
|
|
||||||
WHERE address!=goto
|
|
||||||
AND active = '1'
|
|
||||||
AND address NOT LIKE '@%'
|
|
||||||
GROUP BY goto;
|
|
||||||
|
|
||||||
CREATE VIEW grouped_sender_acl (username, send_as) AS
|
|
||||||
SELECT logged_in_as, IFNULL(GROUP_CONCAT(send_as SEPARATOR ' '), '') AS send_as FROM sender_acl
|
|
||||||
WHERE send_as NOT LIKE '@%'
|
|
||||||
GROUP BY logged_in_as;
|
|
||||||
|
|
||||||
CREATE VIEW grouped_domain_alias_address (username, ad_alias) AS
|
|
||||||
SELECT username, IFNULL(GROUP_CONCAT(local_part, '@', alias_domain SEPARATOR ' '), '') AS ad_alias FROM mailbox
|
|
||||||
LEFT OUTER JOIN alias_domain on target_domain=domain GROUP BY username;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_acl (
|
|
||||||
c_folder_id INTEGER NOT NULL,
|
|
||||||
c_object character varying(255) NOT NULL,
|
|
||||||
c_uid character varying(255) NOT NULL,
|
|
||||||
c_role character varying(80) NOT NULL
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_alarms_folder (
|
|
||||||
c_path VARCHAR(255) NOT NULL,
|
|
||||||
c_name VARCHAR(255) NOT NULL,
|
|
||||||
c_uid VARCHAR(255) NOT NULL,
|
|
||||||
c_recurrence_id INT(11) DEFAULT NULL,
|
|
||||||
c_alarm_number INT(11) NOT NULL,
|
|
||||||
c_alarm_date INT(11) NOT NULL
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_cache_folder (
|
|
||||||
c_uid VARCHAR(255) NOT NULL,
|
|
||||||
c_path VARCHAR(255) NOT NULL,
|
|
||||||
c_parent_path VARCHAR(255) DEFAULT NULL,
|
|
||||||
c_type TINYINT(3) unsigned NOT NULL,
|
|
||||||
c_creationdate INT(11) NOT NULL,
|
|
||||||
c_lastmodified INT(11) NOT NULL,
|
|
||||||
c_version INT(11) NOT NULL DEFAULT '0',
|
|
||||||
c_deleted TINYINT(4) NOT NULL DEFAULT '0',
|
|
||||||
c_content longTEXT,
|
|
||||||
PRIMARY KEY (c_uid,c_path)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_folder_info (
|
|
||||||
c_folder_id BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
||||||
c_path VARCHAR(255) NOT NULL,
|
|
||||||
c_path1 VARCHAR(255) NOT NULL,
|
|
||||||
c_path2 VARCHAR(255) DEFAULT NULL,
|
|
||||||
c_path3 VARCHAR(255) DEFAULT NULL,
|
|
||||||
c_path4 VARCHAR(255) DEFAULT NULL,
|
|
||||||
c_foldername VARCHAR(255) NOT NULL,
|
|
||||||
c_location INTeger NULL,
|
|
||||||
c_quick_location VARCHAR(2048) DEFAULT NULL,
|
|
||||||
c_acl_location VARCHAR(2048) DEFAULT NULL,
|
|
||||||
c_folder_type VARCHAR(255) NOT NULL,
|
|
||||||
PRIMARY KEY (c_path),
|
|
||||||
UNIQUE KEY c_folder_id (c_folder_id)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_quick_appointment (
|
|
||||||
c_folder_id INTeger NOT NULL,
|
|
||||||
c_name character varying(255) NOT NULL,
|
|
||||||
c_uid character varying(255) NOT NULL,
|
|
||||||
c_startdate INTeger,
|
|
||||||
c_enddate INTeger,
|
|
||||||
c_cycleenddate INTeger,
|
|
||||||
c_title character varying(1000) NOT NULL,
|
|
||||||
c_participants TEXT,
|
|
||||||
c_isallday INTeger,
|
|
||||||
c_iscycle INTeger,
|
|
||||||
c_cycleinfo TEXT,
|
|
||||||
c_classification INTeger NOT NULL,
|
|
||||||
c_isopaque INTeger NOT NULL,
|
|
||||||
c_status INTeger NOT NULL,
|
|
||||||
c_priority INTeger,
|
|
||||||
c_location character varying(255),
|
|
||||||
c_orgmail character varying(255),
|
|
||||||
c_partmails TEXT,
|
|
||||||
c_partstates TEXT,
|
|
||||||
c_category character varying(255),
|
|
||||||
c_sequence INTeger,
|
|
||||||
c_component character varying(10) NOT NULL,
|
|
||||||
c_nextalarm INTeger,
|
|
||||||
c_description TEXT,
|
|
||||||
CONSTRAINT sogo_quick_appointment_pkey PRIMARY KEY (c_folder_id, c_name)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_quick_contact (
|
|
||||||
c_folder_id INTeger NOT NULL,
|
|
||||||
c_name character varying(255) NOT NULL,
|
|
||||||
c_givenname character varying(255),
|
|
||||||
c_cn character varying(255),
|
|
||||||
c_sn character varying(255),
|
|
||||||
c_screenname character varying(255),
|
|
||||||
c_l character varying(255),
|
|
||||||
c_mail character varying(255),
|
|
||||||
c_o character varying(255),
|
|
||||||
c_ou character varying(255),
|
|
||||||
c_telephonenumber character varying(255),
|
|
||||||
c_categories character varying(255),
|
|
||||||
c_component character varying(10) NOT NULL,
|
|
||||||
CONSTRAINT sogo_quick_contact_pkey PRIMARY KEY (c_folder_id, c_name)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_sessions_folder (
|
|
||||||
c_id VARCHAR(255) NOT NULL,
|
|
||||||
c_value VARCHAR(255) NOT NULL,
|
|
||||||
c_creationdate INT(11) NOT NULL,
|
|
||||||
c_lastseen INT(11) NOT NULL,
|
|
||||||
PRIMARY KEY (c_id)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_store (
|
|
||||||
c_folder_id INTeger NOT NULL,
|
|
||||||
c_name character varying(255) NOT NULL,
|
|
||||||
c_content mediumTEXT NOT NULL,
|
|
||||||
c_creationdate INTeger NOT NULL,
|
|
||||||
c_lastmodified INTeger NOT NULL,
|
|
||||||
c_version INTeger NOT NULL,
|
|
||||||
c_deleted INTeger,
|
|
||||||
CONSTRAINT sogo_store_pkey PRIMARY KEY (c_folder_id, c_name)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sogo_user_profile (
|
|
||||||
c_uid VARCHAR(255) NOT NULL,
|
|
||||||
c_defaults TEXT,
|
|
||||||
c_settings TEXT,
|
|
||||||
PRIMARY KEY (c_uid)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
|
||||||
|
|
||||||
INSERT INTO `admin` (username, password, superadmin, created, modified, active) SELECT 'admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1 WHERE NOT EXISTS (SELECT * FROM `admin`);
|
|
||||||
DELETE FROM `domain_admins`;
|
|
||||||
INSERT INTO `domain_admins` (username, domain, created, active) SELECT `username`, 'ALL', NOW(), 1 FROM `admin` WHERE superadmin='1' AND `username` NOT IN (SELECT `username` FROM `domain_admins`);
|
|
|
@ -0,0 +1,596 @@
|
||||||
|
<?php
|
||||||
|
function init_db_schema() {
|
||||||
|
try {
|
||||||
|
global $pdo;
|
||||||
|
|
||||||
|
$db_version = "23042017_1807";
|
||||||
|
|
||||||
|
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
if ($num_results != 0) {
|
||||||
|
$stmt = $pdo->query("SELECT `version` FROM `versions`");
|
||||||
|
if ($stmt->fetch(PDO::FETCH_ASSOC)['version'] == $db_version) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$views = array(
|
||||||
|
"grouped_mail_aliases" => "CREATE VIEW grouped_mail_aliases (username, aliases) AS
|
||||||
|
SELECT goto, IFNULL(GROUP_CONCAT(address SEPARATOR ' '), '') AS address FROM alias
|
||||||
|
WHERE address!=goto
|
||||||
|
AND active = '1'
|
||||||
|
AND address NOT LIKE '@%'
|
||||||
|
GROUP BY goto;",
|
||||||
|
"grouped_sender_acl" => "CREATE VIEW grouped_sender_acl (username, send_as) AS
|
||||||
|
SELECT logged_in_as, IFNULL(GROUP_CONCAT(send_as SEPARATOR ' '), '') AS send_as FROM sender_acl
|
||||||
|
WHERE send_as NOT LIKE '@%'
|
||||||
|
GROUP BY logged_in_as;",
|
||||||
|
"grouped_domain_alias_address" => "CREATE VIEW grouped_domain_alias_address (username, ad_alias) AS
|
||||||
|
SELECT username, IFNULL(GROUP_CONCAT(local_part, '@', alias_domain SEPARATOR ' '), '') AS ad_alias FROM mailbox
|
||||||
|
LEFT OUTER JOIN alias_domain on target_domain=domain GROUP BY username;"
|
||||||
|
);
|
||||||
|
|
||||||
|
$tables = array(
|
||||||
|
"versions" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"application" => "VARCHAR(255) NOT NULL",
|
||||||
|
"version" => "VARCHAR(100) NOT NULL",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("application")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"admin" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"username" => "VARCHAR(255) NOT NULL",
|
||||||
|
"password" => "VARCHAR(255) NOT NULL",
|
||||||
|
"superadmin" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE NOW(0)",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("username")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"alias" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"address" => "VARCHAR(255) NOT NULL",
|
||||||
|
"goto" => "TEXT NOT NULL",
|
||||||
|
"domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("address")
|
||||||
|
),
|
||||||
|
"key" => array(
|
||||||
|
"domain" => array("domain")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sender_acl" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"logged_in_as" => "VARCHAR(255) NOT NULL",
|
||||||
|
"send_as" => "VARCHAR(255) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"domain" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"description" => "VARCHAR(255)",
|
||||||
|
"aliases" => "INT(10) NOT NULL DEFAULT '0'",
|
||||||
|
"mailboxes" => "INT(10) NOT NULL DEFAULT '0'",
|
||||||
|
"maxquota" => "BIGINT(20) NOT NULL DEFAULT '0'",
|
||||||
|
"quota" => "BIGINT(20) NOT NULL DEFAULT '0'",
|
||||||
|
"transport" => "VARCHAR(255) NOT NULL",
|
||||||
|
"backupmx" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"relay_all_recipients" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("domain")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"alias_domain" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"alias_domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"target_domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("alias_domain")
|
||||||
|
),
|
||||||
|
"key" => array(
|
||||||
|
"active" => array("active"),
|
||||||
|
"target_domain" => array("target_domain")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"spamalias" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"address" => "VARCHAR(255) NOT NULL",
|
||||||
|
"goto" => "TEXT NOT NULL",
|
||||||
|
"validity" => "INT(11) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("address")
|
||||||
|
),
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"filterconf" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"object" => "VARCHAR(255) NOT NULL DEFAULT ''",
|
||||||
|
"option" => "VARCHAR(50) NOT NULL DEFAULT ''",
|
||||||
|
"value" => "VARCHAR(100) NOT NULL DEFAULT ''",
|
||||||
|
"prefid" => "INT(11) NOT NULL AUTO_INCREMENT"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("prefid")
|
||||||
|
),
|
||||||
|
"key" => array(
|
||||||
|
"object" => array("object")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"quota2" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"username" => "VARCHAR(255) NOT NULL",
|
||||||
|
"bytes" => "BIGINT(20) NOT NULL DEFAULT '0'",
|
||||||
|
"messages" => "BIGINT(20) NOT NULL DEFAULT '0'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("username")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"mailbox" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"username" => "VARCHAR(255) NOT NULL",
|
||||||
|
"password" => "VARCHAR(255) NOT NULL",
|
||||||
|
"name" => "VARCHAR(255)",
|
||||||
|
"maildir" => "VARCHAR(255) NOT NULL",
|
||||||
|
"quota" => "BIGINT(20) NOT NULL DEFAULT '0'",
|
||||||
|
"local_part" => "VARCHAR(255) NOT NULL",
|
||||||
|
"domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"tls_enforce_in" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"tls_enforce_out" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"kind" => "VARCHAR(100) NOT NULL DEFAULT ''",
|
||||||
|
"multiple_bookings" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"wants_tagged_subject" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("username")
|
||||||
|
),
|
||||||
|
"key" => array(
|
||||||
|
"domain" => array("domain")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"domain_admins" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"username" => "VARCHAR(255) NOT NULL",
|
||||||
|
"domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"key" => array(
|
||||||
|
"username" => array("username")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"imapsync" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"id" => "INT NOT NULL AUTO_INCREMENT",
|
||||||
|
"user2" => "VARCHAR(255) NOT NULL",
|
||||||
|
"host1" => "VARCHAR(255) NOT NULL",
|
||||||
|
"authmech1" => "ENUM('PLAIN','LOGIN','CRAM-MD5') DEFAULT 'PLAIN'",
|
||||||
|
"regextrans2" => "VARCHAR(255) DEFAULT ''",
|
||||||
|
"authmd51" => "TINYINT(1) NOT NULL DEFAULT 0",
|
||||||
|
"domain2" => "VARCHAR(255) NOT NULL DEFAULT ''",
|
||||||
|
"subfolder2" => "VARCHAR(255) NOT NULL DEFAULT ''",
|
||||||
|
"user1" => "VARCHAR(255) NOT NULL",
|
||||||
|
"password1" => "VARCHAR(255) NOT NULL",
|
||||||
|
"exclude" => "VARCHAR(500) NOT NULL DEFAULT ''",
|
||||||
|
"maxage" => "SMALLINT NOT NULL DEFAULT '0'",
|
||||||
|
"mins_interval" => "VARCHAR(50) NOT NULL",
|
||||||
|
"port1" => "SMALLINT NOT NULL",
|
||||||
|
"enc1" => "ENUM('TLS','SSL','PLAIN') DEFAULT 'TLS'",
|
||||||
|
"delete2duplicates" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||||
|
"returned_text" => "TEXT",
|
||||||
|
"last_run" => "TIMESTAMP NULL DEFAULT NULL",
|
||||||
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
|
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '0'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("id")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"tfa" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"id" => "INT NOT NULL AUTO_INCREMENT",
|
||||||
|
"username" => "VARCHAR(255) NOT NULL",
|
||||||
|
"authmech" => "ENUM('yubi_otp', 'u2f', 'hotp', 'totp')",
|
||||||
|
"secret" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"keyHandle" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"publicKey" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"counter" => "INT NOT NULL DEFAULT '0'",
|
||||||
|
"certificate" => "TEXT",
|
||||||
|
"active" => "TINYINT(1) NOT NULL DEFAULT '0'"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("id")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"forwarding_hosts" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"host" => "VARCHAR(255) NOT NULL",
|
||||||
|
"source" => "VARCHAR(255) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("host")
|
||||||
|
),
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_acl" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_folder_id" => "INT NOT NULL",
|
||||||
|
"c_object" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_uid" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_role" => "VARCHAR(80) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"key" => array(
|
||||||
|
"sogo_acl_c_folder_id_idx" => array("c_folder_id"),
|
||||||
|
"sogo_acl_c_uid_idx" => array("c_uid")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_alarms_folder" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_path" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_name" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_uid" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_recurrence_id" => "INT(11) DEFAULT NULL",
|
||||||
|
"c_alarm_number" => "INT(11) NOT NULL",
|
||||||
|
"c_alarm_date" => "INT(11) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_cache_folder" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_uid" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_path" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_parent_path" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"c_type" => "TINYINT(3) unsigned NOT NULL",
|
||||||
|
"c_creationdate" => "INT(11) NOT NULL",
|
||||||
|
"c_lastmodified" => "INT(11) NOT NULL",
|
||||||
|
"c_version" => "INT(11) NOT NULL DEFAULT '0'",
|
||||||
|
"c_deleted" => "TINYINT(4) NOT NULL DEFAULT '0'",
|
||||||
|
"c_content" => "LONGTEXT"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_uid", "c_path")
|
||||||
|
),
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_folder_info" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_folder_id" => "BIGINT(20) unsigned NOT NULL AUTO_INCREMENT",
|
||||||
|
"c_path" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_path1" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_path2" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"c_path3" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"c_path4" => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
"c_foldername" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_location" => "INT NULL",
|
||||||
|
"c_quick_location" => "VARCHAR(2048) DEFAULT NULL",
|
||||||
|
"c_acl_location" => "VARCHAR(2048) DEFAULT NULL",
|
||||||
|
"c_folder_type" => "VARCHAR(255) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_path")
|
||||||
|
),
|
||||||
|
"unique" => array(
|
||||||
|
"c_folder_id" => array("c_folder_id")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_quick_appointment" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_folder_id" => "INT NOT NULL",
|
||||||
|
"c_name" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_uid" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_startdate" => "INT",
|
||||||
|
"c_enddate" => "INT",
|
||||||
|
"c_cycleenddate" => "INT",
|
||||||
|
"c_title" => "VARCHAR(1000) NOT NULL",
|
||||||
|
"c_participants" => "TEXT",
|
||||||
|
"c_isallday" => "INT",
|
||||||
|
"c_iscycle" => "INT",
|
||||||
|
"c_cycleinfo" => "TEXT",
|
||||||
|
"c_classification" => "INT NOT NULL",
|
||||||
|
"c_isopaque" => "INT NOT NULL",
|
||||||
|
"c_status" => "INT NOT NULL",
|
||||||
|
"c_priority" => "INT",
|
||||||
|
"c_location" => "VARCHAR(255)",
|
||||||
|
"c_orgmail" => "VARCHAR(255)",
|
||||||
|
"c_partmails" => "TEXT",
|
||||||
|
"c_partstates" => "TEXT",
|
||||||
|
"c_category" => "VARCHAR(255)",
|
||||||
|
"c_sequence" => "INT",
|
||||||
|
"c_component" => "VARCHAR(10) NOT NULL",
|
||||||
|
"c_nextalarm" => "INT",
|
||||||
|
"c_description" => "TEXT"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_folder_id", "c_name")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_quick_contact" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_folder_id" => "INT NOT NULL",
|
||||||
|
"c_name" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_givenname" => "VARCHAR(255)",
|
||||||
|
"c_cn" => "VARCHAR(255)",
|
||||||
|
"c_sn" => "VARCHAR(255)",
|
||||||
|
"c_screenname" => "VARCHAR(255)",
|
||||||
|
"c_l" => "VARCHAR(255)",
|
||||||
|
"c_mail" => "VARCHAR(255)",
|
||||||
|
"c_o" => "VARCHAR(255)",
|
||||||
|
"c_ou" => "VARCHAR(255)",
|
||||||
|
"c_telephonenumber" => "VARCHAR(255)",
|
||||||
|
"c_categories" => "VARCHAR(255)",
|
||||||
|
"c_component" => "VARCHAR(10) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_folder_id", "c_name")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_sessions_folder" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_id" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_value" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_creationdate" => "INT(11) NOT NULL",
|
||||||
|
"c_lastseen" => "INT(11) NOT NULL"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_id")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_store" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_folder_id" => "INT NOT NULL",
|
||||||
|
"c_name" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_content" => "MEDIUMTEXT NOT NULL",
|
||||||
|
"c_creationdate" => "INT NOT NULL",
|
||||||
|
"c_lastmodified" => "INT NOT NULL",
|
||||||
|
"c_version" => "INT NOT NULL",
|
||||||
|
"c_deleted" => "INT"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_folder_id", "c_name")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
|
"sogo_user_profile" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"c_uid" => "VARCHAR(255) NOT NULL",
|
||||||
|
"c_defaults" => "TEXT",
|
||||||
|
"c_settings" => "TEXT"
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("c_uid")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($tables as $table => $properties) {
|
||||||
|
$stmt = $pdo->query("SHOW TABLES LIKE '" . $table . "'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
if ($num_results != 0) {
|
||||||
|
foreach($properties['cols'] as $column => $type) {
|
||||||
|
$stmt = $pdo->query("SHOW COLUMNS FROM `" . $table . "` LIKE '" . $column . "'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
if ($num_results == 0) {
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` ADD `" . $column . "` " . $type);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` MODIFY COLUMN `" . $column . "` " . $type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach($properties['keys'] as $key_type => $key_content) {
|
||||||
|
if (strtolower($key_type) == 'primary') {
|
||||||
|
foreach ($key_content as $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = 'PRIMARY'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
$is_drop = ($num_results != 0) ? "DROP PRIMARY KEY, " : "";
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` " . $is_drop . "ADD PRIMARY KEY (" . $fields . ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strtolower($key_type) == 'key') {
|
||||||
|
foreach ($key_content as $key_name => $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = '" . $key_name . "'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
$is_drop = ($num_results != 0) ? "DROP INDEX `" . $key_name . "`, " : "";
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` " . $is_drop . "ADD KEY `" . $key_name . "` (" . $fields . ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strtolower($key_type) == 'unique') {
|
||||||
|
foreach ($key_content as $key_name => $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = '" . $key_name . "'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
$is_drop = ($num_results != 0) ? "DROP INDEX `" . $key_name . "`, " : "";
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` " . $is_drop . "ADD UNIQUE KEY `" . $key_name . "` (" . $fields . ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Drop all vanished columns
|
||||||
|
$stmt = $pdo->query("SHOW COLUMNS FROM `" . $table . "`");
|
||||||
|
$cols_in_table = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
while ($row = array_shift($cols_in_table)) {
|
||||||
|
if (!array_key_exists($row['Field'], $properties['cols'])) {
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` DROP COLUMN `" . $row['Field'] . "`;");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1: Get all non-primary keys, that currently exist and those that should exist
|
||||||
|
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE `Key_name` != 'PRIMARY'");
|
||||||
|
$keys_in_table = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$keys_to_exist = array();
|
||||||
|
if (isset($properties['keys']['unique']) && is_array($properties['keys']['unique'])) {
|
||||||
|
foreach ($properties['keys']['unique'] as $key_name => $key_values) {
|
||||||
|
$keys_to_exist[] = $key_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isset($properties['keys']['key']) && is_array($properties['keys']['key'])) {
|
||||||
|
foreach ($properties['keys']['key'] as $key_name => $key_values) {
|
||||||
|
$keys_to_exist[] = $key_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Step 2: Drop all vanished indexes
|
||||||
|
while ($row = array_shift($keys_in_table)) {
|
||||||
|
if (!in_array($row['Key_name'], $keys_to_exist)) {
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` DROP INDEX `" . $row['Key_name'] . "`");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Step 3: Drop all vanished primary keys
|
||||||
|
if (!isset($properties['keys']['primary'])) {
|
||||||
|
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = 'PRIMARY'");
|
||||||
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
if ($num_results != 0) {
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` DROP PRIMARY KEY");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Create table if it is missing
|
||||||
|
$sql = "CREATE TABLE IF NOT EXISTS `" . $table . "` (";
|
||||||
|
foreach($properties['cols'] as $column => $type) {
|
||||||
|
$sql .= $column . " " . $type . ",";
|
||||||
|
}
|
||||||
|
foreach($properties['keys'] as $key_type => $key_content) {
|
||||||
|
if (strtolower($key_type) == 'primary') {
|
||||||
|
foreach ($key_content as $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$sql .= "PRIMARY KEY (" . $fields . ")" . ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (strtolower($key_type) == 'key') {
|
||||||
|
foreach ($key_content as $key_name => $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$sql .= "KEY `" . $key_name . "` (" . $fields . ")" . ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (strtolower($key_type) == 'unique') {
|
||||||
|
foreach ($key_content as $key_name => $key_values) {
|
||||||
|
$fields = "`" . implode("`, `", $key_values) . "`";
|
||||||
|
$sql .= "UNIQUE KEY `" . $key_name . "` (" . $fields . ")" . ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sql = rtrim($sql, ",");
|
||||||
|
$sql .= ") " . $properties['attr'];
|
||||||
|
$pdo->query($sql);
|
||||||
|
}
|
||||||
|
// Reset table attributes
|
||||||
|
$pdo->query("ALTER TABLE `" . $table . "` " . $properties['attr'] . ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recreate SQL views
|
||||||
|
foreach ($views as $view => $create) {
|
||||||
|
$pdo->query("DROP VIEW IF EXISTS `" . $view . "`;");
|
||||||
|
$pdo->query($create);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject admin if not exists
|
||||||
|
$stmt = $pdo->query("INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
|
||||||
|
SELECT 'admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1
|
||||||
|
WHERE NOT EXISTS (SELECT * FROM `admin`);");
|
||||||
|
$stmt = $pdo->query("DELETE FROM `domain_admins`;");
|
||||||
|
$stmt = $pdo->query("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
|
||||||
|
SELECT `username`, 'ALL', NOW(), 1 FROM `admin`
|
||||||
|
WHERE superadmin='1' AND `username` NOT IN (SELECT `username` FROM `domain_admins`);");
|
||||||
|
|
||||||
|
// Insert new DB schema version
|
||||||
|
$stmt = $pdo->query("REPLACE INTO `versions` (`application`, `version`) VALUES ('db_schema', '" . $db_version . "');");
|
||||||
|
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'msg' => 'Database initialisation completed'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'msg' => 'Database initialisation failed: ' . $e->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -29,18 +29,28 @@ require_once 'inc/lib/U2F.php';
|
||||||
$u2f = new u2flib_server\U2F('https://' . $_SERVER['SERVER_NAME']);
|
$u2f = new u2flib_server\U2F('https://' . $_SERVER['SERVER_NAME']);
|
||||||
|
|
||||||
// PDO
|
// PDO
|
||||||
$dsn = "$database_type:host=$database_host;dbname=$database_name";
|
// Calculate offset
|
||||||
|
$now = new DateTime();
|
||||||
|
$mins = $now->getOffset() / 60;
|
||||||
|
$sgn = ($mins < 0 ? -1 : 1);
|
||||||
|
$mins = abs($mins);
|
||||||
|
$hrs = floor($mins / 60);
|
||||||
|
$mins -= $hrs * 60;
|
||||||
|
$offset = sprintf('%+d:%02d', $hrs*$sgn, $mins);
|
||||||
|
|
||||||
|
$dsn = $database_type . ":host=" . $database_host . ";dbname=" . $database_name;
|
||||||
$opt = [
|
$opt = [
|
||||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
PDO::ATTR_EMULATE_PREPARES => false,
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
PDO::MYSQL_ATTR_INIT_COMMAND => "SET time_zone = '" . $offset . "'",
|
||||||
];
|
];
|
||||||
try {
|
try {
|
||||||
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
|
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
|
||||||
}
|
}
|
||||||
catch (PDOException $e) {
|
catch (PDOException $e) {
|
||||||
?>
|
?>
|
||||||
<center style='font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;'>🐮 Connection failed, database may be in warm-up state, please try again later.<br /><br />The following error was reported:<br/> <?=$e->getMessage();?></center>
|
<center style='font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;'>?? Connection failed, database may be in warm-up state, please try again later.<br /><br />The following error was reported:<br/> <?=$e->getMessage();?></center>
|
||||||
<?php
|
<?php
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
@ -106,5 +116,6 @@ if (isset($_GET['lang'])) {
|
||||||
require_once 'lang/lang.en.php';
|
require_once 'lang/lang.en.php';
|
||||||
include 'lang/lang.'.$_SESSION['mailcow_locale'].'.php';
|
include 'lang/lang.'.$_SESSION['mailcow_locale'].'.php';
|
||||||
require_once 'inc/functions.inc.php';
|
require_once 'inc/functions.inc.php';
|
||||||
|
require_once 'inc/init_db.inc.php';
|
||||||
require_once 'inc/triggers.inc.php';
|
require_once 'inc/triggers.inc.php';
|
||||||
(!isset($_SESSION['mailcow_cc_username'])) ? init_db_schema() : null;
|
init_db_schema();
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
<?php
|
||||||
|
function get_spf_allowed_hosts($domain)
|
||||||
|
{
|
||||||
|
$hosts = array();
|
||||||
|
|
||||||
|
$records = dns_get_record($domain, DNS_TXT);
|
||||||
|
foreach ($records as $record)
|
||||||
|
{
|
||||||
|
$txt = explode(' ', $record['entries'][0]);
|
||||||
|
if (array_shift($txt) != 'v=spf1') // only handle SPF records
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach ($txt as $mech)
|
||||||
|
{
|
||||||
|
$qual = substr($mech, 0, 1);
|
||||||
|
if ($qual == '-' || $qual == '~') // only handle pass or neutral records
|
||||||
|
continue(2);
|
||||||
|
|
||||||
|
if ($qual == '+' || $qual == '?')
|
||||||
|
$mech = substr($mech, 1); // remove the qualifier
|
||||||
|
|
||||||
|
if (strpos($mech, '=') !== FALSE) // handle a modifier
|
||||||
|
{
|
||||||
|
$mod = explode('=', $mech);
|
||||||
|
if ($mod[0] == 'redirect') // handle a redirect
|
||||||
|
{
|
||||||
|
$hosts = get_spf_allowed_hosts($mod[1]);
|
||||||
|
return $hosts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($cidr);
|
||||||
|
if (strpos($mech, ':') !== FALSE) // handle a domain specification
|
||||||
|
{
|
||||||
|
$split = explode(':', $mech);
|
||||||
|
$mech = array_shift($split);
|
||||||
|
$domain = implode(':', $split);
|
||||||
|
if (strpos($domain, '/') !== FALSE) // remove CIDR specification
|
||||||
|
{
|
||||||
|
$split = explode('/', $domain);
|
||||||
|
$domain = $split[0];
|
||||||
|
$cidr = $split[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_hosts = array();
|
||||||
|
if ($mech == 'include') // handle an inclusion
|
||||||
|
{
|
||||||
|
$new_hosts = get_spf_allowed_hosts($domain);
|
||||||
|
}
|
||||||
|
elseif ($mech == 'a') // handle a mechanism
|
||||||
|
{
|
||||||
|
$new_hosts = get_a_hosts($domain);
|
||||||
|
}
|
||||||
|
elseif ($mech == 'mx') // handle mx mechanism
|
||||||
|
{
|
||||||
|
$new_hosts = get_mx_hosts($domain);
|
||||||
|
}
|
||||||
|
elseif ($mech == 'ip4' || $mech == 'ip6') // handle ip mechanism
|
||||||
|
{
|
||||||
|
$new_hosts = array($domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($cidr)) // add CIDR specification if present
|
||||||
|
{
|
||||||
|
foreach ($new_hosts as &$host)
|
||||||
|
{
|
||||||
|
$host .= '/' . $cidr;
|
||||||
|
}
|
||||||
|
unset($host);
|
||||||
|
}
|
||||||
|
|
||||||
|
$hosts = array_unique(array_merge($hosts,$new_hosts), SORT_REGULAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_mx_hosts($domain)
|
||||||
|
{
|
||||||
|
$hosts = array();
|
||||||
|
|
||||||
|
$mx_records = dns_get_record($domain, DNS_MX);
|
||||||
|
foreach ($mx_records as $mx_record)
|
||||||
|
{
|
||||||
|
$new_hosts = get_a_hosts($mx_record['target']);
|
||||||
|
$hosts = array_unique(array_merge($hosts,$new_hosts), SORT_REGULAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_a_hosts($domain)
|
||||||
|
{
|
||||||
|
$hosts = array();
|
||||||
|
|
||||||
|
$a_records = dns_get_record($domain, DNS_A);
|
||||||
|
foreach ($a_records as $a_record)
|
||||||
|
{
|
||||||
|
$hosts[] = $a_record['ip'];
|
||||||
|
}
|
||||||
|
$a_records = dns_get_record($domain, DNS_AAAA);
|
||||||
|
foreach ($a_records as $a_record)
|
||||||
|
{
|
||||||
|
$hosts[] = $a_record['ipv6'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_outgoing_hosts_best_guess($domain)
|
||||||
|
{
|
||||||
|
// try the SPF record to get hosts that are allowed to send outgoing mails for this domain
|
||||||
|
$hosts = get_spf_allowed_hosts($domain);
|
||||||
|
if ($hosts) return $hosts;
|
||||||
|
|
||||||
|
// try the MX record to get mail servers for this domain
|
||||||
|
$hosts = get_mx_hosts($domain);
|
||||||
|
if ($hosts) return $hosts;
|
||||||
|
|
||||||
|
// fall back to the A record to get the host name for this domain
|
||||||
|
return get_a_hosts($domain);
|
||||||
|
}
|
||||||
|
?>
|
|
@ -72,6 +72,12 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admi
|
||||||
if (isset($_POST["delete_domain_admin"])) {
|
if (isset($_POST["delete_domain_admin"])) {
|
||||||
delete_domain_admin($_POST);
|
delete_domain_admin($_POST);
|
||||||
}
|
}
|
||||||
|
if (isset($_POST["add_forwarding_host"])) {
|
||||||
|
add_forwarding_host($_POST);
|
||||||
|
}
|
||||||
|
if (isset($_POST["delete_forwarding_host"])) {
|
||||||
|
delete_forwarding_host($_POST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "user") {
|
if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "user") {
|
||||||
if (isset($_POST["edit_user_account"])) {
|
if (isset($_POST["edit_user_account"])) {
|
||||||
|
|
|
@ -450,11 +450,20 @@ $lang['admin']['unchanged_if_empty'] = 'Unverändert, wenn leer';
|
||||||
$lang['admin']['yes'] = '✔';
|
$lang['admin']['yes'] = '✔';
|
||||||
$lang['admin']['no'] = '✘';
|
$lang['admin']['no'] = '✘';
|
||||||
$lang['admin']['access'] = 'Zugang';
|
$lang['admin']['access'] = 'Zugang';
|
||||||
$lang['admin']['invalid_max_msg_size'] = 'Invalid max. message size'; // NEEDS TRANSLATION
|
$lang['admin']['invalid_max_msg_size'] = 'Ungültige maximale Nachrichtengröße';
|
||||||
$lang['admin']['site_not_found'] = 'Kann mailcow Site-Konfiguration nicht finden';
|
$lang['admin']['site_not_found'] = 'Kann mailcow Site-Konfiguration nicht finden';
|
||||||
$lang['admin']['public_folder_empty'] = 'Public folder name must not be empty'; // NEEDS TRANSLATION
|
$lang['admin']['public_folder_empty'] = 'Name des öffentlichen Ordners darf nicht leer sein';
|
||||||
$lang['admin']['set_rr_failed'] = 'Kann Postfix Restriktionen nicht setzen';
|
$lang['admin']['set_rr_failed'] = 'Kann Postfix Restriktionen nicht setzen';
|
||||||
$lang['admin']['no_record'] = 'Kein Eintrag';
|
$lang['admin']['no_record'] = 'Kein Eintrag';
|
||||||
$lang['admin']['filter_table'] = 'Tabelle Filtern';
|
$lang['admin']['filter_table'] = 'Tabelle Filtern';
|
||||||
$lang['admin']['empty'] = 'Keine Einträge vorhanden';
|
$lang['admin']['empty'] = 'Keine Einträge vorhanden';
|
||||||
|
$lang['admin']['forwarding_hosts'] = 'Weiterleitungs-Hosts';
|
||||||
|
$lang['admin']['forwarding_hosts_hint'] = 'Eingehende Nachrichten werden von den hier gelisteten Hosts bedingungslos akzeptiert. Diese Hosts werden dann nicht mit DNSBLs abgeglichen oder Greylisting unterworfen. Von ihnen empfangener Spam wird nie abgelehnt und immer in den Spam-Ordner einsortiert. Die übliche Verwendung für diese Funktion ist, um Mailserver anzugeben, auf denen eine Weiterleitung zu Ihrem Mailcow-Server eingerichtet wurde.';
|
||||||
|
$lang['admin']['forwarding_hosts_add_hint'] = 'Sie können entweder IPv4/IPv6-Adressen, Netzwerke in CIDR-Notation, Hostnamen (die zu IP-Adressen aufgelöst werden), oder Domainnamen (die zu IP-Adressen aufgelöst werden, indem ihr SPF-Record abgefragt wird oder, in dessen Abwesenheit, ihre MX-Records) angeben.';
|
||||||
|
$lang['edit']['host'] = 'Host';
|
||||||
|
$lang['edit']['source'] = 'Quelle';
|
||||||
|
$lang['admin']['add_forwarding_host'] = 'Weiterleitungs-Host hinzufügen';
|
||||||
|
$lang['delete']['remove_forwardinghost_warning'] = '<b>Warnung:</b> Sie entfernen den Weiterleitungs-Host <b>%s</b>!';
|
||||||
|
$lang['success']['forwarding_host_removed'] = "Weiterleitungs-Host %s wurde entfernt";
|
||||||
|
$lang['success']['forwarding_host_added'] = "Weiterleitungs-Host %s wurde hinzugefügt";
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -468,4 +468,13 @@ $lang['admin']['set_rr_failed'] = 'Cannot set Postfix restrictions';
|
||||||
$lang['admin']['no_record'] = 'No record';
|
$lang['admin']['no_record'] = 'No record';
|
||||||
$lang['admin']['filter_table'] = 'Filter table';
|
$lang['admin']['filter_table'] = 'Filter table';
|
||||||
$lang['admin']['empty'] = 'No results';
|
$lang['admin']['empty'] = 'No results';
|
||||||
|
$lang['admin']['forwarding_hosts'] = 'Forwarding Hosts';
|
||||||
|
$lang['admin']['forwarding_hosts_hint'] = 'Incoming messages are unconditionally accepted from any hosts listed here. These hosts are then not checked against DNSBLs or subjected to greylisting. Spam received from them is never rejected and always filed into the Junk folder. The most common use for this is to specify mail servers on which you have set up a rule that forwards incoming emails to your Mailcow server.';
|
||||||
|
$lang['admin']['forwarding_hosts_add_hint'] = 'You can either specify IPv4/IPv6 addresses, networks in CIDR notation, host names (which will be resolved to IP addresses), or domain names (which will be resolved to IP addresses by querying SPF records or, in their absence, MX records).';
|
||||||
|
$lang['edit']['host'] = 'Host';
|
||||||
|
$lang['edit']['source'] = 'Source';
|
||||||
|
$lang['admin']['add_forwarding_host'] = 'Add Forwarding Host';
|
||||||
|
$lang['delete']['remove_forwardinghost_warning'] = '<b>Warning:</b> You are about to remove the forwarding host <b>%s</b>!';
|
||||||
|
$lang['success']['forwarding_host_removed'] = "Forwarding host %s has been removed";
|
||||||
|
$lang['success']['forwarding_host_added'] = "Forwarding host %s has been added";
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -55,6 +55,17 @@ services:
|
||||||
aliases:
|
aliases:
|
||||||
- redis
|
- redis
|
||||||
|
|
||||||
|
# clamd-mailcow:
|
||||||
|
# image: mailcow/clamd
|
||||||
|
# restart: always
|
||||||
|
# dns:
|
||||||
|
# - 172.22.1.254
|
||||||
|
# dns_search: mailcow-network
|
||||||
|
# networks:
|
||||||
|
# mailcow-network:
|
||||||
|
# aliases:
|
||||||
|
# - clamd
|
||||||
|
|
||||||
rspamd-mailcow:
|
rspamd-mailcow:
|
||||||
image: mailcow/rspamd
|
image: mailcow/rspamd
|
||||||
build: ./data/Dockerfiles/rspamd
|
build: ./data/Dockerfiles/rspamd
|
||||||
|
|
|
@ -160,6 +160,84 @@ docker-compose exec postfix-mailcow chmod 660 /opt/postfix/conf/smarthost_passwd
|
||||||
docker-compose exec postfix-mailcow postfix reload
|
docker-compose exec postfix-mailcow postfix reload
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Optional: Log to Syslog
|
||||||
|
|
||||||
|
Enable Rsyslog to receive logs on 524/tcp:
|
||||||
|
|
||||||
|
```
|
||||||
|
# This setting depends on your Rsyslog version and configuration format.
|
||||||
|
# For most Debian derivates it will work like this...
|
||||||
|
$ModLoad imtcp
|
||||||
|
$TCPServerAddress 127.0.0.1
|
||||||
|
$InputTCPServerRun 524
|
||||||
|
|
||||||
|
# ...while for Ubuntu 16.04 it looks like this:
|
||||||
|
module(load="imtcp")
|
||||||
|
input(type="imtcp" address="127.0.0.1" port="524")
|
||||||
|
|
||||||
|
# No matter your Rsyslog version, you should set this option to off
|
||||||
|
# if you plan to use Fail2ban
|
||||||
|
$RepeatedMsgReduction off
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart rsyslog after enabling the TCP listener.
|
||||||
|
|
||||||
|
Now setup Docker daemon to start with the syslog driver.
|
||||||
|
This enables the syslog driver for all containers!
|
||||||
|
|
||||||
|
Debian users can change the startup configuration in `/etc/default/docker` while CentOS users find it in `/etc/sysconfig/docker`:
|
||||||
|
```
|
||||||
|
...
|
||||||
|
DOCKER_OPTS="--log-driver=syslog --log-opt syslog-address=tcp://127.0.0.1:524"
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Caution:** For some reason Ubuntu 16.04 and some, but not all, systemd based distros do not read the defaults file parameters.
|
||||||
|
|
||||||
|
Just run `systemctl edit docker.service` and add the following content to fix it.
|
||||||
|
|
||||||
|
**Note:** If "systemctl edit" is not available, just copy the content to `/etc/systemd/system/docker.service.d/override.conf`.
|
||||||
|
|
||||||
|
The first empty ExecStart parameter is not a mistake.
|
||||||
|
|
||||||
|
```
|
||||||
|
[Service]
|
||||||
|
EnvironmentFile=/etc/default/docker
|
||||||
|
ExecStart=
|
||||||
|
ExecStart=/usr/bin/docker daemon -H fd:// $DOCKER_OPTS
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart the Docker daemon and run `docker-compose down && docker-compose up -d` to recreate the containers.
|
||||||
|
|
||||||
|
### Use Fail2ban
|
||||||
|
|
||||||
|
**This is a subsection of "Log to Syslog", which is required for Fail2ban to work.**
|
||||||
|
|
||||||
|
Open `/etc/fail2ban/filter.d/common.conf` and search for the prefix_line parameter, change it to ".*":
|
||||||
|
|
||||||
|
```
|
||||||
|
__prefix_line = .*
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `/etc/fail2ban/jail.d/dovecot.conf`...
|
||||||
|
```
|
||||||
|
[dovecot]
|
||||||
|
enabled = true
|
||||||
|
filter = dovecot
|
||||||
|
logpath = /var/log/syslog
|
||||||
|
chain = FORWARD
|
||||||
|
```
|
||||||
|
|
||||||
|
and `jail.d/postfix-sasl.conf`:
|
||||||
|
```
|
||||||
|
[postfix-sasl]
|
||||||
|
enabled = true
|
||||||
|
filter = postfix-sasl
|
||||||
|
logpath = /var/log/syslog
|
||||||
|
chain = FORWARD
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart Fail2ban.
|
||||||
|
|
||||||
## Install a local MTA
|
## Install a local MTA
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# mailcow: dockerized - 🐮 + 🐋 = 💕
|
# mailcow: dockerized - 🐮 + 🐋 = 💕
|
||||||
|
|
||||||
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JWBSYHF4SMC68)
|
[![Servercow](https://www.servercow.de/img/cow_globe_200.svg)](https://www.servercow.de)
|
||||||
|
|
||||||
|
If you want to support mailcow, consider hosting mailcow on a Servercow virtual machine @ Servercow!
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
|
@ -30,6 +32,7 @@ mailcow dockerized comes with **11 containers** linked in **one bridged network*
|
||||||
- mysql-vol-1
|
- mysql-vol-1
|
||||||
- rspamd-vol-1
|
- rspamd-vol-1
|
||||||
- postfix-vol-1
|
- postfix-vol-1
|
||||||
|
- crypt-vol-1
|
||||||
|
|
||||||
The integrated **mailcow UI** allows administrative work on your mail server instance as well as separated domain administrator and mailbox user access:
|
The integrated **mailcow UI** allows administrative work on your mail server instance as well as separated domain administrator and mailbox user access:
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ Beware that a mailbox user can login to mailcow and override a domain policy fil
|
||||||
Make your changes in `data/Dockerfiles/$service` and build the image locally:
|
Make your changes in `data/Dockerfiles/$service` and build the image locally:
|
||||||
|
|
||||||
```
|
```
|
||||||
docker build data/Dockerfiles/service -t andryyy/mailcow-dockerized:$service
|
docker build data/Dockerfiles/service -t mailcow/$service
|
||||||
```
|
```
|
||||||
|
|
||||||
Now auto-recreate modified containers:
|
Now auto-recreate modified containers:
|
||||||
|
@ -311,14 +311,11 @@ Running `docker-compose down -v` will **destroy all mailcow: dockerized volumes*
|
||||||
## Reset admin password
|
## Reset admin password
|
||||||
Reset mailcow admin to `admin:moohoo`:
|
Reset mailcow admin to `admin:moohoo`:
|
||||||
|
|
||||||
1\. Drop admin table
|
|
||||||
```
|
```
|
||||||
source mailcow.conf
|
cd mailcow_path
|
||||||
docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DROP TABLE admin;"
|
bash reset_admin.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
2\. Open mailcow UI to auto-init the db
|
|
||||||
|
|
||||||
## Rspamd
|
## Rspamd
|
||||||
|
|
||||||
### Learn spam and ham
|
### Learn spam and ham
|
||||||
|
@ -521,6 +518,14 @@ map $http_upgrade $connection_upgrade {
|
||||||
|
|
||||||
Now you can simply navigate to https://${MAILCOW_HOSTNAME}/portainer/ to view your Portainer container monitoring page. You’ll then be prompted to specify a new password for the **admin** account. After specifying your password, you’ll then be able to connect to the Portainer UI.
|
Now you can simply navigate to https://${MAILCOW_HOSTNAME}/portainer/ to view your Portainer container monitoring page. You’ll then be prompted to specify a new password for the **admin** account. After specifying your password, you’ll then be able to connect to the Portainer UI.
|
||||||
|
|
||||||
|
## Change autodiscover setup type
|
||||||
|
|
||||||
|
This disables ActiveSync in the autodiscover service for Outlook and configures it with IMAP and SMTP instead:
|
||||||
|
|
||||||
|
Open `data/web/autodiscover.php` and set `'useEASforOutlook' => 'yes'` to `'useEASforOutlook' => 'no'`.
|
||||||
|
|
||||||
|
To always use IMAP and SMTP instead of EAS, set `'autodiscoverType' => 'imap'`.
|
||||||
|
|
||||||
## Why Bind?
|
## Why Bind?
|
||||||
|
|
||||||
For DNS blacklist lookups and DNSSEC.
|
For DNS blacklist lookups and DNSSEC.
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#/bin/bash
|
||||||
|
if [[ ! -f mailcow.conf ]]; then
|
||||||
|
echo "Cannot find mailcow.conf, make sure this script is run from within the mailcow folder."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "Checking MySQL service... "
|
||||||
|
docker-compose ps -q mysql-mailcow > /dev/null 2>&1
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "failed"
|
||||||
|
echo "MySQL (mysql-mailcow) is not up and running, exiting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "OK"
|
||||||
|
read -r -p "Are you sure you want to reset the mailcow administrator account? [y/N] " response
|
||||||
|
response=${response,,} # tolower
|
||||||
|
if [[ "$response" =~ ^(yes|y)$ ]]; then
|
||||||
|
echo -e "\nWorking, please wait..."
|
||||||
|
source mailcow.conf
|
||||||
|
docker-compose exec -T mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM admin;"
|
||||||
|
docker-compose exec -T mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "INSERT INTO admin (username, password, superadmin, created, modified, active) VALUES ('admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1);"
|
||||||
|
docker-compose exec -T mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM domain_admins WHERE username='admin';"
|
||||||
|
docker-compose exec -T mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "INSERT INTO domain_admins (username, domain, created, active) VALUES ('admin', 'ALL', NOW(), 1);"
|
||||||
|
docker-compose exec -T mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM tfa WHERE username='admin';"
|
||||||
|
echo "
|
||||||
|
Reset credentials:
|
||||||
|
---
|
||||||
|
Username: admin
|
||||||
|
Password: moohoo
|
||||||
|
TFA: none
|
||||||
|
"
|
||||||
|
else
|
||||||
|
echo "Operation canceled."
|
||||||
|
fi
|
|
@ -0,0 +1,76 @@
|
||||||
|
#/bin/bash
|
||||||
|
if [[ ! -f mailcow.conf ]]; then
|
||||||
|
echo "Cannot find mailcow.conf, make sure this script is run from within the mailcow folder."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "Checking Postfix service... "
|
||||||
|
docker-compose ps -q postfix-mailcow > /dev/null 2>&1
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "failed"
|
||||||
|
echo "Postfix (postifx-mailcow) is not up and running, exiting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "OK"
|
||||||
|
|
||||||
|
if [[ -z ${1} ]]; then
|
||||||
|
echo "Usage:"
|
||||||
|
echo
|
||||||
|
echo "Setup a relayhost:"
|
||||||
|
echo "./${0} relayhost port (username) (password)"
|
||||||
|
echo "Username and password are optional parameters."
|
||||||
|
echo
|
||||||
|
echo "Reset to defaults:"
|
||||||
|
echo "./${0} reset"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${1} == "reset" ]]; then
|
||||||
|
# Reset modified values to their defaults
|
||||||
|
sed -i "s/^relayhost\ \=.*/relayhost\ \=/" data/conf/postfix/main.cf
|
||||||
|
sed -i "s/^smtp\_sasl\_password\_maps.*/smtp\_sasl\_password\_maps\ \=/" data/conf/postfix/main.cf
|
||||||
|
sed -i "s/^smtp\_sasl\_security\_options.*/smtp\_sasl\_security\_options\ \=\ noplaintext\,\ noanonymous/" data/conf/postfix/main.cf
|
||||||
|
sed -i "s/^smtp\_sasl\_auth\_enable.*/smtp\_sasl\_auth\_enable\ \=\ no/" data/conf/postfix/main.cf
|
||||||
|
# Also delete the plaintext password file
|
||||||
|
rm -f data/conf/postfix/smarthost_passwd*
|
||||||
|
docker-compose exec postfix-mailcow postfix reload
|
||||||
|
# Exit with dc exit code
|
||||||
|
exit $?
|
||||||
|
else
|
||||||
|
# Try a simple connection to host:port but don't recieve any data
|
||||||
|
# Abort after 3 seconds
|
||||||
|
if ! nc -z -v -w3 ${1} ${2} 2>/dev/null; then
|
||||||
|
echo "Connection to relayhost ${1} failed, aborting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# Use exact hostname as relayhost, don't lookup the MX record of relayhost
|
||||||
|
sed -i "s/relayhost\ \=.*/relayhost\ \=\ \[${1}\]\:${2}/" data/conf/postfix/main.cf
|
||||||
|
if grep -q "smtp_sasl_password_maps" data/conf/postfix/main.cf
|
||||||
|
then
|
||||||
|
sed -i "s/^smtp\_sasl\_password\_maps.*/smtp\_sasl\_password\_maps\ \=\ hash\:\/opt\/postfix\/conf\/smarthost\_passwd/" data/conf/postfix/main.cf
|
||||||
|
else
|
||||||
|
echo "smtp_sasl_password_maps = hash:/opt/postfix/conf/smarthost_passwd" >> data/conf/postfix/main.cf
|
||||||
|
fi
|
||||||
|
if grep -q "smtp_sasl_auth_enable" data/conf/postfix/main.cf
|
||||||
|
then
|
||||||
|
sed -i "s/^smtp\_sasl\_auth\_enable.*/smtp\_sasl\_auth\_enable\ \=\ yes/" data/conf/postfix/main.cf
|
||||||
|
else
|
||||||
|
echo "smtp_sasl_auth_enable = yes" >> data/conf/postfix/main.cf
|
||||||
|
fi
|
||||||
|
if grep -q "smtp_sasl_security_options" data/conf/postfix/main.cf
|
||||||
|
then
|
||||||
|
sed -i "s/^smtp\_sasl\_security\_options.*/smtp\_sasl\_security\_options\ \=/" data/conf/postfix/main.cf
|
||||||
|
else
|
||||||
|
echo "smtp_sasl_security_options =" >> data/conf/postfix/main.cf
|
||||||
|
fi
|
||||||
|
if [[ ! -z ${3} ]]; then
|
||||||
|
echo ${1} ${3}:${4} > data/conf/postfix/smarthost_passwd
|
||||||
|
docker-compose exec postfix-mailcow postmap /opt/postfix/conf/smarthost_passwd
|
||||||
|
fi
|
||||||
|
docker-compose exec postfix-mailcow chown root:postfix /opt/postfix/conf/smarthost_passwd /opt/postfix/conf/smarthost_passwd.db
|
||||||
|
docker-compose exec postfix-mailcow chmod 660 /opt/postfix/conf/smarthost_passwd /opt/postfix/conf/smarthost_passwd.db
|
||||||
|
docker-compose exec postfix-mailcow postfix reload
|
||||||
|
exit $?
|
||||||
|
fi
|
Loading…
Reference in New Issue